436 votes

Le #pragma est-il une fois un garde d'inclusion sûr ?

J'ai lu qu'il y a une certaine optimisation du compilateur lors de l'utilisation de #pragma once ce qui peut permettre une compilation plus rapide. Je reconnais que ce n'est pas standard, et que cela pourrait donc poser un problème de compatibilité entre plates-formes.

Est-ce quelque chose qui est supporté par la plupart des compilateurs modernes sur les plateformes non-Windows (gcc) ?

Je veux éviter les problèmes de compilation des plates-formes, mais je veux aussi éviter le travail supplémentaire des gardes de repli :

#pragma once
#ifndef HEADER_H
#define HEADER_H

...

#endif // HEADER_H

Dois-je m'inquiéter ? Devrais-je dépenser davantage d'énergie mentale à ce sujet ?

3 votes

Après avoir demandé à un question similaire j'ai découvert que #pragma once semble éviter certains problèmes d'affichage des classes dans VS 2008. Je suis en train de me débarrasser des gardes d'inclusion et de les remplacer tous par des #pragma once pour cette raison.

397voto

Motti Points 32921

#pragma once a un inconvénient (autre que celui d'être non standard) et c'est que si vous avez le même fichier à différents endroits (nous avons cela parce que notre système de construction copie les fichiers autour) alors le compilateur pensera que ce sont des fichiers différents.

43 votes

Mais vous pouvez aussi avoir deux fichiers avec le même nom dans des endroits différents sans avoir à prendre la peine de créer des #define NAMES différents, ce qui est souvent sous la forme de HEADERFILENAME_H

83 votes

Vous pouvez également avoir deux fichiers ou plus avec le même #define WHATEVER, ce qui est très amusant, et c'est la raison pour laquelle je préfère utiliser pragma une fois.

157 votes

Pas convaincant... Changez le système de construction pour un système qui ne copie pas les fichiers mais utilise des liens symboliques à la place, ou incluez le même fichier à partir d'un seul emplacement dans chaque unité de traduction. On dirait plutôt que votre infrastructure est un fouillis qui doit être réorganisé.

269voto

Zifre Points 14109

Utilisation de #pragma once devrait fonctionner sur n'importe quel compilateur moderne, mais je ne vois pas pourquoi on ne pourrait pas utiliser une norme #ifndef inclure la garde. Cela fonctionne très bien. La seule réserve est que GCC n'a pas supporté #pragma once avant version 3.4 .

J'ai également constaté que, au moins sur GCC, il reconnaît la norme #ifndef inclure la garde et l'optimiser donc il ne devrait pas être beaucoup plus lent que #pragma once .

15 votes

Cela ne devrait pas être plus lent du tout (avec GCC de toute façon).

0 votes

Je n'ai pas fait de tests, donc je ne savais pas exactement quelle était la différence. Je suppose que #ifndef est probablement légèrement plus lent que #pragma once, car il doit aller jusqu'à la fin du fichier pour s'assurer qu'il y a un #endif.

64 votes

Ce n'est pas implémenté de cette façon. Au lieu de cela, si le fichier commence par un #ifndef la première fois et se termine par un #endif, gcc s'en souvient et saute toujours cette inclusion dans le futur sans même prendre la peine d'ouvrir le fichier.

79voto

Michael Burr Points 181287

Je souhaite #pragma once (ou quelque chose comme ça) avait été dans la norme. Les protections d'inclusion ne sont pas vraiment un gros problème (mais elles semblent être un peu difficiles à expliquer aux personnes qui apprennent le langage), mais cela semble être un inconvénient mineur qui aurait pu être évité.

En effet, puisque dans 99,98% des cas, le #pragma once est le comportement souhaité, il aurait été intéressant que la prévention de l'inclusion multiple d'un en-tête soit automatiquement gérée par le compilateur, avec une balise #pragma ou quelque chose pour permettre la double inclusion.

Mais nous avons ce que nous avons (sauf que vous pourriez ne pas avoir #pragma once ).

64 votes

Ce que je veux vraiment, c'est un standard #import directive.

13 votes

Une directive d'importation standard est à venir : isocpp.org/blog/2012/11/ Mais pas encore ici. Je suis tout à fait favorable à ce projet.

9 votes

@AHelps Vaporware. Cela fait presque cinq ans maintenant. Peut-être qu'en 2023 vous reviendrez sur ce commentaire et direz "je vous l'avais dit".

45voto

JaredPar Points 333733

Je ne sais pas s'il y a des avantages en termes de performance, mais cela fonctionne certainement. Je l'utilise dans tous mes projets C++ (bien que j'utilise le compilateur MS). Je trouve que c'est plus efficace que d'utiliser

#ifndef HEADERNAME_H
#define HEADERNAME_H
...
#endif

Il fait le même travail et ne remplit pas le préprocesseur avec des macros supplémentaires.

Le GCC prend en charge #pragma once officiellement à partir de la version 3.4 .

11voto

Jonathan Leffler Points 299946

Utilisation ' #pragma once peut ne pas avoir d'effet (il n'est pas supporté partout - bien qu'il soit de plus en plus largement supporté), et vous devez donc utiliser le code de compilation conditionnelle de toute façon, auquel cas, pourquoi s'embêter avec ' #pragma once ' ? Le compilateur l'optimise probablement de toute façon. Cela dépend cependant de vos plateformes cibles. Si toutes vos cibles le supportent, alors allez-y et utilisez-le - mais cela doit être une décision consciente parce que l'enfer se déchaînera si vous n'utilisez que le pragma et que vous le portez sur un compilateur qui ne le supporte pas.

1 votes

Je ne suis pas d'accord pour dire que vous devez soutenir les gardes de toute façon. Si vous utilisez #pragma une fois (ou des gardes) c'est parce qu'il soulève certains conflits sans eux. Donc, si votre outil de chaîne ne le supporte pas, le projet ne compilera pas et vous vous retrouverez exactement dans le même genre de situation que lorsque vous voulez compiler du C ansi sur un vieux compilateur K&R. Vous devez simplement vous procurer un outil de chaîne plus récent. Il vous suffit de vous procurer un outil de chaîne plus récent ou de modifier le code pour ajouter des protections. L'enfer se produirait si le programme compilait mais ne fonctionnait pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X