Hay una diferencia sutil en que si SOME_HEADER_H
ya se ha definido antes se incluye la cabecera, a continuación, en el segundo caso el preprocesador procesará la #pragma once
, y en el primero caso no lo hará
verás una diferencia funcional si #undef SOME_HEADER_H
e incluir el archivo de nuevo por el mismo TU:
#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"
Ahora, en el caso 1 Tengo todas las definiciones del archivo de cabecera. En el caso 2, yo no.
Incluso sin el #undef
, es posible que vea una diferencia en el tiempo de preprocesamiento debido a que el #pragma once
se ha ignorado en el caso 1. Eso depende de la implementación.
puedo pensar en dos maneras plausibles que ya se podría definir antes de la primera inclusión de este archivo de cabecera:
- (la más obvia) un archivo completamente separado define, ya sea deliberadamente o por nombre de choque accidental ,
- una copia de este archivo ya lo ha definido. Dependiendo de la implementación que pueda incluir el caso donde este archivo se involucra en la misma TU bajo dos nombres de archivo diferentes, p. debido a un enlace simbólico o fusión del sistema de archivos. Si su implementación es compatible con
#pragma once
, y examina su documentación detenidamente, puede encontrar una declaración definitiva sobre si la optimización se aplica por la ruta en la que se incluye el archivo, o por comparación de algo que identifica el almacenamiento de un archivo, como número de inodo Si es este último, incluso podrá averiguar si todavía hay estafas que podrían ser engañadas para engañar al preprocesador, como el montaje remoto de un sistema de archivos local para ocultar que es "el mismo archivo realmente" ...
Aunque se usa de la manera esperada, no hay diferencia siempre que la implementación trate #pragma once
de la manera en que Microsoft lo define. Siempre que se procese en lugar de omitirse, marcará el archivo que contiene la optimización, por lo que no importa si se procesará o no en un segundo pase a través del archivo; el segundo pase no ocurrirá.
Y, por supuesto, dado que el pragma no es estándar, al menos en teoría podría tener un significado completamente diferente en diferentes implementaciones, en cuyo caso podría importar cuándo y cuántas veces se procesa. En la práctica, uno pensaría que nadie hará eso.
Es bastante redundante incluir ambos, ¿no crees? Solo usaría las definiciones para verificar. –
posible duplicado de [#pragma una vez vs incluir guardias?] (Http://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards) – Jon
@Tim: no son redundantes en un compilador que reconoce "pragma una vez", pero no realiza la optimización inteligente que hace gcc, para detectar cuándo las protecciones de los encabezados no le permiten volver a visitar el archivo. Al menos algunas versiones de MSVC se encuentran en ese estado, no se conocen las últimas. –