Pragma
O comando #pragma
é utilizado para realizar um controle de comportamentos definidos pela implementação, é uma maneira padronizada com que o programador possa "comunicar-se" com detalhes específicos do compilador.
Pode ser escrito de duas formas :
//Primeira forma
#pragma identificador parametros
//Segunda forma (C99)
_Pragma("identificador parametros")
#pragma
: se comporta de uma maneira definida pela implementação, a menos que seja um dos pragmas padrão especificados depois._Pragma
: Disponível desde oC99
, pode ser utilizado ao expandir uma macro, algo que é impossível com o#pragma
, seu conteúdo precisa estar no formato de string, e o conteúdo da string é lido como se fosse a entrada de um#pragma
.
Pragmas padrão
Desde o C99
foram adicionadas três pragmas padrão da linguagem, onde arg
pode ser ON
(ativo), OFF
(desativo) , DEFAULT
(padrão):
#pragma STDC FENV_ACCESS arg
: Indica que o usuário vai modificar o estado das flags de ponto flutuante do processador, proibindo algumas otimizações, geralmente o padrão é desabilitado.#pragma STDC FP_CONTRACT arg
: Permite otimizações de ponto flutuante que omitem erros de arredondamento e exceções de ponto flutuante que seriam observadas se a expressão fosse usada diretamente (por exemplo permite que(x*y)+z
seja implementado por uma instrução otimizada específica do processador ao invés de realizar a multiplicação e soma separadamente), geralmente o padrão é habilitado.#pragma STDC CX_LIMITED_RANGE arg
: Indica que multiplicação, divisão e o valor absoluto de números complexos podem usar formulas matemáticas simplificadas apesar da possibilidade de overflow intermediário, em outras palavras, o programador garante que a faixa de valores passadas a essas funções será limitada, desabilitado por padrão.
Alguns compiladores podem não suportar esses pragmas, mas devem ao menos ter as mesmas opções como opções de linha de comando do compilador.
Pragmas conhecidos
Todos os outros pragmas são definidos pela implementação, porém existem dois pragmas que são muito comuns : #pragma once
e #pragma pack
.
Pragma once
Uma forma mais simplificada de escrita que tem efeito similar a um include guard
conforme descrito no capítulo sobre inclusão de arquivos.
Basicamente ao utilizar #pragma once
, o arquivo será ignorado se for incluido novamente, de forma que possamos ter um efeito similar a um include guard
, porém sem a necessidade de criar uma macro única para o arquivo.
Pragma pack
Utilizado para controlar o alinhamento de uma struct
ou union
, pode ser utilizado de 5 formas, onde arg
é uma potência de 2 indicando o alinhamento:
#pragma pack(arg)
: Define o alinhamento como o valor dearg
.#pragma pack()
: Define o alinhamento como o valor padrão (especificado por um argumento da linha de comando).#pragma pack(push)
: Guarda o valor do alinhamento atual numa "stack" interna.#pragma pack(push, arg)
: Guarda o valor do alinhamento atual na "stack" interna, e define o alinhamento atual paraarg
.#pragma pack(pop)
: Remove o último valor de alinhamento da "stack" interna e define o alinhamento para aquele valor.