Pragmadyrektywy i __pragma
słowa kluczowe i _Pragma
Pragma dyrektywy 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
#pragma
ciąg tokenu
__pragma(
ciąg)
tokenu 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++.
Pragma dyrektywy 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 #pragma
instrukcjami 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:
alloc_text
auto_inline
bss_seg
check_stack
code_seg
comment
component
conform
1
const_seg
data_seg
deprecated
1 Obsługiwane tylko przez kompilator języka C++.
Pragma dyrektywy 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 /Zp8
parametr , 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 kluczowe __pragma
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 #pragma
metody _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
. Na 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