La denominazione include guardie
-
28-10-2019 - |
Domanda
Come vengono in genere le guardie C ++? Tendo a vederlo molto:
#ifndef FOO_H
#define FOO_H
// ...
#endif
Tuttavia, non penso che sia molto intuitivo. Senza vedere il nome del file è difficile dire cosa FOO_H
c'è per e a cosa si riferisce il nome.
Cosa è considerata la migliore pratica?
Soluzione
Dalla mia esperienza, la convenzione è quella di nominare le guardie di inclusione dopo il file di intestazione contenente con l'eccezione che il nome è tutto in CAPS e che il periodo viene sostituito con un sottolineaggio.
Così test.h
diventa TEST_H
.
Esempi di vita reale di questo includono QT Creator, che segue questa convenzione quando si generano i file di intestazione della classe.
Altri suggerimenti
Seguo personalmente la raccomandazione di Boost. È forse una delle più grandi raccolte di librerie C ++ di buona qualità in circolazione e non hanno problemi.
Va come:
<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED
// include/pet/project/file.hpp
#ifndef PET_PROJECT_FILE_HPP_INCLUDED
che è:
- legale (si noti che inizi
_[A-Z]
o contenente__
non è) - facile da generare
- Garantito per essere unico (come incluso Guard) all'interno di un progetto (altrimenti hai due file nello stesso posto)
- garantito per non essere usato per nient'altro (se finisci un'altra macro con
INCLUDED
Stai viziando per una lotta)
Ho letto di GUID ma quelli sembrano strani.
E ovviamente vorrei piuttosto che tutti i compilatori implementano #pragma once
(o meglio, #pragma multiple
e "una volta" sii il comportamento predefinito ...)
Preso direttamente da Guida allo stile di Google:
Tutti i file di intestazione dovrebbero avere guardie #define per prevenire l'inclusione multipla. Il formato del nome del simbolo dovrebbe essereu003CPROJECT> _u003CPATH> _u003CFILE> _H_. Per garantire unicità, dovrebbero essere basati sull'intero percorso nell'albero di origine di un progetto. Ad esempio, il file foo/src/bar/baz.h nel progetto foo dovrebbe avere la seguente guardia:
#ifndef FOO_BAR_BAZ_H_ #define FOO_BAR_BAZ_H_ ... #endif // FOO_BAR_BAZ_H_
Uso questo stile nei miei progetti.
Guarda il codice che #include la tua intestazione.
Se è qualcosa di simile:
#include "mylib/myheader.h"
mylib/myheader.h
è già un nome univoco. Basta capitalizzare e sostituire / e. insieme a _
#define MYLIB_MYHEADER_H
Se hai due intestazioni sul percorso di Include con lo stesso nome relativo al percorso include, hai già una collisione a quel livello.
Sostituire FOO_H
insieme a FOO_H_INCLUDED
Ed è più chiaro.
Come altri menzionati in precedenza, una convenzione molto comune è quella di utilizzare la versione maiuscola del nome e il punto sostituito da un sottolineaggio: foo.h -> foo_h
Tuttavia, ciò può portare a collisioni di nome con nomi semplici e/o comuni. Per questo motivo, l'intestazione autogenerata come stDafx.h in progetti non vuoti C ++ aggiunge una stringa casuale, come:
#ifndef FOO_H__NsknZfLkajnTFBpHIhKS
#define FOO_H__NsknZfLkajnTFBpHIhKS
#endif
http://www.random.org/strings/ è un utile generatore casuale per questo.
Inoltre, se il file fa parte di qualche sottomodulo o il suo contenuto risiede in uno spazio dei nomi specifico, tendo ad aggiungerlo anche alla guardia:
#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS
namespace somecomponent
{
...
}
#endif
Normalmente uso qualcosa di simile FOO_H_INCLUDED_
. Alcune intestazioni (Microsoft) hanno quella che assomiglia molto a una rappresentazione di stringa di un GUID, ma non ho mai avuto bisogno di nulla di così elaborato.
Di solito le persone lo fanno per nome del file in modo che il codice di ogni file venga compilato e aggiunto solo una volta. Potresti fare foo_h qualunque cosa tu voglia, ma quasi tutto ciò che ho mai codificato o visto ha usato il nome del file. Assicurati solo che sia unico perché non vuoi il tuo foo_h in conflitto con il foo_h di qualcun altro.
Di solito guardo a che ora è e lo aggiungo alla fine, cioè FOO_H_248
, è una precauzione in più e non dovrai mai ricordarlo comunque, quindi non devi preoccuparti del fatto che sia criptico.