Vous pouvez utiliser #include
partout dans un fichier, et pas seulement à l'échelle globale - comme à l'intérieur d'une fonction (et plusieurs fois si nécessaire). Bien sûr, c'est laid et ce n'est pas un bon style, mais c'est possible et parfois raisonnable (selon le fichier que vous incluez). Si #include
n'était qu'une chose ponctuelle, alors ça ne marcherait pas. #include
ne fait qu'une simple substitution de texte (couper-coller) après tout, et tout ce que vous incluez ne doit pas nécessairement être un fichier d'en-tête. Vous pouvez, par exemple #include
un fichier contenant des données générées automatiquement et contenant les données brutes pour initialiser une std::vector
. Comme
std::vector<int> data = {
#include "my_generated_data.txt"
}
Et que "mes_données_générées.txt" soit quelque chose généré par le système de construction pendant la compilation.
Ou peut-être que je suis paresseux/stupide et que je mets cela dans un fichier ( muy exemple artificiel) :
const noexcept;
et ensuite je fais
class foo {
void f1()
#include "stupid.file"
int f2(int)
#include "stupid.file"
};
Un autre exemple, un peu moins artificiel, serait un fichier source où de nombreuses fonctions doivent utiliser un grand nombre de types dans un espace de noms, mais vous ne voulez pas simplement dire using namespace foo;
globalement, car cela polluerait l'espace de noms global avec un tas d'autres choses que vous ne voulez pas. Vous créez donc un fichier "foo" contenant
using std::vector;
using std::array;
using std::rotate;
... You get the idea ...
Et ensuite vous faites ceci dans votre fichier source
void f1() {
#include "foo" // needs "stuff"
}
void f2() {
// Doesn't need "stuff"
}
void f3() {
#include "foo" // also needs "stuff"
}
Note : Je ne préconise pas de faire des choses comme ça. Mais c'est possible et fait dans certaines bases de code et je ne vois pas pourquoi cela ne devrait pas être autorisé. Il hace a son utilité.
Il se peut également que le fichier que vous incluez se comporte différemment selon la valeur de certaines macros ( #define
s). Il se peut donc que vous souhaitiez inclure le fichier à plusieurs endroits, après avoir d'abord modifié une valeur, afin d'obtenir un comportement différent dans différentes parties de votre fichier source.
24 votes
Y a-t-il une raison d'inclure un seul fichier plusieurs fois ? \=> Cela pourrait être le cas. Un fichier peut avoir une compilation conditionnelle
#ifdefs
en elle. On peut donc dire#define MODE_ONE 1
et ensuite#include "has-modes.h"
et ensuite#undef MODE_ONE
con#define MODE_TWO 1
y#include "has-modes.h"
encore. Le préprocesseur est agnostique par rapport à ce genre de choses, et parfois elles peuvent avoir un sens.66 votes
Il serait logique qu'il s'agisse de la valeur par défaut. Mais pas celui qu'ils ont choisi lorsque les programmeurs C montaient encore à cheval, portaient des armes et avaient 16 Ko de mémoire.
1 votes
@FrançoisAndrieux mais le duplicata semble demander la même chose sur les gardes d'inclusion en général pas seulement #pragma une fois.
11 votes
Vous pouvez inclure
<assert.h>
plusieurs fois, avec des définitions différentes deNDEBUG
dans le même fichier source.1 votes
@FrançoisAndrieux Assez juste. Cela devrait être plus clair.
3 votes
Quant à
#pragma once
En soi, il existe des environnements matériels (généralement avec des lecteurs en réseau et la possibilité de plusieurs chemins vers le même en-tête) où cela ne fonctionnera pas correctement.0 votes
Il s'agirait d'un changement radical, et il faudrait trouver un nouveau moyen de le désactiver - deux bonnes raisons de ne pas le faire.
1 votes
Vous répondez tous dans les commentaires : la cible des dupes est toujours ouverte aux réponses...
0 votes
@BaummitAugen : Mais cette question ne porte pas sur
#pragma once
Ces réponses ne sont donc pas appropriées. La question porte sur les protections include.0 votes
Toutes les réponses dans ce fil de commentaires semblent s'appliquer exactement de la même manière aux gardes d'inclusion classiques qu'aux gardes d'inclusion.
#pragma once
afaict.0 votes
@BaummitAugen : Non pertinent. Le "duplicata" ne demande pas
#pramga once
donc une réponse expliquant uniquement comment#pragma once
ne fonctionne pas serait hors sujet. Remarquez comment la réponse à cette question ne parle pas des include-guards ou même des échecs de#pragma once
il parle plutôt des cas où les inclusions multiples sont utiles. Ce qui ne serait pas non plus une réponse appropriée à la "duplication".2 votes
@JohnnyCache dois-je interpréter votre dernier commentaire de manière à ce que vous ne soyez pas vraiment intéressé par une réponse, mais plutôt par un trolling et marquer votre question pour les modérateurs comme telle ?
0 votes
@SergeyA Je suis très intéressé par une réponse, mais le fait que les gens continuent de le marquer et de le démarquer comme duplicata est également curieux. En fait, c'est la raison pour laquelle j'ai commenté avec cette remarque, au lieu de l'éditer dans la question.
0 votes
Je me souviens de plusieurs inclusions des mêmes en-têtes utilisées dans
c
plus que nous ne l'utiliserions dansc++
. Un compilateur ne voudrait pas casser cette utilisation cependant.12 votes
Si vous avez
#pragma once
supposé, quel est le moyen de contrer ce défaut ?#pragma many
? Combien de compilateurs ont implémenté quelque chose comme ça ?1 votes
@JonathanLeffler Ce n'est cependant pas un véritable argument. Si le défaut
#pragma once
et une option de refus#pragma many
était implémentable et considéré comme une bonne idée au point que la norme le souhaite, les compilateurs l'implémenteraient. La question ici est essentiellement de savoir pourquoi cela ne se produit pas.1 votes
@MaxLanghof : Il s'agit principalement de souligner que le changement de la valeur par défaut nécessite un moyen de s'assurer que
<assert.h>
- pour citer (une fois de plus) l'exemple du C standard d'un en-tête qui doit pouvoir être inclus plusieurs fois dans une même UT avec (potentiellement) différents à chaque fois - continue de fonctionner correctement. Réalisation de#pragma once
le défaut ne se produira probablement pas parce qu'il perturberait le code de travail, et il y a déjà d'autres alternatives viables disponibles dans la norme. Un jour, peut-être, il pourrait y avoir#pragma STDC once
- ce qui serait nominalement la façon dont il serait normalisé.2 votes
TL;DR parce que le système de construction C++ est une vieille blague et que les programmeurs en sont venus à dépendre de ses bizarreries.
0 votes
Je ne veux pas savoir combien de combats de coulisses il y a eu sur la ré-utilisation
auto
.2 votes
Voir aussi #pragma once vs include guards ? et la partie #pragma once has unfixable bugs. Il ne devrait jamais être utilisé. D'après ce que j'ai compris, les en-têtes créés par des liens posent de nombreux problèmes.
1 votes
Duplicata possible de #pragma once vs include guards ?
2 votes
Hans Passant : Désolé, mais je monte toujours à cheval, et je suis connu pour porter une arme à feu lorsque je le fais, car il y a des ours et des pumas dans la nature.