Partilhar via


Diretivas Pragma e as palavras-chave __pragma e _Pragma

As diretivas Pragma especificam recursos de compilador específicos da máquina ou do sistema operacional. Uma linha que começa com #pragma especifica uma diretiva pragma. A palavra-chave __pragma específica da Microsoft permite codificar diretivas pragma dentro de definições de macro. O operador de pré-processador _Pragma padrão, introduzido no C99 e adotado pelo C++11, é semelhante.

Sintaxe

#pragma de cadeia de caracteres de token
__pragma( token-string) // dois sublinhados principais - extensão específica da Microsoft
_Pragma( ) literal // C99

Comentários

Cada implementação de C e C++ suporta alguns recursos exclusivos para sua máquina host ou sistema operacional. Alguns programas, por exemplo, devem exercer um controle preciso sobre a localização dos dados na memória, ou controlar a forma como certas funções recebem parâmetros. As diretivas #pragma oferecem uma maneira de cada compilador oferecer recursos específicos da máquina e do sistema operacional, mantendo a compatibilidade geral com as linguagens C e C++.

As diretivas Pragma são específicas da máquina ou do sistema operacional por definição, e normalmente são diferentes para cada compilador. Um pragma pode ser usado em uma diretiva condicional, para fornecer uma nova funcionalidade de pré-processador. Ou, use um para fornecer informações definidas pela implementação para o compilador.

A de cadeia de caracteres de token é uma série de caracteres que representam uma instrução e argumentos específicos do compilador, se houver. O sinal numérico (#) deve ser o primeiro caractere sem espaço em branco na linha que contém o pragma. Caracteres de espaço em branco podem separar o sinal numérico e a palavra "pragma". Seguindo #pragma, escreva qualquer texto que o tradutor possa analisar como tokens de pré-processamento. O argumento para #pragma está sujeito a expansão macro.

A string-literal é a entrada para _Pragma. As aspas externas e o espaço em branco à esquerda/à direita são removidos. \" é substituído por " e \\ é substituído por \.

O compilador emite um aviso quando encontra um pragma que não reconhece e continua a compilação.

Os compiladores Microsoft C e C++ reconhecem as seguintes diretivas pragma:

1 Suportado apenas pelo compilador C++.

Diretivas Pragma e opções do compilador

Algumas diretivas pragma fornecem a mesma funcionalidade que as opções do compilador. Quando um pragma é alcançado no código-fonte, ele substitui o comportamento especificado pela opção do compilador. Por exemplo, se você especificou /Zp8, você pode substituir essa configuração do compilador para seções específicas do código com 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
// ...

A palavra-chave __pragma

O compilador também suporta a palavra-chave __pragma específica da Microsoft, que tem a mesma funcionalidade que a diretiva #pragma. A diferença é que a palavra-chave __pragma é utilizável embutida em uma definição de macro. A diretiva #pragma não é utilizável em uma definição de macro, porque o compilador interpreta o caractere de sinal numérico ('#') na diretiva como o operador de stringizing (#).

O exemplo de código a seguir demonstra como a palavra-chave __pragma pode ser usada em uma macro. Este código é extraído do cabeçalho mfcdual.h no exemplo ACDUAL em "Compiler 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; \

O operador de pré-processamento _Pragma

_Pragma é semelhante à palavra-chave __pragma específica da Microsoft. Foi introduzido no padrão C em C99 e no padrão C++ em C++11. Ele está disponível em C somente quando você especifica a opção /std:c11 ou /std:c17. Para C++, ele está disponível em todos os modos /std, incluindo o padrão.

Ao contrário #pragma, _Pragma permite que você coloque diretivas pragma em uma definição de macro. O literal da cadeia de caracteres deve ser o que você colocaria após uma instrução #pragma. Por exemplo:

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

Aspas e barras invertidas devem ser evitadas, como mostrado acima. Uma cadeia de caracteres pragma que não é reconhecida é ignorada.

O exemplo de código a seguir demonstra como a palavra-chave _Pragma pode ser usada em uma macro assert-like. Ele cria uma diretiva pragma que suprime um aviso quando a expressão da condição passa a ser constante.

A definição de macro usa o idioma do ... while(0) para macros de várias instruções para que possa ser usada como se fosse uma instrução. Para obter mais informações, consulte de macro de várias linhas C no estouro de pilha. A instrução _Pragma no exemplo só se aplica à linha de código que a segue.

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

Ver também

de referência do pré-processador C/C++
C pragma diretivas
Palavras-chave