Pragma-Direktiven und die __pragma und _Pragma Schlüsselwort (keyword)

Pragma-Direktiven geben computerspezifische oder betriebssystemspezifische Compilerfeatures an. Eine Zeile, die mit #pragma einer pragma Direktive beginnt. Mit dem microsoftspezifischen __pragma Schlüsselwort (keyword) können Sie Direktiven in Makrodefinitionen codierenpragma. Der in C99 eingeführte Standard-Präprozessoroperator _Pragma , der von C++11 übernommen wurde, ist ähnlich.

Syntax

#pragmatoken-string
__pragma(token-string) // zwei führende Unterstriche - Microsoft-spezifische Erweiterung
_Pragma(string-literal) // C99

Hinweise

Jede Implementierung von C und C++ unterstützt mehrere Funktionen, die auf dem Hostcomputer oder Betriebssystem einzigartig sind. Einige Programme müssen z. B. präzise Kontrolle über die Position von Daten im Speicher ausüben oder die Art und Weise steuern, wie bestimmte Funktionen Parameter empfangen. Die #pragma Direktiven bieten jedem Compiler eine Möglichkeit, computer- und betriebssystemspezifische Features anzubieten, während Standard die allgemeine Kompatibilität mit den C- und C++-Sprachen beibehalten wird.

Pragma-Direktiven sind computerspezifische oder betriebssystemspezifische Definition und unterscheiden sich in der Regel für jeden Compiler. Eine pragma kann in einer bedingten Direktive verwendet werden, um neue Präprozessorfunktionen bereitzustellen. Oder verwenden Sie einen, um dem Compiler implementierungsdefinierte Informationen bereitzustellen.

Die Tokenzeichenfolge ist eine Reihe von Zeichen, die eine bestimmte Compileranweisung und -argumente darstellen, falls vorhanden. Das Nummernzeichen (#) muss das erste Nicht-Leerzeichen in der Zeile sein, die das pragmaZeichen enthält. Leerzeichen können das Nummernzeichen und das Wort "pragma" trennen. Schreiben Sie im Folgenden #pragmaeinen beliebigen Text, den der Übersetzer als Vorverarbeitungstoken analysieren kann. Das Argument, das #pragma der Makroerweiterung unterliegt.

Das Zeichenfolgenliteral ist die Eingabe für _Pragma. Äußere Anführungszeichen und führende/nachfolgende Leerzeichen werden entfernt. \" wird durch und "\\ wird durch ersetzt durch \.

Der Compiler gibt eine Warnung aus, wenn eine pragma Nichterkennung gefunden wird, und die Kompilierung wird fortgesetzt.

Die Microsoft C- und C++-Compiler erkennen die folgenden pragma Direktiven:

1 Wird nur vom C++-Compiler unterstützt.

Pragma-Direktiven und Compileroptionen

Einige pragma Direktiven bieten die gleiche Funktionalität wie Compileroptionen. Wenn ein pragma Objekt im Quellcode erreicht wird, setzt es das von der Compileroption angegebene Verhalten außer Kraft. Wenn Sie beispielsweise angegeben /Zp8haben, können Sie diese Compilereinstellung für bestimmte Abschnitte des Codes überschreiben mit 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
// ...

dem __pragma-Schlüsselwort

Der Compiler unterstützt auch die microsoftspezifische __pragma Schlüsselwort (keyword), die die gleiche Funktionalität wie die #pragma Direktive aufweist. Der Unterschied besteht darin, dass die __pragma Schlüsselwort (keyword) inline in einer Makrodefinition verwendet werden kann. Die #pragma Direktive kann in einer Makrodefinition nicht verwendet werden, da der Compiler das Nummernzeichen ('#') in der Direktive als Zeichenfolgenoperator (#)interpretiert.

Im folgenden Codebeispiel wird veranschaulicht, wie die __pragma Schlüsselwort (keyword) in einem Makro verwendet werden kann. Dieser Code wird aus dem mfcdual.h-Header im ACDUAL-Beispiel in "Compiler COM-Supportbeispiele" auszugsweise:

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

Der _Pragma Vorverarbeitungsoperator

_Pragmaähnelt den microsoftspezifischen __pragma Schlüsselwort (keyword). Es wurde in C99 in den C-Standard und den C++-Standard in C++11 eingeführt. Sie ist nur in C verfügbar, wenn Sie die Option oder /std:c17 die /std:c11 Option angeben. Für C++ ist es in allen /std Modi verfügbar, einschließlich des Standardwerts.

Im Gegensatz dazu #pragma_Pragma können Sie Direktiven in eine Makrodefinition einfügenpragma. Das Zeichenfolgenliteral sollte das sein, was Sie andernfalls nach einer #pragma Anweisung setzen würden. Beispiel:

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

Anführungszeichen und Schrägstriche sollten wie oben dargestellt escapet werden. Eine pragma Zeichenfolge, die nicht erkannt wird, wird ignoriert.

Im folgenden Codebeispiel wird veranschaulicht, wie die _Pragma Schlüsselwort (keyword) in einem assertionsähnlichen Makro verwendet werden kann. Sie erstellt eine pragma Direktive, die eine Warnung unterdrückt, wenn der Bedingungsausdruck konstant ist.

Die Makrodefinition verwendet den do ... while(0) Idiom für Makros mit mehreren Anweisungen, sodass sie wie eine Anweisung verwendet werden kann. Weitere Informationen finden Sie unter C-mehrzeiliges Makro auf Stack Overflow. Die _Pragma Anweisung im Beispiel gilt nur für die Codezeile, die darauf folgt.

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

Siehe auch

C/C++-Präprozessorreferenz
C-Richtlinien pragma
Schlüsselwörter