Question

J'ai toujours utilisé un fichier *.h pour mes définitions de classe, mais après avoir lu du code de bibliothèque boost, j'ai compris qu'ils utilisaient tous *.hpp. J'ai toujours eu une aversion pour cette extension de fichier, principalement parce que je n'y suis pas habitué.

Quels sont les avantages et les inconvénients d’utiliser <=> par rapport à <=>?

Était-ce utile?

La solution

Voici quelques raisons pour lesquelles le nommage des en-têtes C vs C ++ est différent:

  • Le formatage automatique du code peut avoir différentes consignes pour formater le code C et C ++. Si les en-têtes sont séparés par extension, vous pouvez configurer votre éditeur pour appliquer automatiquement le formatage approprié
  • En ce qui concerne les noms, j'ai participé à des projets comportant des bibliothèques écrites en C, puis des wrappers en C ++. Étant donné que les en-têtes avaient généralement des noms similaires, c'est-à-dire Feature.h vs Feature.hpp, ils étaient faciles à distinguer.
  • Inclusion, votre projet dispose peut-être de versions plus appropriées écrites en C ++, mais vous utilisez la version C (voir le point ci-dessus). Si les en-têtes portent le nom du langage dans lequel ils sont implémentés, vous pouvez facilement repérer tous les en-têtes C et rechercher les versions C ++.

N'oubliez pas que C n'est pas C ++ et qu'il peut être très dangereux de mélanger et assortir à moins de savoir ce que vous faites. Nommer vos sources de manière appropriée vous aide à distinguer les langues.

Autres conseils

J'utilise .hpp parce que je veux que l'utilisateur différencie les en-têtes C ++ et les en-têtes C.

Cela peut être important lorsque votre projet utilise à la fois les modules C et C ++. vous proposez via l'extension

.hpp: en-têtes C ++

(ou .hxx, ou .hh, ou autre chose)

Cet en-tête concerne uniquement C ++.

Si vous êtes dans un module C, n'essayez même pas de l'inclure. Vous n’aimerez pas cela, car aucun effort n’est fait pour le rendre convivial (trop de pertes en seraient perdues, telles que la surcharge de fonctions, les espaces de noms, etc.).

.h: en-têtes C purs ou compatibles avec C / C ++

Cet en-tête peut être inclus directement ou indirectement par une source C et une source C ++.

Il peut inclure directement, en étant protégé par la __cplusplus macro:

  • Ce qui signifie que, d'un point de vue C ++, le code compatible avec C sera défini comme extern "C".
  • D'un point de vue C, tout le code C sera clairement visible, mais le code C ++ sera masqué (car il ne compilera pas dans un compilateur C).

Par exemple:

#ifndef MY_HEADER_H
#define MY_HEADER_H

   #ifdef __cplusplus
      extern "C"
      {
   #endif

   void myCFunction() ;

   #ifdef __cplusplus
      } // extern "C"
   #endif

#endif // MY_HEADER_H

Ou il pourrait être inclus indirectement par l'en-tête .hpp correspondant le renfermant avec la <=> déclaration.

Par exemple:

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP

extern "C"
{
#include "my_header.h"
}

#endif // MY_HEADER_HPP

et:

#ifndef MY_HEADER_H
#define MY_HEADER_H

void myCFunction() ;

#endif // MY_HEADER_H

J'ai toujours considéré que l'en-tête .hpp était une sorte de portemanteau de fichiers .h et .cpp ... un en-tête contenant également les détails de la mise en oeuvre.

Généralement, lorsque j'ai vu (et utilisé) <=> comme extension, il n'y a pas de fichier <=> correspondant. Comme d’autres l’ont dit, ce n’est pas une règle absolue, mais j’ai tendance à utiliser <=> des fichiers.

Peu importe quelle extension vous utilisez. L'un ou l'autre est OK.

J'utilise *.h pour C et *.hpp pour C ++.

MODIFIER [Ajout d'une suggestion de Dan Nissenbaum]:

Selon une convention, les fichiers .hpp sont utilisés lorsque les prototypes sont définis dans l’en-tête même. De telles définitions dans les en-têtes sont utiles dans le cas de modèles, car le compilateur génère le code pour chaque type uniquement lors de l'instanciation du modèle. Par conséquent, s'ils ne sont pas définis dans les fichiers d'en-tête, leurs définitions ne seront pas résolues au moment de la liaison à partir d'autres unités de compilation. Si votre projet est un projet uniquement C ++ qui utilise beaucoup de modèles, cette convention peut être utile.

Certaines bibliothèques de modèles qui adhèrent à cette convention fournissent des en-têtes avec des extensions .hpp pour indiquer qu'elles ne possèdent pas les fichiers .cpp correspondants.

Certaines autres bibliothèques de modèles utilisent une autre convention, comme l'utilisation de .h pour les en-têtes C et de .hpp pour C ++; un bon exemple serait la bibliothèque boost.

  

Citation de la FAQ Boost,

     

Les extensions de fichier communiquent le " type " du fichier, à l'homme   et aux programmes informatiques. L'extension '.h' est utilisée pour l'en-tête C   fichiers, et communique donc la mauvaise chose à propos de l'en-tête C ++   des dossiers. Ne pas utiliser d'extension ne communique rien et force l'inspection   du contenu du fichier pour déterminer le type. Utiliser '.hpp' sans ambiguïté   l'identifie comme fichier d'en-tête C ++ et fonctionne bien dans la pratique.   (Rainer Deyke)

J'ai récemment commencé à utiliser *.hpp pour les en-têtes c ++.

La raison en est que j’utilise emacs comme éditeur principal. Il entre automatiquement en mode c lorsque vous chargez un fichier *.h et en mode c ++ lorsque vous chargez un fichier <=>.

Hormis ce fait, je ne vois aucune bonne raison de choisir <=> plutôt que <=> ou inversement.

Je réponds à cela en guise de rappel, pour indiquer mes commentaires sur & "user1949346 &"; répondre à ce même OP.

Donc, autant de personnes ont déjà répondu: l'une ou l'autre solution convient. Suivie par souligne de leurs propres impressions.

Introduction, comme indiqué également dans les commentaires nommés précédents, j’estime que C++ les extensions d’en-tête proposées sont .h s’il n’ya aucune raison de s’y opposer.

Étant donné que les documents ISO / CEI utilisent cette notation de fichiers d'en-tête, aucune chaîne correspondant à .hpp ne figure même dans leurs documentations linguistiques concernant '\n'.

Mais je vise maintenant une raison valable pour laquelle l'une ou l'autre solution est acceptable, et surtout pourquoi elle n'est pas soumise à la langue elle-même.

Alors on y va.

La <> documentation (je prends en référence la version N3690) définit qu'un en-tête doit être conforme à la syntaxe suivante:

  

2.9 Noms d'en-tête

header-name:
    < h-char-sequence >
    " q-char-sequence "
h-char-sequence:
    h-char
    h-char-sequence h-char
h-char:
    any member of the source character set except new-line and >
q-char-sequence:
    q-char
    q-char-sequence q-char
q-char:
    any member of the source character set except new-line and "

Comme nous pouvons en extraire cette partie, le nom du fichier d’en-tête peut également contenir tout ce qui est valide dans le code source. Sauf si elle contient > caractères et selon qu’elle doit être incluse avant "", il n’est pas autorisé à contenir un ". Ou l'inverse s'il est inclus par prettyStupidIdea.> - include, il n'est pas autorisé à contenir un .cc.

En d'autres termes: si vous aviez un environnement prenant en charge les noms de fichiers tels que .mm, une inclusion telle que:

#include "prettyStupidIdea.>"

serait valide, mais:

#include <prettyStupidIdea.>>

serait invalide. L’inverse est identique.

Et même

#include <<.<>

serait un nom de fichier d'en-tête d'inclusion valide.

Même si cela serait conforme à <=>, ce serait une idée assez stupide, quoique.

Et c'est pourquoi <=> est également valide.

Mais ce n'est pas le résultat des comités qui élaborent les décisions concernant la langue!

Discuter de l'utilisation de <=> revient donc à le faire à propos de <=>, <=> ou de tout ce que j'ai lu dans d'autres articles de ce sujet.

Je dois admettre que je ne sais pas d'où <=> vient < 1 , mais je parierais que l'inventeur d'un outil d'analyse syntaxique, de l'EDI ou de quelque chose d'autre lié à <=> est venu à cette idée d'optimiser certains processus internes ou simplement d'inventer (probablement même pour eux nécessairement) de nouvelles conventions de nommage.

Mais cela ne fait pas partie de la langue.

Et chaque fois que l’on décide de l’utiliser de cette façon. Que ce soit parce qu’il aime le plus ou que certaines applications du flux de travail le requièrent, jamais 2 n’est une exigence du langage. Ainsi, quiconque dit & "; Le pp est parce qu’il est utilisé avec C ++ &" ;, est tout simplement faux en ce qui concerne la définition des langages.

C ++ autorise tout ce qui concerne le paragraphe précédent. Et s’il existe quelque chose que le comité a proposé d’utiliser, il utilise <=> car il s’agit de l’extension visée dans tous les exemples du document ISO.

Conclusion:

Tant que vous ne ressentez pas le besoin d'utiliser <=> sur <=> ou inversement, vous ne devriez pas vous déranger. Parce que les deux seraient former un nom d'en-tête valide de même qualité en ce qui concerne la norme. Et par conséquent, tout ce que VOUS EXIGE d'utiliser <=> ou <=> constitue une restriction supplémentaire de la norme qui pourrait même être en contradiction avec d'autres restrictions supplémentaires non conformes les unes aux autres. Mais comme OP ne mentionne aucune restriction linguistique supplémentaire, il s’agit de la seule réponse correcte et susceptible d’être approuvée

" *. h ou * .hpp pour vos définitions de classe " est:

Les deux sont également corrects et applicables tant qu'aucune restriction externe n'est présente.

1 De ce que je sais, il semble que ce soit le framework de boost qui a créé cette <=> extension.

2 Bien sûr, je ne peux pas dire ce que certaines versions futures apporteront!

Je préfère .hpp pour C ++ pour indiquer clairement aux éditeurs et aux autres programmeurs qu'il s'agit d'un en-tête C ++ plutôt que d'un fichier d'en-tête C.

C ++ (& "; C Plus Plus &";) est logique en tant que .cpp

Les fichiers d'en-tête avec une extension .hpp n'ont pas le même flux logique.

Vous pouvez appeler votre inclus comme vous le souhaitez.

Il suffit de spécifier ce nom complet dans le #include.

Je suggère que, si vous travaillez avec C, utilisez .h et lorsque C ++, utilisez .hpp.

C’est finalement juste une convention.

Codegear C ++ Builder utilise .hpp pour les fichiers d’en-tête générés automatiquement à partir de fichiers sources Delphi et les fichiers .h pour votre " propre " fichiers d'en-tête.

Ainsi, lorsque j'écris un fichier d'en-tête C ++, j'utilise toujours .h.

Dans l'une de mes tâches au début des années 90, nous utilisions respectivement les fichiers .cc et .hh pour les fichiers source et les fichiers d'en-tête. Je le préfère toujours à toutes les alternatives, probablement parce que c'est plus facile à taper.

Bjarne Stroustrup et Herb Sutter ont répondu à cette question dans leurs consignes de base pour le langage C ++: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-source , qui fait également référence aux dernières modifications apportées à l'extension standard (C + +11, C ++ 14, etc.)

  

SF.1: utilisez un suffixe .cpp pour les fichiers de code et .h pour les fichiers d'interface si votre   Le projet Y ne suit pas déjà une autre convention   Raison

     

C'est un congrès de longue date. Mais la cohérence est plus importante, donc si   votre projet utilise autre chose, suivez-le.   Note

     

Cette convention reflète un schéma d'utilisation commun: les en-têtes sont plus souvent partagés.   avec C pour compiler à la fois C ++ et C, qui utilise généralement .h, et il est   plus facile de nommer tous les en-têtes .h au lieu d’avoir des extensions différentes pour   juste les en-têtes qui sont destinés à être partagés avec C. D'autre part,   les fichiers de mise en œuvre sont rarement partagés avec C et devraient donc être généralement   distinguer des fichiers .c, il est donc préférable de nommer tous les C ++   fichiers d’implémentation autre chose (comme .cpp).

     

Les noms spécifiques .h et .cpp ne sont pas obligatoires (simplement recommandés en tant que   par défaut) et d’autres noms sont très répandus. Les exemples sont .hh, .C et   .cxx. Utilisez ces noms de manière équivalente. Dans ce document, nous faisons référence à .h et .cpp & Gt; en abrégé pour les fichiers d’en-tête et d’implémentation, même si la   l'extension peut être différente.

     

Votre IDE (si vous en utilisez un) peut avoir des opinions bien arrêtées sur les suffrages.

Je ne suis pas un grand fan de cette convention car si vous utilisez une bibliothèque populaire telle que boost, votre cohérence est déjà dépassée et vous devriez mieux utiliser .hpp.

Comme beaucoup d’entre eux l’ont déjà mentionné, je préfère également utiliser .hpp pour les bibliothèques d’en-tête uniquement qui utilisent des classes / fonctions de modèle. Je préfère utiliser .h pour les fichiers d'en-tête accompagnés de fichiers sources .cpp ou de bibliothèques partagées ou statiques.

La plupart des bibliothèques que je développe sont basées sur des modèles et ne doivent donc contenir que des en-têtes. Toutefois, lors de l'écriture d'applications, j'ai tendance à séparer la déclaration de la mise en oeuvre et à me retrouver avec les fichiers .h et .cpp

Heureusement, c'est simple.

Vous devez utiliser l'extension .hpp si vous travaillez avec C ++ et vous devez utiliser .h pour C ou mélanger C et C ++.

J'utilise .h parce que c'est ce que Microsoft utilise et ce que son générateur de code crée. Pas besoin d'aller à contre-courant.

Dans & "Le langage de programmation C ++, troisième édition de Bjarne Stroustrup &", le n & # 186; 1 livre C ++ à lire absolument, il utilise * .h. Je suppose donc que la meilleure pratique consiste à utiliser * .h.

Cependant, * .hpp convient également!

Il est facile pour les outils et les utilisateurs de différencier quelque chose . C'est ça.

En utilisation conventionnelle (par boost, etc.), .hpp correspond spécifiquement aux en-têtes C ++. D’autre part, .h concerne les en-têtes non C ++ (principalement C). Détecter avec précision la langue du contenu est généralement difficile, car il existe de nombreux cas non triviaux. Cette différence rend donc souvent un outil prêt à l'emploi facile à écrire. Pour les humains, une fois la convention acquise, il est également facile à retenir et facile à utiliser.

Toutefois, je tiens à souligner que la convention elle-même ne fonctionne pas toujours comme prévu.

  • Il n'est pas forcé par la spécification de langages , ni C ni C ++. Il existe de nombreux projets qui ne suivent pas la convention. Une fois que vous avez besoin de les fusionner, cela peut être gênant.
  • .hh lui-même n'est pas le seul choix. Pourquoi pas .hxx ou .cpp? (Quoi qu'il en soit, vous avez généralement besoin d'au moins une règle conventionnelle sur les noms de fichiers et les chemins.)

J'utilise personnellement <=> et <=> dans mes projets C ++. Je ne suis pas la convention ci-dessus parce que:

J'utilise habituellement <=> sur les en-têtes C ++ et les en-têtes doivent être utilisés (maintenus) d'une manière en-tête uniquement , par exemple. comme bibliothèques de modèles. Pour les autres en-têtes de <=>, il existe un fichier <=> correspondant en tant qu'implémentation ou il s'agit d'un en-tête non C ++. Ce dernier est facile à différencier par le contenu de l’en-tête par des humains (ou par des outils avec métadonnées incorporées explicites, si nécessaire).

L'extension du fichier source peut avoir une signification pour votre système de construction. Par exemple, vous pouvez avoir une règle dans votre fichier makefile pour les fichiers .cpp ou .c, ou votre compilateur (par exemple Microsoft cl.exe) peut compiler le fichier en tant que C ou C ++ en fonction de l'extension.

Etant donné que vous devez fournir l'intégralité du nom de fichier à la directive #include, l'extension du fichier d'en-tête n'est pas pertinente. Vous pouvez inclure un fichier /P dans un autre fichier source si vous le souhaitez, car il ne s'agit que d'une inclusion textuelle. Votre compilateur aura peut-être une option permettant de vider la sortie prétraitée, ce qui sera clair (Microsoft: /E prétraiter le fichier, stdout prétraiter /EP, #line omettre les /C directives, .hpp conserver les commentaires)

Vous pouvez choisir d’utiliser <=> des fichiers qui ne concernent que l’environnement C ++, c’est-à-dire qu’ils utilisent des fonctionnalités qui ne seront pas compilées en C.

Il n’ya aucun avantage à une extension particulière, si ce n’est que celle-ci peut avoir une signification différente pour vous, le compilateur et / ou vos outils. header.h est un en-tête valide. header.hpp est un en-tête valide. header.hh est un en-tête valide. header.hx est un en-tête valide. h.header est un en-tête valide. this.is.not.a.valid.header est un en-tête valide dans le déni. ihjkflajfajfklaf est un en-tête valide. Tant que le nom peut être analysé correctement par le compilateur et que le système de fichiers le prend en charge, il s'agit d'un en-tête valide et le seul avantage de son extension est ce que l'on y lit.

Cela étant dit, être capable de formuler des hypothèses avec précision sur l'extension est très utile, il serait donc sage d'utiliser un ensemble de règles facilement compréhensible pour vos fichiers d'en-tête. Personnellement, je préfère faire quelque chose comme ça:

  1. S'il existe déjà des directives établies, suivez-les pour éviter toute confusion.
  2. Si tous les fichiers source du projet utilisent la même langue, utilisez .h. Il n'y a pas d'ambiguïté.
  3. Si certains en-têtes sont compatibles avec plusieurs langues, alors que d'autres ne le sont que dans une seule langue, les extensions sont basées sur la langue la plus restrictive avec laquelle un en-tête est compatible. Un en-tête compatible avec C ou avec les deux C & Amp; C ++, obtient .hpp, alors qu'un en-tête compatible avec C ++ mais pas C obtient .hh ou .tpp ou quelque chose du genre.

Ceci, bien sûr, n’est qu’un des nombreux moyens de gérer les extensions, et vous ne pouvez pas nécessairement faire confiance à votre première impression même si les choses semblent simples. Par exemple, on a mentionné l’utilisation de .hxx pour les en-têtes normaux et de <=> pour les en-têtes ne contenant que les définitions des fonctions de membre de classe basées sur un modèle, avec <=> des fichiers définissant des classes basées sur un modèle, y compris les <=> fichiers définissant leurs fonctions membres (au lieu de l'en-tête <=> contenant directement à la fois la déclaration de fonction et la définition). Autre exemple, bon nombre de personnes reflètent toujours le libellé de l'en-tête dans son extension, même lorsqu'il n'y a aucune chance d'ambiguïté; pour eux, <=> est toujours un en-tête C et <=> (ou <=>, ou <=>, etc.) est toujours un en-tête C ++. Et encore une fois, certaines personnes utilisent <=> pour & Quot; en-tête associé à un fichier source & Quot; et <=> pour " en-tête avec toutes les fonctions définies en ligne ".

.

Compte tenu de cela, le principal avantage serait de toujours nommer vos en-têtes dans le même style et de rendre ce style facilement visible pour quiconque examinera votre code. De cette façon, toute personne familiarisée avec votre style de codage habituel sera en mesure de déterminer ce que vous voulez dire avec une extension donnée en un simple coup d'œil.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top