Include guard: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
ZéroBot (discussione | contributi)
m r2.7.1) (Bot: Aggiungo fr:Include guard
Xr1blu (discussione | contributi)
Funzionalità collegamenti suggeriti: 1 collegamento inserito.
 
(19 versioni intermedie di 14 utenti non mostrate)
Riga 1:
{{F|linguaggi di programmazione|febbraio 2013}}
Nei linguaggi [[C (linguaggio)|C]] e [[C++]], le #'''include guard''' sono delle particolari direttive (o [[Macro (informatica)|macro]]) che vengono usate nei file header per evitare problemi di averedoppia spiacevoli erroridefinizione in fase di linking. In alcuni casi è proprio impossibile farne a meno, specialmente se il progetto inizia ad avere molti file sorgenti.
 
== Esempio ==
VediamoSupponiamo oradi unavere esempio3 difile utilizzosorgenti dellesenza #include guard. Supponiamo di avere 3 file sorgenti:
 
=== <ttkbd>persona.h</ttkbd> ===
 
<sourcesyntaxhighlight lang="Cpp">
class persona
{
// dichiarazione
};
</syntaxhighlight>
</source>
 
=== <ttkbd>impiegato.h</ttkbd> ===
 
<sourcesyntaxhighlight lang="Cpp">
#include< "persona.h>"
 
class impiegato : public persona
Riga 22 ⟶ 23:
// dichiarazione
};
</syntaxhighlight>
</source>
 
=== <ttkbd>main.cpp</ttkbd> ===
 
<sourcesyntaxhighlight lang="Cpp">
#include< "persona.h>"
#include< "impiegato.h>"
 
int main()
Riga 35 ⟶ 36:
impiegato i;
}
</syntaxhighlight>
</source>
 
== Compilazione ==
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.
In fase di compilazione, verranno creati 3 file oggetto:
# <tt>persona.o</tt> che contiene la dichiarazione e definizione di una persona;
# <tt>impiegato.o</tt> che contiene la dichiarazione e definizione di un impiegato e ''la dichiarazione di una persona'';
# <tt>main.o</tt> che contiene tutto ciò che serve al main.
 
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à però una doppia dichiarazione di persona e rilascerà un errore di linkaggio. Infatti la classe persona sarà definita sia nel file <ttkbd>persona.o</ttkbd> che nel file <ttkbd>impiegato.o</ttkbd>. In quest'ultimo caso, quello del file <kbd>impiegato.o</kbd>, è 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:
 
=== <ttkbd>persona.h</ttkbd> ===
 
<sourcesyntaxhighlight lang="Cpp">
#ifndef H_PERSONAPERSONA_H
#define H_PERSONAPERSONA_H
 
// tutto il resto
 
#endif // PERSONA_H
</syntaxhighlight>
</source>
 
Con questo ''trucchetto''accorgimento, la prima volta che viene incluso <ttkbd>persona.h</ttkbd>, il simbolo '''H_PERSONAPERSONA_H''' non è ancora stato definito, e di conseguenza viene creato. Le successive volte che viene incluso <ttkbd>persona.h</ttkbd>, il simbolo '''H_PERSONAPERSONA_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 <ttkbd>.h</ttkbd> in modo da assicurare una maggiore trasparenza al programmatore evitando di incorrere in questo tipo di errore.
 
==#pragma once==
 
La seguente è un'alternativa equivalente agli include guard ma più breve e più semplice e a volte incrementa la velocità di compilazione.
 
=== <kbd>persona.h</kbd> ===
 
<syntaxhighlight lang="Cpp">
#pragma once
 
//tutto il resto
</syntaxhighlight>
 
Indica che il file deve essere incluso una sola volta nella compilazione.
 
===Portabilità===
 
Nonostante questa direttiva non sia definita negli standard del C/C++, è definita in quasi tutti i compilatori.
 
{| class="wikitable sortable"
|-
! Compiler
! #pragma once
 
|-
| [[Clang]] || Supportato
|-
| [[Comeau C/C++]] || Supportato
|-
| [[C++Builder XE3]] || Supportato
|-
| [[Digital Mars C++]] || Supportato
|-
| [[GNU Compiler Collection|GCC]] || Supportato
|-
| [[HP aC++|HP C/aC++]] || Supportato
|-
| [[IBM XL C++|IBM XL C/C++]] || Supportato
|-
| [[Intel C++ Compiler]] || Supportato
|-
| [[Microsoft Visual C++]] || Supportato
|-
| [[Pelles C]] || Supportato
|-
| [[ARM DS-5]] || Supportato
|-
| [[IAR C/C++]] || Supportato
|-
| [[Oracle Solaris Studio|Solaris Studio C/C++]] || Non supportato
|}
 
{{C++}}
[[Categoria:Teorie della programmazione]]
[[Categoria:C++]]
{{portale|informatica}}
 
[[Categoria:C]]
[[de:Include Guard]]
[[Categoria:C++]]
[[en:Include guard]]
[[fa:Include guard]]
[[fr:Include guard]]
[[ru:Include guard]]
[[zh:Include防範]]