Tradicionalmente, la forma estándar y portátil de evitar múltiples inclusiones de encabezado en C ++ era / es usar el #ifndef - #define - #endif
esquema de directivas precompilador también llamado esquema de macro-guardia (vea el fragmento de código a continuación).
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
Sin embargo, en la mayoría de las implementaciones / compiladores (vea la imagen a continuación), hay una alternativa más "elegante" que sirve para el mismo propósito que el esquema de macro-guardia llamado #pragma once
. #pragma once
tiene varias ventajas en comparación con el esquema de macro-guardia, que incluye menos código, evitar conflictos de nombres y, a veces, una velocidad de compilación mejorada.
Investigando un poco, me di cuenta de que aunque la #pragma once
directiva es compatible con casi todos los compiladores conocidos, existe una turbidez sobre si la #pragma once
directiva es parte del estándar C ++ 11 o no.
Preguntas:
- ¿Podría alguien aclarar si la
#pragma once
directiva es parte del estándar C ++ 11 o no? - Si no es parte del estándar C ++ 11, ¿hay planes para incluirlo en versiones posteriores (por ejemplo, C ++ 14 o posterior)?
- También sería bueno si alguien pudiera profundizar en las ventajas / desventajas en el uso de cualquiera de las técnicas (es decir, macro-guardia versus
#pragma once
).
#pragma once
generalmente no.Respuestas:
#pragma once
No es estándar. Es una extensión extendida (pero no universal), que se puede usarSe consideró para la estandarización, pero se rechazó porque no se puede implementar de manera confiable. (Los problemas se producen cuando tiene archivos accesibles a través de varios montajes remotos diferentes).
Es bastante fácil asegurarse de que no haya conflictos de protección de inclusión dentro de un solo desarrollo. Para las bibliotecas, que pueden ser utilizadas por muchos desarrollos diferentes, la solución obvia es generar muchos caracteres aleatorios para el protector de inclusión cuando lo cree. (Se puede configurar un buen editor para que haga esto por usted cada vez que abra un nuevo encabezado). Pero incluso sin esto, todavía no he encontrado ningún problema con conflictos entre bibliotecas.
fuente
pragma once
no se puede implementar de manera portátil algo que no es inherentemente portátil (y que ni siquiera se debe considerar) es otra tontería del mundo al revés de C ++.#include
tiene que eliminarse, ya que se puede usar indebidamente la directiva.#pragma once
no restringe la portabilidad de ninguna manera, siempre que no explote los enlaces simbólicos para romper la compilación.La Sección § 16.6 de la Norma ( borrador N3936 ) describe las
#pragma
directivas como:Básicamente
#pragma once
es una instancia específica de implementación de una#pragma
directiva, y no, no es estándar. Todavía.A menudo es ampliamente compatible con la mayoría de los "compiladores principales", incluidos GCC y Clang y, por lo tanto, a veces se recomienda evitar la placa de protección de inclusión.
fuente
#pragma
y#define
encabezado-guardia.#define
encabezado, él / ella NO tiene razón para escribir#pragma once
también.#pragma once
d, y en el caso de que sea#include
d nuevamente puede omitir el#include
(ni siquiera abrir el archivo). gcc hace lo mismo con los protectores de encabezado, pero es muy, muy frágil. El#pragma
uno es fácil de hacer, el protector de cabecera es difícil.