51 votes

Quand peut-on omettre l'extension de fichier dans une directive #include ?

Je joue avec gmock et j'ai remarqué qu'il contient cette ligne :

#include <tuple>

Je m'attendais à ce que tuple.h .

Quand peut-on exclure l'extension et cela donne-t-il un sens différent à la directive ?

73voto

Michael Burr Points 181287

La norme C++ en-têtes de ne pas avoir un ".h" suffixe. Je crois que la raison est qu'il y en avait beaucoup, pré-mise en œuvre standard que la norme serait de pause. Donc, au lieu d'exiger que les vendeurs changer leur sortie de "iostream.h" (par exemple) de la tête pour être conformes aux normes (qui briserait leur code d'utilisateur), le comité de normalisation a décidé qu'ils allaient déposer le suffixe (ce qui, je crois pas en vigueur, la mise en œuvre avait déjà fait).

De cette façon, non-standard des programmes continuera à travailler en utilisant le fournisseur de la non-standard des bibliothèques. Lorsque l'utilisateur a voulu rendre leurs programmes conformes aux normes, l'une des mesures qu'ils prendraient est de changer le "#include" directive pour la chute de l' ".h" suffixe.

Donc

#include <iostream>     // include the standard library version
#include <iostream.h>   // include a vendor specific version (which by 
                        //      now might well be the same)

Comme d'autres réponses ont mentionné, les écrivains de la non-standard des bibliothèques peut choisir convention d'affectation de noms, mais je pense qu'ils veulent continuer à utiliser ".h" ou ".hpp" (que Stimuler l'a fait) pour plusieurs raisons:

  1. si et quand la bibliothèque est standardisé, la version standard ne sont pas automatiquement remplacer la précédente, non-standard (provoquant des fractures de code d'utilisateur dans tous les probabilité)
  2. il semble être une convention (plus ou moins) que les en-têtes sans suffixe sont des bibliothèques standard, et ceux avec un suffixe (autre que l'ancien C-têtes) sont non-standard.

Notez qu'un problème similaire s'est produit lorsque le comité est allé à ajouter de hachage cartes à la STL, ils ont trouvé qu'il y a déjà beaucoup (différents) hash_map des implémentations existent, donc au lieu de venir avec un standard qui casse beaucoup de choses là-bas aujourd'hui, ils sont en appelant le standard de mise en œuvre "unordered_map". Les espaces de noms étaient censés aider à prévenir ce type de sauter à travers des cerceaux, mais il n'a pas l'air de fonctionner assez bien (ou être utilisé assez bien) pour leur permettre d'utiliser le plus naturel nom sans casser beaucoup de code.

À noter que pour les " C " en-têtes, C++ permet d'inclure soit une <cxxxxxx> ou <xxxxxx.h> variante. Celle qui commence par " c " et n'a pas ".h" suffixe de mettre leurs déclarations dans l' std d'espace de noms (et éventuellement de l'espace de noms global), ceux avec les ".h" suffixe met le nom de l'espace de noms global (certains compilateurs aussi mettre les noms dans l' std de l'espace de noms c'est pas clair pour moi si c'est conforme aux normes, mais je ne vois pas le mal).

9 votes

Une autre raison (mais probablement pas la principale :)) pourrait être de souligner le fait que les en-têtes standards ne sont pas tenus d'être des fichiers. ils pourraient donc avoir décidé de supprimer le ".h", parce qu'il suggère une extension de fichier.

5 votes

Cela est vrai depuis l'ANSI C 1989, dont la note de bas de page indique : "Un en-tête n'est pas nécessairement un fichier source..." Au fait, quelqu'un connaît-il un compilateur qui fait autre chose que des fichiers source normaux pour les en-têtes standard ?

3 votes

@MichaelBurr Les en-têtes précompilés ne pourraient-ils pas faire l'affaire ?

21voto

Ferruccio Points 51508

Si le fichier est nommé tuple vous devez alors #include <tuple> s'il est nommé tuple.h vous devez alors #include <tuple.h>

C'est aussi simple que cela. Vous n'omettez aucune extension.

15voto

Crashworks Points 22920

Il inclut un fichier qui s'appelle simplement "tuple" -- le fichier lui-même n'a pas d'extension.

La norme supposée pour les fichiers d'inclusion C++ est de les nommer sans l'extension .h ; de nombreux auteurs de bibliothèques suivent cette norme (STL, etc.), mais certains ne le font pas.

1 votes

Pour autant que je sache, les fichiers Boost portent l'extension .hpp.

9voto

Drew Dormann Points 25025

Il n'y a rien de spécial. Le fichier s'appelle simplement tuple .

La raison pour laquelle les en-têtes de la bibliothèque standard n'ont pas d'extension de fichier est la suivante namespace s.

Les espaces de noms ont été ajoutés à la norme C++ tardivement, avec la norme C++98, y compris l'espace de nommage (Namespaces). std dans lequel résident toutes les entités de la bibliothèque standard.

Lorsque la bibliothèque standard a été déplacée dans le répertoire std cela signifie que tout le code C++ existant ne fonctionnerait pas puisqu'il s'attendait à ce que la bibliothèque soit dans l'espace de noms global. La solution a consisté à ne pas toucher aux anciens fichiers d'en-tête "dot-h" et à fournir la bibliothèque de l'espace de noms dans des fichiers sans extension.

De cette façon, l'ancien code qui #include<iosteam.h> pourrait s'attendre à ce que l'on assiste à une cout tandis que le nouveau code pourrait #include<iostream> et s'attendre à une std::cout .

0 votes

Je viens de trouver une déclaration contraire et je voulais la signaler. Peter Becker affirme que "Les espaces de nommage n'ont rien à voir avec les noms d'en-tête.

0 votes

@DanielK. Je pense que cette déclaration est sortie de son contexte. Avez-vous lu le commentaire suivant de Peter Becker ? Il semble reprendre l'explication de cette réponse.

1 votes

Je pense que vous avez raison. Commentaire suivant de Peter Becker déclare "Lorsque la bibliothèque standard a été intégrée à std, la question de la compatibilité ascendante s'est posée, et l'approche évidente était de passer de iostream.h à quelque chose d'autre, et nous avons décidé, de manière assez arbitraire, d'utiliser des noms sans extensions."

4voto

nmiller Points 148

J'avais cru comprendre que #include tuple "pointerait" vers tuple.h.

A vérifier : iostream vs iostream.h

2 votes

Le compilateur peut décider que c'est le cas. La conversion de la chaîne de caractères du code source en chemin de fichier complet pour le système d'exploitation est du ressort du compilateur. Le préfixage des répertoires est assez courant, mais le suffixage des extensions ne l'est pas.

0 votes

Le lien est cassé

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