una taladro steelock pilas llave fuerte first con como clave caja bloqueo antigua abrir c++ include-guards

c++ - taladro - ¿Es#pragma una vez que una caja fuerte incluye guardia?



como abrir una caja fuerte steelock sin llave y sin clave (14)

He leído que hay una optimización del compilador al usar #pragma once que puede resultar en una compilación más rápida. Reconozco que no es estándar y, por lo tanto, podría plantear un problema de compatibilidad entre plataformas.

¿Es esto algo que es compatible con la mayoría de los compiladores modernos en plataformas que no son Windows (gcc)?

Quiero evitar los problemas de compilación de la plataforma, pero también quiero evitar el trabajo adicional de los guardias de reserva:

#pragma once #ifndef HEADER_H #define HEADER_H ... #endif // HEADER_H

¿Debería Preocuparme? ¿Debo gastar más energía mental en esto?


Al usar gcc 3.4 y 4.1 en árboles muy grandes (a veces haciendo uso de distcc ), todavía no he visto ninguna aceleración al usar #pragma una vez en lugar de, o en combinación con las guardas estándar.

Realmente no veo cuánto vale la pena confundir versiones anteriores de gcc, o incluso otros compiladores, ya que no hay ahorros reales. No he probado todos los diferentes destiladores, pero estoy dispuesto a apostar que confundirá a muchos de ellos.

Ojalá hubiera sido adoptado desde el principio, pero puedo ver el argumento "¿Por qué necesitamos eso cuando ifndef funciona perfectamente bien?". Dados los muchos rincones oscuros y las complejidades de C, incluir guardias es una de las cosas más fáciles y autoexplicativas. Si tiene un pequeño conocimiento de cómo funciona el preprocesador, deben explicarse por sí mismos.

Sin embargo, si observa una aceleración significativa, actualice su pregunta.


Desearía que #pragma once (o algo así) hubiera estado en el estándar. Incluir guardias no es un gran problema (pero parece ser un poco difícil de explicar a las personas que aprenden el idioma), pero parece una molestia menor que podría haberse evitado.

De hecho, dado que 99.98% del tiempo, el comportamiento de #pragma once es el comportamiento deseado, hubiera sido bueno si el compilador se encargara automáticamente de evitar la inclusión múltiple de un encabezado, con un #pragma o algo para permitir el doble incluido.

Pero tenemos lo que tenemos (excepto que es posible que no tengas #pragma once ).


El beneficio de rendimiento es que no tiene que volver a abrir el archivo una vez que se ha leído #pragma. Con los guardias, el compilador tiene que abrir el archivo (que puede ser costoso en el tiempo) para obtener la información de que no debe incluir su contenido nuevamente.

Esa es la teoría solo porque algunos compiladores no abrirán automáticamente archivos que no tengan ningún código de lectura para cada unidad de compilación.

De todos modos, no es el caso de todos los compiladores, así que lo ideal es que #pragma, una vez que se debe evitar el código multiplataforma, no es estándar en absoluto / no tiene una definición y efecto estandarizados. Sin embargo, en la práctica, es realmente mejor que los guardias.

Al final, la mejor sugerencia que puede obtener para asegurarse de tener la mejor velocidad de su compilador sin tener que verificar el comportamiento de cada compilador en este caso, es usar pragma una vez y guardas.

#ifndef NR_TEST_H #define NR_TEST_H #pragma once #include "Thing.h" namespace MyApp { // ... } #endif

De esa forma, obtendrá lo mejor de ambos (multiplataforma y velocidad de compilación de ayuda).

Ya que es más largo para escribir, personalmente uso una herramienta para ayudar a generar todo eso de una manera muy inteligente (Visual Assist X).


El uso de '' #pragma once '' podría no tener ningún efecto (no se admite en todas partes, aunque se admite cada vez más), por lo que debe usar el código de compilación condicional de todos modos, en cuyo caso, ¿por qué molestarse con '' #pragma once ''? El compilador probablemente lo optimice de todos modos. Sin embargo, depende de sus plataformas de destino. Si todos sus objetivos lo soportan, entonces continúe y utilícelo, pero debe ser una decisión consciente porque todo el infierno se desatará si solo usa el pragma y luego el puerto a un compilador que no lo admite.


GCC admite #pragma once desde la #pragma once 3.4, consulte http://en.wikipedia.org/wiki/Pragma_once para obtener más información sobre el compilador.

La gran ventaja que veo al usar #pragma once en lugar de incluir guardas es evitar errores de copiar / pegar.

Afrontémoslo: la mayoría de nosotros apenas iniciamos un nuevo archivo de encabezado desde cero, sino que simplemente copiamos uno existente y lo modificamos según nuestras necesidades. Es mucho más fácil crear una plantilla de trabajo usando #pragma once lugar de incluir guardas. Cuanto menos tenga que modificar la plantilla, menos probabilidades hay de encontrar errores. Tener el mismo include guard en diferentes archivos conduce a errores extraños en el compilador y lleva algo de tiempo averiguar qué salió mal.

TL; DR: #pragma once es más fácil de usar.


Hoy en día, los guardias de la vieja escuela son tan rápidos como un #pragma una vez. Incluso si el compilador no los trata especialmente, se detendrá cuando vea #ifndef WHATEVER y WHATEVER está definido. Abrir un archivo es muy barato hoy. Incluso si hubiera una mejora, sería del orden de milisegundos.

Simplemente no uso #pragma una vez, ya que no tiene ningún beneficio. Para evitar choques con otras guardias de inclusión, uso algo como: CI_APP_MODULE_FILE_H -> CI = Company Initials; APP = nombre de la aplicación; el resto se explica por sí mismo.


La principal diferencia es que el compilador tuvo que abrir el archivo de encabezado para leer el protector de inclusión. En comparación, pragma una vez hace que el compilador realice un seguimiento del archivo y no haga ningún IO de archivo cuando se encuentre con otra inclusión para el mismo archivo. Si bien eso puede parecer insignificante, puede escalar fácilmente con grandes proyectos, especialmente los que no tienen un buen encabezado incluyen disciplinas.

Dicho esto, en estos días los compiladores (incluido GCC) son lo suficientemente inteligentes como para tratar a los guardias como pragma una vez. es decir, no abren el archivo y evitan la penalización de IO del archivo.

En compiladores que no soportan pragma, he visto implementaciones manuales que son un poco engorrosas.

#ifdef FOO_H #include "foo.h" #endif

Personalmente, me gusta el enfoque de #pragma once ya que evita la molestia de nombrar colisiones y posibles errores tipográficos. También es un código más elegante en comparación. Dicho esto, para el código portátil, no debería hacer daño tener ambos a menos que el compilador se queje de ello.


Lo uso y estoy contento con él, ya que tengo que escribir mucho menos para hacer un nuevo encabezado. Funcionó bien para mí en tres plataformas: Windows, Mac y Linux.

No tengo ninguna información sobre el rendimiento, pero creo que la diferencia entre #pragma y include guarda no será nada en comparación con la lentitud de analizar la gramática de C ++. Ese es el verdadero problema. Intente compilar la misma cantidad de archivos y líneas con un compilador de C #, por ejemplo, para ver la diferencia.

Al final, usar la guardia o el pragma, no importará en absoluto.


No conozco ningún beneficio de rendimiento, pero ciertamente funciona. Lo uso en todos mis proyectos de C ++ (si estoy usando el compilador de MS). Me parece más efectivo que usar

#ifndef HEADERNAME_H #define HEADERNAME_H ... #endif

Hace el mismo trabajo y no llena el preprocesador con macros adicionales.

GCC soporta #pragma once oficialmente a partir de la versión 3.4 .


No siempre.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52566 tiene un buen ejemplo de dos archivos destinados a ser incluidos ambos, pero erróneamente se piensa que son idénticos debido a sellos de tiempo y contenido idénticos (nombre de archivo no idéntico) .


Nota adicional para las personas que piensan que siempre se desea una inclusión automática de los archivos de encabezado por única vez: construyo generadores de código con inclusión doble o múltiple de los archivos de encabezado desde décadas. Especialmente para la generación de apéndices de la biblioteca de protocolos, me parece muy cómodo tener un generador de código extremadamente portátil y potente sin herramientas ni idiomas adicionales. No soy el único desarrollador que usa este esquema como lo muestran los blogs de X-Macros . Esto no sería posible sin la protección automática faltante.


Si usamos msvc o Qt (hasta Qt 4.5), dado que GCC (hasta 3.4), msvc ambos admiten #pragma once , no veo ninguna razón para no usar #pragma once .

El nombre del archivo de origen suele ser el mismo nombre de clase, y sabemos que, en algún momento necesitamos refactorizar , para cambiar el nombre de la clase, luego tuvimos que cambiar el #include XXXX también, por lo que creo que el mantenimiento manual del #include xxxxx no es un trabajo inteligente. incluso con la extensión Visual Assist X, mantener el "xxxx" no es un trabajo necesario.


Usar #pragma once debería funcionar en cualquier compilador moderno, pero no veo ninguna razón para no usar un #ifndef inclusión #ifndef estándar. Funciona bien La única advertencia es que GCC no #pragma once antes de la versión 3.4 .

También encontré que, al menos en GCC, reconoce el estándar #ifndef incluye guardia y lo optimiza , por lo que no debería ser mucho más lento que #pragma once .


#pragma once tiene un inconveniente (aparte de no ser estándar) y es que si tiene el mismo archivo en diferentes ubicaciones (tenemos esto porque nuestro sistema de compilación copia los archivos), el compilador pensará que estos son archivos diferentes.