Warum sollte ich nicht <bits / stdc ++. H> einschließen?

266

Ich habe eine Frage mit meinem Code gepostet, dessen einzige #includeAnweisung die folgende war:

#include <bits/stdc++.h>

Mein Lehrer sagte mir, ich solle das tun, aber im Kommentarbereich wurde ich informiert, dass ich das nicht tun sollte.

Warum?

Leichtigkeitsrennen im Orbit
quelle
72
Huh. Ich hätte wissen müssen, dass using namespace std;es irgendwo eine Include-Version von da draußen geben würde.
user4581301
1
Warum existiert dieser Header überhaupt? sicherlich enthält keiner der Standard-Includes dies tatsächlich, da es viel Müll einbringen würde? und wenn es von keiner der Öffentlichkeit aufgenommen wird ... warum wird es dann in die Distribution geliefert?
Chris Beck
10
@ ChrisBeck: Es ist ein Implementierungsdetail. Es ist nicht Teil der "öffentlichen API" oder zur Verwendung bestimmt. Aber es muss noch versendet werden, sonst würde nichts funktionieren. Die Standard-Includes verwenden es möglicherweise nicht einzeln, sondern zur Verwendung in vorkompilierten Headern. Siehe den Kommentar oben, der besagt: "Dies ist eine Implementierungsdatei für einen vorkompilierten Header." .
Leichtigkeitsrennen im Orbit
1
@LightnessRacesinOrbit Wenn Sie es nicht selbst verwenden sollen, wie hilft seine Existenz bei PCH? Oder ist gcc intelligent genug, um unter bestimmten Umständen automatisch für PCH-Zwecke darauf umzuschalten?
Daniel H
2
@LightnessRacesinOrbit "Es ist nicht Teil der" öffentlichen API "oder zur Verwendung bestimmt." Völlig falsch, es ist für die öffentliche Verwendung als vorkompilierter Header gedacht. Libstdc ++ (vor) kompiliert und installiert eine vorkompilierte Version dieses Headers. Wenn Sie ihn also einschließen, enthält G ++ bits/stdc++.h.gchstattdessen die vorkompilierte Version. Es existiert, weil es existieren muss, damit die vorkompilierte Version davon generiert werden kann.
Jonathan Wakely

Antworten:

309

Das Einbeziehen <bits/stdc++.h>scheint bei Stack Overflow immer häufiger vorzukommen, vielleicht etwas, das im laufenden akademischen Jahr neu in einen nationalen Lehrplan aufgenommen wurde.

Ich stelle mir vor, die Vorteile sind vage gegeben:

  • Sie müssen nur eine #includeZeile schreiben
  • Sie müssen nicht nachsehen, in welchem ​​Standardheader sich alles befindet

Leider ist dies ein fauler Hack, ein GCC internen Header direkt anstelle von einzelnen Standard - Header wie Benennung <string>, <iostream>und <vector>. Es ruiniert die Portabilität und fördert schreckliche Gewohnheiten.

Die Nachteile umfassen:

  • Es wird wahrscheinlich nur auf diesem Compiler funktionieren
  • Sie haben keine Ahnung, was es tun wird, wenn Sie es verwenden, da sein Inhalt nicht durch einen Standard festgelegt ist
  • Selbst ein Upgrade Ihres Compilers auf die nächste Version kann Ihr Programm beschädigen
  • Jeder einzelne Standardheader muss zusammen mit Ihrem Quellcode analysiert und kompiliert werden. Dies ist langsam und führt unter bestimmten Kompilierungseinstellungen zu einer umfangreichen ausführbaren Datei

Tu es nicht!


Mehr Informationen:

Beispiel, warum Quora schlecht ist:

Leichtigkeitsrennen im Orbit
quelle
77
"Vielleicht etwas, das im laufenden akademischen Jahr neu in einen nationalen Lehrplan aufgenommen wurde" Blind führt den Blinden an :(
Setzen Sie Monica
14
@ KubaOber: Genau.
Leichtigkeitsrennen im Orbit
31
Bin gerade durch ein Wurmloch in einer anderen Frage hierher gekommen, sehr gut. Was diese Unterrichtsgewohnheit noch schlimmer macht, ist, dass sie normalerweise von einem direkten gefolgt wird using namesapce std;. Nur zwei Zeilen und praktisch jede nette Kennung wird verwendet. Unglaublich frustrierend zu sehen, wie es gelehrt wird.
Geschichtenerzähler - Unslander Monica
5
Über das Quora-Beispiel könnte es sich mit der Zeit verschoben haben. Ich habe heute die Seite besucht und sowohl die Vor- als auch die Nachteile von <bits / stdc ++. H> wurden im spezifischen Kontext von Online-Programmierwettbewerben aufgeführt. Ich finde ihre Schlussfolgerung in Ordnung.
YSC
3
@ EvgeniSergeev: 2 KB ist eine Menge Code, Daten, Symbolinformationen usw., wenn versucht wird, seine Wirkung zu bestimmen. Verstehst du alles, was hinzugefügt wird? Für Ihren Compiler? Die aktuelle Version? Alle Veröffentlichungen dazwischen? Alle zukünftigen Versionen? Wenn Sie sich zwischen Bequemlichkeit und Richtigkeit entscheiden müssen, gibt es nur eine einzige gültige Option.
Unsichtbarer
47

Warum? Weil es so verwendet wird, als ob es ein C ++ - Standardheader sein sollte, aber kein Standard erwähnt es. Ihr Code ist also konstruktionsbedingt nicht portierbar. Auf cppreference finden Sie keine Dokumentation dazu . Es könnte also genauso gut nicht existieren. Es ist eine Erfindung der Fantasie von jemandem :)

Zu meinem Entsetzen und Unglauben habe ich festgestellt, dass es eine bekannte Tutorial-Site gibt, auf der jedes C ++ - Beispiel diesen Header zu enthalten scheint . Die Welt ist verrückt. Das ist der Beweis.


An alle, die solche "Tutorials" schreiben

Bitte verwenden Sie diesen Header nicht mehr. Vergiss es. Verbreite diesen Wahnsinn nicht. Wenn Sie nicht verstehen wollen, warum dies falsch ist , nehmen Sie mein Wort dafür. Ich bin nicht in Ordnung, als Autoritätsperson für irgendetwas behandelt zu werden, und ich bin wahrscheinlich die halbe Zeit voll davon, aber ich werde nur in diesem einen Fall eine Ausnahme machen. Ich behaupte, dass ich weiß, wovon ich hier spreche. Nimm mich beim Wort. Ich flehe dich an.

PS Ich kann mir gut vorstellen, welchen abscheulichen "Lehrstandard" diese böse Idee hätte haben können und welche Umstände dazu geführt haben. Nur weil es einen praktischen Bedarf dafür zu geben schien, ist dies nicht akzeptabel - auch nicht im Nachhinein.

PPS Nein, es gab keinen praktischen Bedarf dafür. Es gibt nicht so viele C ++ - Standardheader und sie sind gut dokumentiert. Wenn Sie unterrichten, tun Sie Ihren Schülern einen schlechten Dienst, indem Sie solche "Magie" hinzufügen. Programmierer mit einer magischen Denkweise zu produzieren, ist das Letzte, was wir wollen. Wenn Sie den Schülern eine Teilmenge von C ++ anbieten müssen, um ihnen das Leben zu erleichtern, erstellen Sie einfach ein Handout mit der kurzen Liste der Überschriften, die für den von Ihnen unterrichteten Kurs gelten, und einer präzisen Dokumentation der Bibliothekskonstrukte, die die Schüler verwenden sollen.

Stellen Sie Monica wieder her
quelle
35

Es gibt eine Stack Exchange-Site namens Programming Puzzles & Code Golf . Die Programmierpuzzles auf dieser Site passen zu dieser Definition von Puzzle :

Ein Spielzeug, ein Problem oder eine andere Einrichtung, die amüsieren soll, indem sie Schwierigkeiten aufwirft, die durch Einfallsreichtum oder geduldige Anstrengung gelöst werden können.

Sie sollen amüsieren und nicht so, wie ein arbeitender Programmierer sich über ein reales Problem amüsieren könnte, das bei seiner täglichen Arbeit auftritt.

Code Golf ist "eine Art Freizeit-Computerprogrammierwettbewerb, bei dem die Teilnehmer versuchen, den kürzestmöglichen Quellcode zu erreichen, der einen bestimmten Algorithmus implementiert." In den Antworten auf der PP & CG-Site sehen Sie, wie Personen die Anzahl der Bytes in ihren Antworten angeben. Wenn sie einen Weg finden, ein paar Bytes zu sparen, streichen sie die ursprüngliche Nummer aus und zeichnen die neue auf.

Wie zu erwarten ist, belohnt Code-Golf extremen Missbrauch von Programmiersprachen. Ein-Buchstaben-Variablennamen. Kein Leerzeichen. Kreative Nutzung von Bibliotheksfunktionen. Undokumentierte Funktionen. Nicht standardisierte Programmierpraktiken. Schreckliche Hacks.

Wenn ein Programmierer bei der Arbeit eine Pull-Anfrage mit Golf-Code einreichte, wurde diese abgelehnt. Ihre Mitarbeiter würden sie auslachen. Ihr Manager würde an ihrem Schreibtisch vorbeischauen, um sich zu unterhalten. Trotzdem amüsieren sich Programmierer, indem sie Antworten an PP & CG senden.

Was hat das damit zu tun stdc++.h? Wie andere betont haben, ist die Verwendung faul. Es ist nicht portierbar, sodass Sie nicht wissen, ob es auf Ihrem Compiler oder der nächsten Version Ihres Compilers funktioniert. Es fördert schlechte Gewohnheiten. Es ist nicht Standard, daher kann das Verhalten Ihres Programms von Ihren Erwartungen abweichen. Dies kann die Kompilierungszeit und die Größe der ausführbaren Datei erhöhen.

Dies sind alles gültige und korrekte Einwände. Warum sollte jemand diese Monstrosität nutzen?

Es stellt sich heraus, dass manche Leute gerne Rätsel ohne den Code Golf programmieren . Sie treffen sich und treten bei Veranstaltungen wie ACM-ICPC, Google Code Jam und Facebook Hacker Cup oder auf Websites wie Topcoder und Codeforces an. Ihr Rang basiert auf der Programmkorrektheit, der Ausführungsgeschwindigkeit und der Geschwindigkeit, mit der sie eine Lösung einreichen. Um die Ausführungsgeschwindigkeit zu maximieren, verwenden viele Teilnehmer C ++. Um die Codierungsgeschwindigkeit zu maximieren, verwenden einige von ihnen stdc++.h.

Ist das eine gute Idee? Lassen Sie uns die Liste der Nachteile überprüfen. Portabilität? Es spielt keine Rolle, da diese Codierungsereignisse eine bestimmte Compilerversion verwenden, die die Teilnehmer im Voraus kennen. Einhaltung von Standards? Nicht relevant für einen Codeblock, dessen Nutzungsdauer weniger als eine Stunde beträgt. Kompilierzeit und ausführbare Größe? Diese sind nicht Teil der Bewertungsrubrik des Wettbewerbs.

Wir haben also schlechte Gewohnheiten. Dies ist ein berechtigter Einwand. Durch die Verwendung dieser Header-Datei vermeiden die Teilnehmer die Möglichkeit zu erfahren, welche Standard-Header-Datei die Funktionalität definiert, die sie in ihrem Programm verwenden. Wenn sie Code aus der realen Welt schreiben (und nicht verwenden stdc++.h), müssen sie Zeit damit verbringen, diese Informationen nachzuschlagen, was bedeutet, dass sie weniger produktiv sind. Das ist der Nachteil beim Üben stdc++.h.

Dies wirft die Frage auf, warum es sich überhaupt lohnt, an wettbewerbsorientierten Programmen teilzunehmen, wenn dadurch schlechte Gewohnheiten wie die Verwendung stdc++.hund Verletzung anderer Codierungsstandards gefördert werden. Eine Antwort ist, dass die Leute dies aus dem gleichen Grund tun, aus dem sie Programme auf PP & CG veröffentlichen: Einige Programmierer finden es angenehm, ihre Codierungsfähigkeiten in einem spielerischen Kontext einzusetzen.

Die Frage, ob verwendet werden soll, stdc++.hhängt also davon ab, ob die Vorteile der Codierungsgeschwindigkeit bei einem Programmierwettbewerb die schlechten Gewohnheiten überwiegen, die man durch die Verwendung entwickeln könnte.

Diese Frage lautet: "Warum sollte ich nicht # einschließen <bits/stdc++.h>?" Mir ist klar, dass es gefragt und beantwortet wurde, um einen Punkt zu machen, und die akzeptierte Antwort soll die einzig wahre Antwort auf diese Frage sein. Die Frage lautet jedoch nicht "Warum sollte ich nicht # <bits/stdc++.h>in den Produktionscode aufnehmen?" Daher halte ich es für sinnvoll, andere Szenarien in Betracht zu ziehen, in denen die Antwort möglicherweise anders ist.

RedGreenCode
quelle
5
Ich habe bereits positiv bewertet, aber es könnte erwähnenswert sein, dass "zum Spaß" ein guter Grund ist, an wettbewerbsorientierten Programmen teilzunehmen. Auf der anderen Seite ist "einen potenziellen Arbeitgeber zu beeindrucken" nicht - es wird Ihrem Fall bei mir aktiv schaden .
Martin Bonner unterstützt Monica
2
@MartinBonner Ich weiß, dass einige Personalchefs wettbewerbsfähige Programmiererfahrungen als rote Fahne betrachten. Solange Top-Software-Unternehmen in ihren Interviews Probleme im CP-Stil verwenden und Programmierwettbewerbe durchführen, um neue Mitarbeiter zu finden, wird CP bei aufstrebenden Entwicklern weiterhin beliebt sein.
RedGreenCode
@RedGreenCode Ich bin kein Manager (danke $ DEITY), aber ich habe manchmal Einfluss auf die Einstellung von Zielen. Und ich sehe definitiv jeden Hinweis auf "wettbewerbsfähige Programmierung" als große rote Fahne - kein Vorteil.
Jesper Juhl
3
@JesperJuhl Wenn technische Interviewer in Ihrem Unternehmen in ihren Interviews algorithmische Rätsel verwenden (wie viele), haben Kandidaten mit wettbewerbsfähiger Programmiererfahrung einen Vorteil. Vielleicht besteht die rationale Wahl für Kandidaten darin, an CP teilzunehmen, aber vermeiden Sie es, dies in ihrem Lebenslauf zu erwähnen.
RedGreenCode
2
Es ist zwar richtig, dass dieser Header in einigen wettbewerbsfähigen Programmen Verwendung finden kann, aber es ist nicht ganz der Ursprung. Es kam aus einem Klassenzimmer. Und wer auch immer in diesem Klassenzimmer unterrichtete, hatte genug Einfluss, um über eine Kaskade, die folgte, Zehntausende, wenn nicht Hunderttausende von Schülern zu verschmutzen (indem er die Lehrer und Gleichaltrigen erzog, die diese Krankheit dann unwissentlich verbreitet hatten). Und jetzt schreiben diese Schüler auch Tutorials an einer Anlaufstelle für Tutorials. Ich möchte nur in einer Ecke weinen. Wettbewerbsfähige Programmierseiten sollten nur einen regulären Ausdruck haben, um nicht standardmäßige Header abzulehnen .
Setzen Sie Monica
8

Ab N4606, Arbeitsentwurf, Standard für die Programmiersprache C ++:

17.6.1.2 Header [Header]

  1. Jedes Element der C ++ - Standardbibliothek wird in einem Header deklariert oder (entsprechend) definiert.

  2. Die C ++ - Standardbibliothek bietet 61 C ++ - Bibliotheksheader (siehe Tabelle 14).

Tabelle 14 - C ++ - Bibliotheksheader

<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>

Es gibt dort kein <bits / stdc ++. H>. Dies ist nicht überraschend, da <bits / ...> -Header Implementierungsdetails sind und normalerweise eine Warnung enthalten:

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

<bits / stdc ++. h> enthält auch eine Warnung:

*  This is an implementation file for a precompiled header.
Kugelmagnet
quelle