Поделиться через


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 директивы:

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
Ключевые слова