Pourquoi ne devrais-je pas #inclure <bits / stdc ++. H>?

267

J'ai posté une question avec mon code dont la seule #includedirective était la suivante:

#include <bits/stdc++.h>

Mon professeur m'a dit de le faire, mais dans la section des commentaires, j'ai été informé que je ne devrais pas.

Pourquoi?

Courses de légèreté en orbite
la source
72
Huh. J'aurais dû savoir qu'il y aurait une version using namespace std;incluse de quelque part.
user4581301
1
pourquoi cet en-tête existe-t-il même? sûrement aucun des standards inclus ne comprend vraiment cela, car cela apporterait beaucoup de déchets? et si ce n'est pas inclus par l'un des publics comprend ... alors pourquoi est-il expédié dans la distribution?
Chris Beck
10
@ChrisBeck: C'est un détail d'implémentation. Il ne fait pas partie de l '"API publique" ni n'est destiné à être utilisé. Mais il doit encore être expédié, sinon rien ne fonctionnerait. La norme comprend peut ne pas l'utiliser individuellement mais elle est là pour une utilisation dans les en-têtes précompilés. Voir le commentaire en haut, qui dit: "Il s'agit d'un fichier d'implémentation pour un en-tête précompilé." .
Courses de légèreté en orbite le
1
@LightnessRacesinOrbit Si vous n'êtes pas censé l'utiliser vous-même, comment son existence aide-t-elle avec PCH? Ou est-ce que gcc est assez intelligent pour passer automatiquement à celui-ci à des fins PCH dans certaines circonstances?
Daniel H
2
@LightnessRacesinOrbit "Il ne fait pas partie de l '" API publique "ou n'est pas destiné à être utilisé." Entièrement faux, il est destiné à un usage public, en tant qu'en-tête précompilé. Libstdc ++ (pre) compile et installe une version précompilée de cet en-tête, donc si vous l'incluez, G ++ inclura en fait à la bits/stdc++.h.gchplace la version précompilée. Il existe car il doit exister pour que sa version précompilée puisse être générée.
Jonathan Wakely du

Réponses:

311

L'inclusion <bits/stdc++.h>semble être une chose de plus en plus courante à voir sur Stack Overflow, peut-être quelque chose de nouveau ajouté à un programme national au cours de l'année universitaire en cours.

J'imagine que les avantages sont vaguement donnés ainsi:

  • Vous n'avez besoin que d'écrire une #includeligne
  • Vous n'avez pas besoin de rechercher dans quel en-tête standard tout est

Malheureusement, c'est un hack paresseux, nommant un en-tête interne GCC directement au lieu d'en-têtes standard individuels comme <string>, <iostream>et <vector>. Il ruine la portabilité et favorise de terribles habitudes.

Les inconvénients comprennent:

  • Cela ne fonctionnera probablement que sur ce compilateur
  • Vous n'avez aucune idée de ce qu'il fera lorsque vous l'utiliserez, car son contenu n'est pas défini par une norme
  • Même la simple mise à niveau de votre compilateur vers sa propre prochaine version peut interrompre votre programme
  • Chaque en-tête standard unique doit être analysé et compilé avec votre code source, ce qui est lent et se traduit par un exécutable volumineux sous certains paramètres de compilation

Ne fais pas ça!


Plus d'information:

Exemple de pourquoi Quora est mauvais:

Courses de légèreté en orbite
la source
78
"peut-être quelque chose nouvellement ajouté à un programme d'études national dans l'année académique en cours" Blind mène les aveugles :(
Réintègre Monica le
14
@KubaOber: Exactement.
Courses de légèreté en orbite le
33
Je viens juste d'arriver par un trou de ver dans une autre question, très bien. Ce qui aggrave cette habitude d'enseignement, c'est qu'elle est généralement suivie d'un direct using namesapce std;. Seulement deux lignes et pratiquement tous les identifiants agréables sont utilisés. Incroyablement frustrant de le voir enseigné.
StoryTeller - Unslander Monica
6
À propos de l'exemple quora, il pourrait avoir changé avec le temps. J'ai visité la page aujourd'hui et les avantages et les inconvénients de <bits / stdc ++. H> sont répertoriés dans le contexte spécifique des concours de programmation en ligne. Je trouve leur conclusion ok-ish.
YSC
4
@EvgeniSergeev: 2 Ko représentent beaucoup de code, de données, d'informations sur les symboles, etc., lorsque vous essayez de déterminer son effet. Comprenez-vous tout ce qui est ajouté? Pour votre compilateur? La version actuelle? Toutes les versions entre les deux? Toutes les futures versions? Si vous devez décider entre la commodité et l'exactitude, il n'y a qu'une seule option valide.
IInspectable
48

Pourquoi? Parce qu'il est utilisé comme s'il était censé être un en-tête standard C ++, mais aucun standard ne le mentionne. Par conséquent, votre code n'est pas portable par construction. Vous ne trouverez aucune documentation à ce sujet sur cppreference . Il pourrait donc aussi bien ne pas exister. C'est le fruit de l'imagination de quelqu'un :)

J'ai découvert - à mon horreur et mon incrédulité - qu'il existe un site de tutoriel bien connu où chaque exemple C ++ semble inclure cet en-tête . Le monde est fou. Voilà la preuve.


A tous ceux qui écrivent de tels "tutoriels"

Veuillez cesser d'utiliser cet en-tête. Oublie ça. Ne propagez pas cette folie. Si vous n'êtes pas disposé à comprendre pourquoi cela est mal , croyez-moi. Je ne suis pas d'accord d'être traité comme une figure d'autorité sur quoi que ce soit, et j'en suis probablement plein la moitié du temps, mais je ne ferai une exception que dans ce cas. Je prétends savoir de quoi je parle ici. Prends-moi sur parole. Je vous en supplie.

PS Je peux très bien imaginer l'abominable «norme d'enseignement» où cette mauvaise idée aurait pu se produire, et les circonstances qui y ont conduit. Ce n'est pas parce qu'il semble qu'il y ait un besoin pratique qu'il soit acceptable - même pas rétrospectivement.

PPS Non, il n'y en avait aucun besoin pratique. Il n'y a pas beaucoup d'en-têtes standard C ++ et ils sont bien documentés. Si vous enseignez, vous ne rendez pas service à vos élèves en ajoutant une telle «magie». Produire des programmeurs avec un état d'esprit magique est la dernière chose que nous voulons. Si vous devez offrir aux étudiants un sous-ensemble de C ++ pour leur faciliter la vie, il vous suffit de produire un document avec la courte liste des en-têtes applicables au cours que vous enseignez et avec une documentation concise pour les constructions de bibliothèque que vous attendez des étudiants.

Réintégrer Monica
la source
35

Il existe un site Stack Exchange appelé Programming Puzzles & Code Golf . Les puzzles de programmation sur ce site correspondent à cette définition du puzzle :

un jouet, un problème ou un autre dispositif conçu pour amuser en présentant des difficultés à résoudre par l'ingéniosité ou l'effort du patient.

Ils sont conçus pour amuser, et non de la manière dont un programmeur qui travaille pourrait être amusé par un problème du monde réel rencontré dans son travail quotidien.

Code Golf est "un type de compétition de programmation informatique récréative dans laquelle les participants s'efforcent d'obtenir le code source le plus court possible qui implémente un certain algorithme." Dans les réponses sur le site PP&CG, vous verrez des personnes spécifier le nombre d'octets dans leurs réponses. Quand ils trouveront un moyen de raser quelques octets, ils supprimeront le numéro d'origine et enregistreront le nouveau.

Comme vous pouvez vous y attendre, le golf de code récompense les abus extrêmes du langage de programmation. Noms de variables à une lettre. Pas d'espace. Utilisation créative des fonctions de bibliothèque. Fonctionnalités non documentées. Pratiques de programmation non standard. Des hacks épouvantables.

Si un programmeur soumettait une demande de tirage au travail contenant un code de style golf, elle serait rejetée. Leurs collègues se moquaient d'eux. Leur manager passait devant leur bureau pour discuter. Même ainsi, les programmeurs s'amusent en soumettant des réponses à PP&CG.

Qu'est-ce que cela a à voir stdc++.h? Comme d'autres l'ont souligné, son utilisation est paresseuse. Ce n'est pas portable, donc vous ne savez pas si cela fonctionnera sur votre compilateur ou la prochaine version de votre compilateur. Cela favorise les mauvaises habitudes. Ce n'est pas standard, donc le comportement de votre programme peut différer de ce que vous attendez. Cela peut augmenter le temps de compilation et la taille de l'exécutable.

Ce sont toutes des objections valides et correctes. Alors pourquoi quelqu'un utiliserait-il cette monstruosité?

Il s'avère que certaines personnes aiment programmer des puzzles sans le code golf . Ils se réunissent et participent à des événements comme ACM-ICPC, Google Code Jam et Facebook Hacker Cup, ou sur des sites comme Topcoder et Codeforces. Leur classement est basé sur l'exactitude du programme, la vitesse d'exécution et la vitesse à laquelle ils soumettent une solution. Pour maximiser la vitesse d'exécution, de nombreux participants utilisent C ++. Pour maximiser la vitesse de codage, certains d'entre eux utilisent stdc++.h.

Est-ce une bonne idée? Vérifions la liste des inconvénients. Portabilité? Cela n'a pas d'importance car ces événements de codage utilisent une version de compilateur spécifique que les candidats connaissent à l'avance. Conformité aux normes? Sans objet pour un bloc de code dont la durée de vie est inférieure à une heure. Temps de compilation et taille exécutable? Ceux-ci ne font pas partie de la rubrique de notation du concours.

Nous nous retrouvons donc avec de mauvaises habitudes. Ceci est une objection valable. En utilisant ce fichier d'en-tête, les candidats évitent de savoir quel fichier d'en-tête standard définit les fonctionnalités qu'ils utilisent dans leur programme. Quand ils écrivent du code du monde réel (et ne l'utilisent pas stdc++.h), ils devront passer du temps à rechercher ces informations, ce qui signifie qu'ils seront moins productifs. C'est l'inconvénient de pratiquer avec stdc++.h.

Cela soulève la question de savoir pourquoi cela vaut la peine de participer à une programmation compétitive si elle encourage de mauvaises habitudes comme l'utilisation stdc++.het la violation d'autres normes de codage. Une réponse est que les gens le font pour la même raison qu'ils publient des programmes sur PP&CG: certains programmeurs trouvent agréable d'utiliser leurs compétences de codage dans un contexte de jeu.

Ainsi, la question de savoir si utiliser stdc++.hrevient à savoir si les avantages de la vitesse de codage dans un concours de programmation l'emportent sur les mauvaises habitudes que l'on pourrait développer en l'utilisant.

Cette question demande: "Pourquoi ne devrais-je pas #inclure <bits/stdc++.h>?" Je me rends compte qu'il a été demandé et répondu pour faire un point, et la réponse acceptée est destinée à être la seule vraie réponse à cette question. Mais la question n'est pas "Pourquoi ne devrais-je pas #inclure <bits/stdc++.h>dans le code de production?" Par conséquent, je pense qu'il est raisonnable d'envisager d'autres scénarios où la réponse peut être différente.

RedGreenCode
la source
5
J'ai déjà voté, mais il vaut peut-être la peine de souligner que «pour le plaisir» est une bonne raison de participer à une programmation compétitive. D'un autre côté, «impressionner un employeur potentiel» ne l'est pas - cela nuira activement à votre cas avec moi.
Martin Bonner soutient Monica le
2
@MartinBonner Je sais que certains gestionnaires d'embauche voient l'expérience de la programmation concurrentielle comme un drapeau rouge. Mais tant que les meilleures sociétés de logiciels utilisent des problèmes de style CP dans leurs entretiens et organisent des concours de programmation pour trouver de nouvelles recrues, CP continuera d'être populaire parmi les développeurs en herbe.
RedGreenCode
@RedGreenCode Je ne suis pas un manager (merci $ DEITY), mais j'ai parfois une influence sur l'embauche de candidats. Et je vois définitivement toute référence à la "programmation compétitive" comme un énorme drapeau rouge - pas un avantage.
Jesper Juhl
3
@JesperJuhl Si les intervieweurs techniques de votre entreprise utilisent des puzzles algorithmiques dans leurs entretiens (comme beaucoup le font), cela donne un avantage aux candidats ayant une expérience de programmation compétitive. Peut-être que le choix rationnel des candidats est de participer au CP, mais évitez de le mentionner sur leur CV / CV.
RedGreenCode
2
S'il est vrai que cet en-tête peut trouver une utilisation dans une programmation compétitive, ce n'est pas tout à fait d'où il vient. Cela venait d'une salle de classe. Et celui qui enseignait dans cette classe avait suffisamment d'influence pour polluer - via la cascade qui a suivi - des dizaines, voire des centaines de milliers d'élèves (en éduquant les enseignants et les pairs qui, alors, sans le savoir, avaient propagé cette maladie). Et maintenant, ces étudiants écrivent également des tutoriels dans un go-to-place pour les tutoriels. Je veux juste pleurer dans un coin. Les sites de programmation compétitifs devraient simplement avoir une expression régulière pour rejeter tout en-tête non standard .
Rétablir Monica
9

D'après N4606, Working Draft, Standard for Programming Language C ++:

17.6.1.2 En-têtes [en-têtes]

  1. Chaque élément de la bibliothèque standard C ++ est déclaré ou défini (selon le cas) dans un en-tête.

  2. La bibliothèque standard C ++ fournit 61 en-têtes de bibliothèque C ++, comme indiqué dans le tableau 14.

Tableau 14 - En-têtes de bibliothèque C ++

<algorithm> <future> <numeric> <strstream>
<any> <initializer_list> <optional> <system_error>
<array> <iomanip> <ostream> <thread>
<atomic> <ios> <queue> <tuple>
<bitset> <iosfwd> <random> <type_traits>
<chrono> <iostream> <ratio> <typeindex>
<codecvt> <istream> <regex> <typeinfo>
<complex> <iterator> <scoped_allocator> <unordered_map>
<condition_variable> <limits> <set> <unordered_set>
<deque> <list> <shared_mutex> <utility>
<exception> <locale> <sstream> <valarray>
<execution> <map> <stack> <variant>
<filesystem> <memory> <stdexcept> <vector>
<forward_list> <memory_resorce> <streambuf>
<fstream> <mutex> <string>
<functional> <new> <string_view>

Il n'y a pas de <bits / stdc ++. H> là-bas. Cela n'est pas surprenant, car les en-têtes <bits / ...> sont des détails d'implémentation et comportent généralement un avertissement:

*  This is an internal header file, included by other library headers.
*  Do not attempt to use it directly. 

<bits / stdc ++. h> comporte également un avertissement:

*  This is an implementation file for a precompiled header.
Bulletmagnet
la source