Pragma директивы и ключевые __pragma
_Pragma
слова
Pragma Директивы указывают функции компилятора для конкретного компьютера или операционной системы. Строка, начинающаяся с #pragma
указания pragma директивы. Ключевое слово, определенное __pragma
корпорацией Майкрософт, позволяет кодировать pragma директивы в определениях макросов. Стандартный _Pragma
оператор препроцессора, представленный в C99 и принятый C++11, аналогичен.
Синтаксис
#pragma
строка токена
__pragma(
строка)
токена два ведущих подчеркивания — расширение, определенное корпорацией Майкрософт
_Pragma(
строковый литерал)
C99
Замечания
Каждая реализация C и C++ поддерживает некоторые возможности, уникальные для хост-компьютера или операционной системы. Например, некоторые программы должны осуществлять точный контроль над расположением данных в памяти или управлять способом получения определенных функций. Директивы #pragma
позволяют каждому компилятору предлагать функции, относящиеся к компьютерам и операционной системе, сохраняя общую совместимость с языками C и C++.
Pragma Директивы относятся к определенному компьютеру или операционной системе по определению и обычно отличаются для каждого компилятора. Можно pragma использовать в условной директиве для предоставления новых функциональных возможностей препроцессора. Кроме того, используйте один для предоставления определяемой реализацией информации компилятору.
Строка токена представляет собой ряд символов, представляющих определенную инструкцию компилятора и аргументы, если таковые есть. Знак номера (#
) должен быть первым символом без пробела в строке, содержащей .pragma Символы пробелов могут разделять знак номера и слово "pragma". Далее #pragma
напишите любой текст, который переводчик может анализировать как маркеры предварительной обработки. Аргумент, подлежащий #pragma
расширению макроса.
Строковый литерал — это входные данные_Pragma
. Внешние кавычки и начальные или конечные пробелы удаляются. \"
заменяется "
и \\
заменяется на \
.
Компилятор выдает предупреждение при обнаружении pragma того, что он не распознает и продолжает компиляцию.
Компиляторы Microsoft C и C++ распознают следующие pragma директивы:
alloc_text
auto_inline
bss_seg
check_stack
code_seg
comment
component
conform
1
const_seg
data_seg
deprecated
1 Поддерживается только компилятором C++.
Pragma директивы и параметры компилятора
Некоторые pragma директивы предоставляют те же функции, что и параметры компилятора. pragma Когда достигается в исходном коде, он переопределяет поведение, указанное параметром компилятора. Например, если задано /Zp8
, можно переопределить этот параметр компилятора для определенных разделов кода с помощью 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
// ...
Ключевое слово __pragma
.
Компилятор также поддерживает ключевое слово, определенное __pragma
корпорацией Майкрософт, которое имеет те же функции, что и директива #pragma
. Разница заключается в том, __pragma
что ключевое слово является пригодным для использования в определении макроса. Директива #pragma
не используется в определении макроса, так как компилятор интерпретирует символ знака номера ('#) в директиве в качестве оператора строки (#).
В следующем примере кода показано, как __pragma
ключевое слово может использоваться в макросе. Этот код фрагментируется из заголовка mfcdual.h в примере ACDUAL в разделе "Примеры поддержки COM компилятора":
#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; \
Оператор _Pragma
предварительной обработки
_Pragma
аналогично ключевому слову, определенному корпорацией __pragma
Майкрософт. Он был введен в стандарт C в C99 и стандарт C++ в C++11. Он доступен только в C, если указать /std:c11
или /std:c17
параметр. Для C++он доступен во всех /std
режимах, включая значение по умолчанию.
В отличие от #pragma
этого, _Pragma
можно поместить pragma директивы в определение макроса. Строковый литерал должен быть тем, что в противном случае следует поместить после инструкции #pragma
. Например:
#pragma message("the #pragma way")
_Pragma ("message( \"the _Pragma way\")")
Кавычки и косые черты должны быть экранированы, как показано выше. Строка pragma , которая не распознается, игнорируется.
В следующем примере кода показано, как _Pragma
ключевое слово может использоваться в макросе, аналогичном утверждению. Он создает pragma директиву, которая подавляет предупреждение, когда выражение условия будет константой.
Определение макроса использует do ... while(0)
идиом для макросов с несколькими операторами, чтобы его можно было использовать так, как будто это была одна инструкция. Дополнительные сведения см. в разделе многострочный макрос C в Stack Overflow. Инструкция _Pragma
в примере применяется только к строке кода, следующей за ней.
// 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;
}
См. также
Справочник по препроцессору в C/C++
Директивы C pragma
Ключевые слова