Include guard
Da Wikipedia, l'enciclopedia libera.
Nei linguaggi C e C++, le #include guard sono delle particolari direttive (o macro) che vengono usate nei file header per evitare problemi di doppia definizione in fase di linking.
Supponiamo di avere 3 file sorgenti senza #include guard:
class persona { // dichiarazione };
#include "persona.h" class impiegato : public persona { // dichiarazione };
#include "persona.h" #include "impiegato.h" int main() { persona p; impiegato i; }
In fase di compilazione, verrà creato un file oggetto: main.o Gli header files vengono inclusi nel file sorgente main.cpp ovvero il loro contenuto viene copiato dal preprocessore all'inizio del file main.cpp prima della compilazione.
Senza interessarci delle implementazioni di persona e impiegato, il nostro obiettivo sarà quello di usare indistintamente una persona o un impiegato (ed i relativi metodi). Quando il linker andrà a creare l'eseguibile definitivo, avrà una doppia dichiarazione di persona e rilascerà un errore di linkaggio. Infatti la classe persona sarà definita sia nel file persona.o che nel file impiegato.o. In quest'ultimo caso, quello del file impiegato.o, è necessario inserire la dichiarazione di persona per via della direttiva #include specificata.
Per non avere questo tipo di problema basta utilizzare le #include guard in questa maniera:
#ifndef PERSONA_H #define PERSONA_H // tutto il resto #endif // PERSONA_H
Con questo accorgimento, la prima volta che viene incluso persona.h, il simbolo PERSONA_H non è ancora stato definito, e di conseguenza viene creato. Le successive volte che viene incluso persona.h, il simbolo PERSONA_H è definito, perciò la parte relativa alla definizione della classe persona non viene tenuta in considerazione.
Di buona norma le #include guard devono essere inserite in tutti i file .h in modo da assicurare una maggiore trasparenza al programmatore evitando di incorrere in questo tipo di errore.
La seguente è un'alternativa equivalente agli include guard ma più breve e più semplice e a volte incrementa la velocità di compilazione.
#pragma once //tutto il resto
Indica che il file deve essere incluso una sola volta nella compilazione.
Nonostante questa direttiva non sia definita negli standard del C/C++, è definita in quasi tutti i compilatori.
| Compiler | #pragma once |
|---|---|
| Clang | Supportato |
| Comeau C/C++ | Supportato |
| C++Builder XE3 | Supportato |
| Digital Mars C++ | Supportato |
| GCC | Supportato |
| HP C/aC++ | Supportato |
| IBM XL C/C++ | Supportato |
| Intel C++ Compiler | Supportato |
| Microsoft Visual C++ | Supportato |
| Pelles C | Supportato |
| ARM DS-5 | Supportato |
| IAR C/C++ | Supportato |
| Solaris Studio C/C++ | Non supportato |
| C++ | |
|---|---|
| Standard del linguaggio | C++98 · C++03 · C++11 · C++14 · C++17 · C++20 · C++23 · C++26 |
| Librerie | Libreria standard C++ · Standard Template Library · Boost |
| Caratteristiche | Array · Dynamic cast · Include guard · Operatori |
| IDE | Anjuta · CLion · Code::Blocks · CodeLite · Dev-C++ · Eclipse · Geany · KDevelop · Microsoft Visual C++ · NetBeans |
| Persone legate al linguaggio | Bjarne Stroustrup |