Dela via


Pragma-direktiv och nyckelorden __pragma och _Pragma

Pragma-direktiv anger maskinspecifika eller operativsystemspecifika kompilatorfunktioner. En rad som börjar med #pragma anger ett pragma direktiv. Med det Microsoft-specifika nyckelordet __pragma kan du koda pragma direktiv i makrodefinitioner. Standardoperatorn _Pragma preprocessor, som introducerades i C99 och antogs av C++11, är liknande.

Syntax

#pragma tokensträng
__pragma( tokensträng) // två inledande understreck – Microsoft-specifikt tillägg
_Pragma( strängliteral) // C99

Anmärkningar

Varje implementering av C och C++ stöder vissa funktioner som är unika för värddatorn eller operativsystemet. Vissa program måste till exempel utöva exakt kontroll över platsen för data i minnet eller styra hur vissa funktioner tar emot parametrar. De #pragma direktiven erbjuder ett sätt för varje kompilator att erbjuda maskin- och operativsystemspecifika funktioner, samtidigt som den övergripande kompatibiliteten med C- och C++-språken upprätthålls.

Pragma-direktiv är datorspecifika eller operativsystemspecifika per definition och skiljer sig vanligtvis åt för varje kompilator. En pragma kan användas i ett villkorligt direktiv för att tillhandahålla nya funktioner för förprocessorer. Du kan också använda en för att tillhandahålla implementeringsdefinierad information till kompilatorn.

Den tokensträngen är en serie tecken som representerar en specifik kompilatorinstruktion och eventuella argument. Taltecknet (#) måste vara det första icke-blankstegstecknet på raden som innehåller pragma. Blankstegstecken kan avgränsa taltecknet och ordet "pragma". Efter #pragmaskriver du all text som översättaren kan parsa som förbearbetningstoken. Argumentet för att #pragma är föremål för makroexpansion.

strängliteral är indata till _Pragma. Yttre citattecken och inledande/avslutande blanksteg tas bort. \" ersätts med " och \\ ersätts med \.

Kompilatorn utfärdar en varning när den hittar en pragma som den inte känner igen och fortsätter kompilering.

Microsoft C- och C++-kompilatorerna känner igen följande pragma direktiv:

1 stöds endast av C++-kompilatorn.

Pragma-direktiv och kompilatoralternativ

Vissa pragma-direktiv har samma funktioner som kompilatoralternativ. När en pragma nås i källkoden åsidosätter den det beteende som anges av kompilatoralternativet. Om du till exempel har angett /Zp8kan du åsidosätta den här kompilatorinställningen för specifika delar av koden med 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
// ...

Nyckelordet __pragma

Kompilatorn stöder också det Microsoft-specifika nyckelordet __pragma, som har samma funktioner som #pragma-direktivet. Skillnaden är att nyckelordet __pragma kan användas infogat i en makrodefinition. #pragma-direktivet kan inte användas i en makrodefinition, eftersom kompilatorn tolkar talteckentecknet ('#') i direktivet som strängoperator (#).

I följande kodexempel visas hur nyckelordet __pragma kan användas i ett makro. Den här koden är utdragen från mfcdual.h-rubriken i ACDUAL-exemplet i "Kompilator COM-supportexempel":

#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; \

Operatorn _Pragma förbearbetning

_Pragma liknar det Microsoft-specifika nyckelordet __pragma. Den introducerades i C-standarden i C99 och C++-standarden i C++11. Den är endast tillgänglig i C när du anger alternativet /std:c11 eller /std:c17. För C++är den tillgänglig i alla /std lägen, inklusive standardläget.

Till skillnad från #pragmakan du _Pragma placera pragma-direktiv i en makrodefinition. Strängliteralen bör vara det som du annars skulle lägga till efter en #pragma-instruktion. Till exempel:

#pragma message("the #pragma way")
_Pragma ("message( \"the _Pragma way\")") 

Citattecken och snedstreck bör vara undantagna, som du ser ovan. En pragma sträng som inte känns igen ignoreras.

Följande kodexempel visar hur nyckelordet _Pragma kan användas i ett assert-liknande makro. Det skapar ett pragma direktiv som undertrycker en varning när villkorsuttrycket råkar vara konstant.

Makrodefinitionen använder do ... while(0) idiom för makron med flera instruktioner så att det kan användas som om det vore en instruktion. Mer information finns i C-makro med flera rader på Stack Overflow. Instruktionen _Pragma i exemplet gäller bara för den kodrad som följer den.

// 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;
}

Se även

C/C++-referens för förprocessor
C pragma direktiv
nyckelord