Tradicionalmente, a maneira padrão e portátil de evitar múltiplas inclusões de cabeçalho no C ++ era / é usar o #ifndef - #define - #endif
esquema de diretivas de pré-compilador, também chamado de esquema de guarda de macro (veja o trecho de código abaixo).
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
Na maioria das implementações / compiladores (veja a figura abaixo), no entanto, há uma alternativa mais "elegante" que serve ao mesmo propósito que o esquema de proteção macro chamado #pragma once
. #pragma once
possui várias vantagens em comparação com o esquema de proteção macro, incluindo menos código, prevenção de conflitos de nomes e, às vezes, maior velocidade de compilação.
Pesquisando, percebi que, embora a #pragma once
diretiva seja suportada por quase todos os compiladores conhecidos, há uma turvação sobre se a #pragma once
diretiva faz parte do padrão C ++ 11 ou não.
Questões:
- Alguém poderia esclarecer se a
#pragma once
diretiva faz parte do padrão C ++ 11 ou não? - Se não faz parte do padrão C ++ 11, há planos de incluí-lo em versões posteriores (por exemplo, C ++ 14 ou posterior)?
- Também seria bom se alguém pudesse aprofundar as vantagens / desvantagens no uso de qualquer uma das técnicas (por exemplo, proteção macro versus
#pragma once
).
#pragma once
geralmente não.Respostas:
#pragma once
não é padrão. É uma extensão generalizada (mas não universal), que pode ser usadaFoi considerado para padronização, mas rejeitado porque não pode ser implementado com confiabilidade. (Os problemas ocorrem quando você tem arquivos acessíveis através de várias montagens remotas diferentes.)
É bastante fácil garantir que não haja conflitos de guarda de inclusão em um único desenvolvimento. Para bibliotecas, que podem ser usadas por muitos desenvolvimentos diferentes, a solução óbvia é gerar muitos caracteres aleatórios para o guarda de inclusão quando você o criar. (Um bom editor pode ser configurado para fazer isso sempre que você abrir um novo cabeçalho.) Mas mesmo sem isso, ainda não encontrei problemas com conflitos entre bibliotecas.
fonte
pragma once
não é possível implementar de maneira portável algo que não seja portátil (e nem deveria ser considerado) é mais uma bobagem do mundo invertido do C ++.#include
deve ser removido, porque é possível usar cegamente a diretiva.#pragma once
não restringe a portabilidade de forma alguma, desde que você não explore os links simbólicos para interromper a compilação.A seção §16.6 da Norma ( rascunho N3936 ) descreve as
#pragma
diretrizes como:Basicamente,
#pragma once
é uma instância específica de implementação de uma#pragma
diretiva e não, não é padrão. Ainda.Muitas vezes, é amplamente suportado pela maioria dos "principais compiladores", incluindo GCC e Clang, e, portanto, às vezes é recomendado para evitar clichês de inclusão.
fonte
#pragma
e#define
guarda de cabeçalho.#define
um protetor de cabeçalho, ele / ela NÃO tem motivos para escrever#pragma once
também.#pragma once
d e, no caso de ser#include
novamente d, pode pular o#include
(nem mesmo abrir o arquivo). O gcc faz o mesmo com os protetores de cabeçalho, mas é muito, muito frágil. O#pragma
primeiro é fácil de fazer, o outro é difícil.