2010-08-13 8 views
18

appena visto questo all'interno <boost/asio.hpp>Qual è la ragione per #pragma una volta all'interno delle protezioni?

#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 

La mancata osservanza delle _MSC_VER controlli preprocessore, qual è il vantaggio di avere il #pragma once in questo caso? La protezione dell'intestazione del preprocessore non garantisce in tutti i casi e su tutte le piattaforme, i contenuti dell'intestazione sono sempre solo included una volta?

risposta

21

#pragma once specifica che il file sarà incluso (aperto) solo una volta dal compilatore quando si compila un file di codice sorgente. Questo può ridurre i tempi di compilazione in quanto il compilatore non si apre e legge il file dopo il primo #include del modulo.

Se non #pragma once, il file sarà aperto ogni volta è necessario e compilatore si fermerà l'analisi su #ifndef BOOST_ASIO_HPP, se è stato definito.

+0

Stai dicendo che l'intestazione è aperta e leggi solo una volta se abbiamo #pragma? Le guardie di intestazione significa che il file è sempre aperto ma i contenuti all'interno delle guardie vengono saltati, giusto? La mia comprensione è corretta? Se solo potessi dimostrarlo così vedo che succede :) – dubnde

+1

In caso di #pragma una volta non è sempre aperto. Questa direttiva fa ricordare al compilatore di non riaprirla (più di una volta). Ecco perché questa direttiva è superiore a #ifndef, che potrebbe essere omessa. Tuttavia molte persone usano ancora #ifndef per supportare vecchi compilatori che non riconoscono #pragma una volta. –

0

Sì, le protezioni di intestazione assicurano che i contenuti dell'intestazione siano inclusi solo una volta. ma qui stai usando #pragma per controllare un'altra definizione e non includere il file.

Il link sottostante è una domanda esistente su protezioni intestazione in SO.

Purpose of Header guards

+1

Il parapetto lo fa comunque, giusto? perché ha bisogno di #pragma anche una volta? – dubnde

+4

La protezione intestazione dice al preprocessore che deve silenziare tutte le righe nel file da '# ifndef' a' # endif', ma si presume che il preprocessore legga l'intero file e non produca alcun risultato per il blocco. Il '#pragma once' dice al preprocessore che ogni successivo' # include' che contiene lo stesso file deve essere ignorato. La differenza è che in quest'ultimo caso il preprocessore non apre nemmeno il file e controlla. Detto questo, '#pragma once' non è standard, e i compilatori sono cresciuti per comprendere il pattern di protezione incluso e non ci dovrebbe essere molta differenza. –

+0

@MeThinks - forse non tutte le implementazioni supportano questo pragma, quindi vuoi ancora evitare che l'intestazione venga elaborata più volte. Il pragma è un ulteriore vantaggio qui. (commento duplicato da un'altra risposta) – ysap

3
+1

Perché il voto negativo? – DumbCoder

+1

ok. Capisco lo scopo delle guardie di intestazione.La domanda è perché abbiamo header guard e pragma one – dubnde

+1

@MeThinks - forse non tutte le implementazioni supportano questo pragma, quindi vuoi ancora evitare che l'intestazione venga elaborata più volte. Il pragma è un ulteriore vantaggio qui. – ysap

0

#pragma once#pragma once ha lo stesso scopo, ma includere le guardie hanno lo scopo di richiedere un'analisi più approfondita per garantire che un file sia incluso esattamente una volta - ad es.

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

A meno che il compilatore fa gestire questi casi in modo corretto, ha ancora bisogno di aprire il file e passarlo attraverso il preprocessore anche se è stato inserito prima.

0

è possibile riprodurre l'effetto del #pragma once in modo standard utilizzando il seguente:

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

anche se è molto più dettagliato. Come altri hanno già detto, aiuta con i tempi di compilazione dal momento che il file non viene ricercato/aperto invece di aprire il file e ignorare tutto al suo interno - il file deve ancora essere analizzato dal preprocessore.

+1

Come notato in precedenza da David, la maggior parte dei compilatori moderni (in particolare gcc) comprende il modello di protezione dell'intestazione abbastanza bene da saltare la parte di reparsing, e si comporta come se ci fosse un pragma una volta o come se il codice fosse stato scritto come mostrato qui. Questo, e il fatto che una volta pragma non può gestire correttamente alcuni casi d'angolo è anche il motivo per cui una volta la pragma è stata attivamente rifiutata dall'essere stata introdotta nel nuovo standard C++ 0x. vedi anche questo [SO discoscenza] (http://stackoverflow.com/questions/787533/is-pragma-once-a-safe-include-guard) –

Problemi correlati