Pragma-instructies en de __pragma
en _Pragma
trefwoorden
Pragma-instructies geven machinespecifieke of besturingssysteemspecifieke compilerfuncties op. Een regel die begint met #pragma
geeft een pragma richtlijn aan. Met het microsoft-specifieke __pragma
trefwoord kunt u pragma instructies codeeren binnen macrodefinities. De standaardoperator _Pragma
preprocessor, geïntroduceerd in C99 en door C++11 aangenomen, is vergelijkbaar.
Syntaxis
#pragma
tokentekenreeks
__pragma(
tokentekenreeks)
// twee voorlooponderstrepingstekens - Microsoft-specifieke extensie
_Pragma(
letterlijke tekenreeks)
// C99
Opmerkingen
Elke implementatie van C en C++ ondersteunt bepaalde functies die uniek zijn voor de hostcomputer of het besturingssysteem. Sommige programma's moeten bijvoorbeeld nauwkeurige controle uitoefenen over de locatie van gegevens in het geheugen of de manier bepalen waarop bepaalde functies parameters ontvangen. De #pragma
-instructies bieden een manier voor elke compiler om machine- en besturingssysteemspecifieke functies te bieden, terwijl de algehele compatibiliteit met de C- en C++-talen behouden blijft.
Pragma-instructies zijn per definitie machinespecifiek of besturingssysteemspecifiek en zijn doorgaans verschillend voor elke compiler. Een pragma kan worden gebruikt in een voorwaardelijke richtlijn om nieuwe preprocessorfunctionaliteit te bieden. Of gebruik er een om door de implementatie gedefinieerde informatie aan de compiler te bieden.
De tokentekenreeks is een reeks tekens die een specifieke compilerinstructie en argumenten vertegenwoordigen, indien van toepassing. Het nummerteken (#
) moet het eerste niet-witruimteteken zijn op de regel die de pragmabevat. Spatietekens kunnen het cijferteken en het woord 'pragma' scheiden. Schrijf na #pragma
alle tekst die de vertaler kan parseren als voorverwerkingstokens. Het argument voor #pragma
is onderhevig aan macro-uitbreiding.
De letterlijke tekenreeks is de invoer voor _Pragma
. Buitenste aanhalingstekens en voorloop-/volgspaties worden verwijderd.
\"
wordt vervangen door "
en \\
wordt vervangen door \
.
De compiler geeft een waarschuwing wanneer er een pragma wordt gevonden die niet wordt herkend en wordt de compilatie voortgezet.
De Microsoft C- en C++-compilers herkennen de volgende pragma instructies:
alloc_text
auto_inline
bss_seg
check_stack
code_seg
comment
component
conform
1
const_seg
data_seg
deprecated
1 alleen ondersteund door de C++-compiler.
Pragma-instructies en compileropties
Sommige pragma instructies bieden dezelfde functionaliteit als compileropties. Wanneer een pragma wordt bereikt in de broncode, wordt het gedrag dat is opgegeven door de compileroptie overschreven. Als u bijvoorbeeld /Zp8
hebt opgegeven, kunt u deze compilerinstelling overschrijven voor specifieke secties van de code met pack
:
cl /Zp8 some_file.cpp
// some_file.cpp - packing is 8
// ...
#pragma pack(push, 1) - packing is now 1
// ...
#pragma pack(pop) - packing is 8 again
// ...
Het trefwoord __pragma
De compiler ondersteunt ook het microsoft-specifieke __pragma
trefwoord, dat dezelfde functionaliteit heeft als de #pragma
-instructie. Het verschil is dat het __pragma
trefwoord inline kan worden gebruikt in een macrodefinitie. De #pragma
instructie is niet bruikbaar in een macrodefinitie, omdat de compiler het teken voor het nummerteken ('#') in de instructie interpreteert als de operator voor tekenreeksen (#) (#).
In het volgende codevoorbeeld ziet u hoe het __pragma
trefwoord in een macro kan worden gebruikt. Deze code wordt opgehaald uit de mfcdual.h header in het ACDUAL-voorbeeld in 'Com-ondersteuningsvoorbeelden compileren':
#define CATCH_ALL_DUAL \
CATCH(COleException, e) \
{ \
_hr = e->m_sc; \
} \
AND_CATCH_ALL(e) \
{ \
__pragma(warning(push)) \
__pragma(warning(disable:6246)) /*disable _ctlState prefast warning*/ \
AFX_MANAGE_STATE(pThis->m_pModuleState); \
__pragma(warning(pop)) \
_hr = DualHandleException(_riidSource, e); \
} \
END_CATCH_ALL \
return _hr; \
De operator _Pragma
voorverwerking
_Pragma
is vergelijkbaar met het microsoft-specifieke __pragma
trefwoord. Het werd geïntroduceerd in de C-standaard in C99 en de C++-standaard in C++11. Deze is alleen beschikbaar in C wanneer u de optie /std:c11
of /std:c17
opgeeft. Voor C++is deze beschikbaar in alle /std
modi, inclusief de standaardmodus.
In tegenstelling tot #pragma
kunt u met _Pragma
instructies pragma in een macrodefinitie plaatsen. De letterlijke tekenreeks moet zijn wat u anders zou plaatsen na een #pragma
instructie. Bijvoorbeeld:
#pragma message("the #pragma way")
_Pragma ("message( \"the _Pragma way\")")
Aanhalingstekens en back-slashes moeten worden ontsnapt, zoals hierboven wordt weergegeven. Een pragma tekenreeks die niet wordt herkend, wordt genegeerd.
In het volgende codevoorbeeld ziet u hoe het _Pragma
trefwoord kan worden gebruikt in een assert-achtige macro. Er wordt een pragma instructie gemaakt die een waarschuwing onderdrukt wanneer de voorwaardeexpressie constant is.
De macrodefinitie gebruikt de do ... while(0)
idioom voor macro's met meerdere instructies, zodat deze kan worden gebruikt alsof het één instructie was. Zie C-macro met meerdere regels op Stack Overflow voor meer informatie. De _Pragma
-instructie in het voorbeeld is alleen van toepassing op de coderegel die hierop volgt.
// Compile with /W4
#include <stdio.h>
#include <stdlib.h>
#define MY_ASSERT(BOOL_EXPRESSION) \
do { \
_Pragma("warning(suppress: 4127)") /* C4127 conditional expression is constant */ \
if (!(BOOL_EXPRESSION)) { \
printf("MY_ASSERT FAILED: \"" #BOOL_EXPRESSION "\" on %s(%d)", __FILE__, __LINE__); \
exit(-1); \
} \
} while (0)
int main()
{
MY_ASSERT(0 && "Note that there is no warning: C4127 conditional expression is constant");
return 0;
}
Zie ook
preprocessorverwijzing voor C/C++
C pragma richtlijnen
trefwoorden