2010-08-13 9 views
18

acabamos de ver esto dentro <boost/asio.hpp>¿Cuál es el motivo de #pragma una vez dentro de los protectores de encabezado?

#ifndef BOOST_ASIO_HPP 
#define BOOST_ASIO_HPP 

#if defined(_MSC_VER) && (_MSC_VER >= 1200) 
# pragma once 
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 

/// .... 

#endif // BOOST_ASIO_HPP 

Sin tener en cuenta los cheques _MSC_VER preprocesador, ¿cuál es el beneficio de tener el #pragma once en este caso? ¿El protector de encabezado del preprocesador no garantiza en todos los casos y en todas las plataformas, que el contenido del encabezado solo sea included una vez?

Respuesta

21

#pragma once especifica que el archivo se incluirá (abierto) sola vez por el compilador cuando se compila un archivo de código fuente. Esto puede reducir los tiempos de compilación ya que el compilador no abrirá y leerá el archivo después del primer #include del módulo.

Si no #pragma once, el archivo se abrió cada vez se necesita y compilador se detendrá analizarlo en #ifndef BOOST_ASIO_HPP, si se ha definido.

+0

¿Estás diciendo que el encabezado está abierto y leído solo una vez si tenemos #pragma? Los protectores de cabecera significan que el archivo siempre está abierto, pero se omite el contenido dentro de los guardias, ¿verdad? Es mi entendimiento correcto? Si solo pudiera demostrar esto, lo veo suceder :) – dubnde

+1

En caso de #pragma una vez, no siempre está abierto. Esta directiva hace que el compilador recuerde no abrirla nuevamente (más de una vez). Es por eso que esta directiva es superior a #ifndef, que podría omitirse. Sin embargo, muchas personas todavía usan #ifndef para admitir compiladores antiguos que no reconocen #pragma una vez. –

0

Sí guardias de encabezado garantiza que el contenido del encabezado se incluya solo una vez. pero aquí está usando #pragma para verificar otra definición y no incluir el archivo.

El siguiente enlace es una pregunta existente sobre guardias de encabezado en SO.

Purpose of Header guards

+1

El protector de cabecera hace esto de todos modos, ¿verdad? ¿Por qué también necesitas #pragma una vez? – dubnde

+4

El protector de encabezado le dice al preprocesador que debe silenciar todas las líneas del archivo del '# ifndef' al' # endif', pero se supone que el preprocesador lee todo el archivo y simplemente no genera ningún resultado para el bloque. El '#pragma una vez' le dice al preprocesador que cualquier' 'include 'posterior que contenga el mismo archivo será ignorado. La diferencia es que en este último caso el preprocesador ni siquiera abrirá el archivo y comprobará. Dicho esto, '#pragma una vez' no es estándar, y los compiladores han crecido para comprender el patrón de incluir protector y no debería haber mucha diferencia. –

+0

@MeThinks: quizás no todas las implementaciones admitan este pragma, por lo que aún desea evitar que su encabezado se procese varias veces. El pragma es un beneficio adicional aquí. (comentario duplicado de otra respuesta) – ysap

3
+1

¿Por qué votar abajo? – DumbCoder

+1

bien. Entiendo el propósito de los guardias de cabecera.La pregunta es por qué tenemos header guard y pragma one – dubnde

+1

@MeThinks - tal vez no todas las implementaciones son compatibles con este pragma, por lo que aún desea evitar que su encabezado se procese varias veces. El pragma es un beneficio adicional aquí. – ysap

0

#pragma once tiene la misma finalidad, pero las guardias incluyen la intención de requerir un análisis más profundo para garantizar que un archivo se incluye exactamente una vez, p. Ej.

// somerandomfileinmyproject.cpp 
#undef BOOST_ASIO_HPP 
#include <bost/asio.cpp> 

A menos que el compilador hace manejar estos casos correctamente, que todavía tiene que abrir el archivo y pasarla a través del preprocesador a pesar de que se ha incluido antes.

0

Puede reproducir el efecto de la #pragma once de una manera estándar utilizando la siguiente:

#if !defined GUARD_SYMBOL 
#include "GUARDED_FILE" 
#endif 

aunque es mucho más prolija. Como han dicho otros, ayuda con los tiempos de compilación ya que el archivo no se busca/abre en lugar de abrir el archivo e ignorar todo lo que contiene: el archivo aún tiene que ser analizado por el preprocesador.

+1

Como señaló David anteriormente, la mayoría de los compiladores modernos (especialmente gcc) entiende el patrón de protección del encabezado lo suficientemente bien como para omitir la parte reparsing y actuar como si hubiera un pragma una vez o como si el código se escribiera de la manera que se muestra aquí. Esto, y el hecho de que pragma una vez no puede manejar correctamente algunos casos de esquina es también la razón por la cual pragma una vez ha sido activamente rechazado de ser introducido en el nuevo estándar C++ 0x. vea también esto [SO disscussion] (http://stackoverflow.com/questions/787533/is-pragma-once-a-safe-include-guard) –

Cuestiones relacionadas