Delen via


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 #pragmaalle 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:

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 /Zp8hebt 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 #pragmakunt 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