Dyrektywy Pragma i __pragma słowa kluczowe i _Pragma

Dyrektywy Pragma określają funkcje kompilatora specyficzne dla maszyny lub systemu operacyjnego. Wiersz rozpoczynający się od #pragma określa dyrektywę pragma . Słowo kluczowe specyficzne dla __pragma firmy Microsoft umożliwia kod pragma dyrektyw w definicjach makr. Standardowy _Pragma operator preprocesora wprowadzony w języku C99 i przyjęty przez język C++11 jest podobny.

Składnia

#pragmaciąg tokenu
__pragma(token-string) // dwa wiodące podkreślenia — rozszerzenie specyficzne dla firmy Microsoft
_Pragma(literał) ciągu // C99

Uwagi

Każda implementacja języka C i C++ obsługuje niektóre funkcje unikatowe dla maszyny hosta lub systemu operacyjnego. Niektóre programy, na przykład, muszą mieć dokładną kontrolę nad lokalizacją danych w pamięci lub kontrolować sposób odbierania parametrów przez niektóre funkcje. Dyrektywy #pragma umożliwiają każdemu kompilatorowi oferowanie funkcji specyficznych dla maszyn i systemu operacyjnego przy zachowaniu ogólnej zgodności z językami C i C++.

Dyrektywy Pragma są specyficzne dla maszyny lub systemu operacyjnego według definicji i są zwykle różne dla każdego kompilatora. Element pragma można użyć w dyrektywie warunkowej, aby zapewnić nowe funkcje preprocesora. Możesz też podać informacje zdefiniowane przez implementację kompilatorowi.

Ciąg tokenu to seria znaków reprezentujących konkretną instrukcję i argumenty kompilatora, jeśli istnieją. Znak numeru (#) musi być pierwszym znakiem innego niż biały znak w wierszu zawierającym pragmaznak . Znaki odstępu mogą oddzielić znak numeru i wyraz "pragma". Zgodnie z #pragmainstrukcjami napisz dowolny tekst, który translator może przeanalizować jako tokeny przetwarzania wstępnego. Argument , który #pragma ma być przedmiotem rozszerzenia makra.

Literał ciągu to dane wejściowe ._Pragma Cudzysłowy zewnętrzne i białe znaki wiodące/końcowe są usuwane. \" element jest zastępowany elementem " i \\ jest zastępowany ciągiem \.

Kompilator wyświetla ostrzeżenie, gdy wykryje pragma , że nie rozpoznaje i kontynuuje kompilację.

Kompilatory microsoft C i C++ rozpoznają następujące pragma dyrektywy:

1 Obsługiwane tylko przez kompilator języka C++.

Dyrektywy Pragma i opcje kompilatora

Niektóre pragma dyrektywy zapewniają takie same funkcje jak opcje kompilatora. Gdy element zostanie osiągnięty w kodzie źródłowym pragma , zastępuje zachowanie określone przez opcję kompilatora. Jeśli na przykład określono /Zp8parametr , możesz zastąpić to ustawienie kompilatora dla określonych sekcji kodu za pomocą polecenia 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
// ...

Słowo __pragma kluczowe

Kompilator obsługuje również słowo kluczowe specyficzne dla __pragma firmy Microsoft, które ma taką samą funkcjonalność jak #pragma dyrektywa. Różnica polega na tym, że __pragma słowo kluczowe jest używane w tekście w definicji makra. Dyrektywa #pragma nie może być użyteczna w definicji makra, ponieważ kompilator interpretuje znak numeru ('#') w dyrektywie jako operator ciągu (#).

W poniższym przykładzie kodu pokazano, jak __pragma słowo kluczowe może być używane w makrze. Ten kod jest fragmentem nagłówka mfcdual.h w przykładzie ACDUAL w sekcji "Kompilator COM Support Samples":

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

Operator przetwarzania _Pragma wstępnego

_Pragma jest podobny do słowa kluczowego specyficznego dla __pragma firmy Microsoft. Wprowadzono go do standardu C w języku C99 i standardu C++ w języku C++11. Jest ona dostępna w języku C tylko wtedy, gdy określisz /std:c11 opcję lub /std:c17 . W przypadku języka C++jest ona dostępna we wszystkich /std trybach, w tym w trybie domyślnym.

W przeciwieństwie do #pragmametody _Pragma , umożliwia umieszczenie pragma dyrektyw w definicji makra. Literał ciągu powinien być tym, co w przeciwnym razie należy umieścić po instrukcji #pragma . Przykład:

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

Znaki cudzysłowu i ukośniki wsteczne powinny zostać uniknięte, jak pokazano powyżej. Ciąg pragma , który nie jest rozpoznawany, jest ignorowany.

W poniższym przykładzie kodu pokazano, jak _Pragma słowo kluczowe może być używane w makrze przypominającym asercję. Tworzy dyrektywę pragma , która pomija ostrzeżenie, gdy wyrażenie warunku ma być stałe.

Definicja makr używa do ... while(0) idiomu dla makr z wieloma instrukcjami, dzięki czemu może być używana tak, jakby była to jedna instrukcja. Aby uzyskać więcej informacji, zobacz Makro wielowierszowe języka C w witrynie Stack Overflow. Instrukcja _Pragma w przykładzie ma zastosowanie tylko do wiersza kodu, który następuje po nim.

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

Zobacz też

Dokumentacja preprocesora języka C/C++
Dyrektywy języka C pragma
Słowa kluczowe