Traditionnellement, le moyen standard et portable d'éviter les inclusions d'en-têtes multiples en C ++ était / consiste à utiliser le #ifndef - #define - #endif
schéma de directives pré-compilateur également appelé schéma de macro-garde (voir l'extrait de code ci-dessous).
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
Dans la plupart des implémentations / compilateurs (voir l'image ci-dessous) cependant, il existe une alternative plus "élégante" qui sert le même objectif que le schéma de macro-garde appelé #pragma once
. #pragma once
présente plusieurs avantages par rapport au schéma de macro-garde, notamment moins de code, éviter les conflits de noms et parfois une vitesse de compilation améliorée.
En faisant quelques recherches, je me suis rendu compte que, bien que la #pragma once
directive soit prise en charge par presque tous les compilateurs connus, il y a une incertitude quant à savoir si la #pragma once
directive fait partie du standard C ++ 11 ou non.
Des questions:
- Quelqu'un pourrait-il clarifier si la
#pragma once
directive fait partie du standard C ++ 11 ou non? - S'il ne fait pas partie de la norme C ++ 11, est-il prévu de l'inclure dans les versions ultérieures (par exemple, C ++ 14 ou version ultérieure)?
- Ce serait également bien si quelqu'un pouvait développer davantage les avantages / inconvénients de l'utilisation de l'une ou l'autre des techniques (c.-à-d. Macro-garde contre
#pragma once
).
#pragma once
généralement pas.Réponses:
#pragma once
n'est pas standard. C'est une extension répandue (mais pas universelle), qui peut être utiliséeIl a été envisagé pour la normalisation, mais rejeté car il ne peut pas être mis en œuvre de manière fiable. (Les problèmes se produisent lorsque vous avez des fichiers accessibles via plusieurs montages distants différents.)
Il est assez facile de s'assurer qu'il n'y a pas de conflits d'inclusion de garde dans un seul développement. Pour les bibliothèques, qui peuvent être utilisées par de nombreux développements différents, la solution évidente est de générer beaucoup de caractères aléatoires pour la garde d'inclusion lorsque vous la créez. (Un bon éditeur peut être configuré pour le faire pour vous chaque fois que vous ouvrez un nouvel en-tête.) Mais même sans cela, je n'ai pas encore rencontré de problèmes de conflits entre bibliothèques.
la source
pragma once
ne peut pas implémenter de manière portative quelque chose qui n'est pas en soi portable (et ne devrait même pas être considéré) est encore un autre non-sens du monde à l'envers du C ++.#include
devait être supprimé, car on peut abuser aveuglément de la directive.#pragma once
ne limite en aucune façon la portabilité, à condition que vous n'utilisiez pas les liens symboliques pour interrompre la compilation.La section §16.6 de la norme ( projet N3936 ) décrit les
#pragma
directives comme:Fondamentalement, il
#pragma once
s'agit d'une instance spécifique de mise en œuvre d'une#pragma
directive, et non, ce n'est pas standard. Encore.Il est souvent largement supporté par la plupart des "grands compilateurs", y compris GCC et Clang, et il est donc parfois recommandé d'éviter le passe-partout d'inclusion-gardes.
la source
#pragma
et#define
head-guard.#define
en-tête-garde, il / elle n'a AUCUNE raison d'écrire#pragma once
aussi.#pragma once
d, et dans le cas où il est à#include
nouveau d peut sauter le#include
(pas même ouvrir le fichier). gcc fait la même chose avec les protections d'en-tête, mais il est très, très fragile. Celui#pragma
est facile à faire, celui du garde-tête est dur.