web-dev-qa-db-fra.com

#Pragma fait-il une fois partie du standard C ++ 11?

Traditionnellement, le moyen standard et portable d'éviter les inclusions d'en-têtes multiples en C++ était/consistait à utiliser le schéma de directives de pré-compilation #ifndef - #define - #endif Également appelé schéma de macro-garde (voir l'extrait de code ci-dessous). .

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

Cependant, dans la plupart des implémentations/compilateurs (voir image ci-dessous), il existe une alternative plus "élégante" servant le même objectif que le schéma de macro-garde appelé #pragma once . #pragma once Présente plusieurs avantages par rapport au système de macro-protection, notamment une réduction du code, une prévention des conflits de noms et, parfois, une amélioration de la vitesse de compilation.

enter image description here

En faisant des recherches, je me suis rendu compte que bien que la directive #pragma once Soit supportée par presque tous les compilateurs connus, il existe un trouble quant au fait que la directive #pragma once Fasse partie de la norme C++ 11 ou non.

Questions:

  • Quelqu'un pourrait-il préciser si la directive #pragma once Fait partie de la norme C++ 11 ou non?
  • Si cela 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 une version ultérieure)?
  • Ce serait également agréable si quelqu'un pouvait préciser les avantages/inconvénients de l'utilisation de l'une ou l'autre des techniques (c'est-à-dire la macro-garde contre #pragma once).
133
101010

#pragma once est pas standard. C’est une extension répandue (mais pas universelle), qui peut être utilisée

  • si vos problèmes de portabilité sont limités, et
  • vous pouvez être sûr que tous vos fichiers d'inclusion sont toujours sur un disque local.

Il a été envisagé d'être normalisé, 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 dans un seul développement. Pour les bibliothèques, qui peuvent être utilisées par de nombreux développements différents, la solution évidente consiste à générer un grand nombre de caractères aléatoires pour la protection d'inclusion lorsque vous le 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 encore rencontré aucun problème de conflit entre bibliothèques.

103
James Kanze

La section §16.6 de la norme ( N3936 projet) décrit #pragma directives comme:

Une directive de prétraitement de la forme

# pragma pp-tokensopt new-line

provoque la mise en œuvre de se comporter d'une manière définie par la mise en œuvre. Ce comportement peut entraîner l'échec de la traduction ou entraîner un comportement non conforme du traducteur ou du programme résultant. Tout pragma qui n'est pas reconnu par l'implémentation est ignoré.

Fondamentalement #pragma once est une instance spécifique à la mise en oeuvre d'un #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 est donc parfois recommandé d'éviter les inclusions de gardes. .

32
Shoe