#include <bits / stdc ++。h>を使用してはいけないのはなぜですか?


267

私のコードで質問を投稿しました#includeが、その唯一のディレクティブは次のとおりです:

#include <bits/stdc++.h>

私の先生はこれをするように私に言いました、しかし私はコメントセクションで私がすべきではないと知らされました。

どうして?


72
ええと。using namespace std;どこかにあるインクルードバージョンがあることを知っていたはずです。
user4581301 2015

1
なぜこのヘッダーが存在するのですか?確かに、標準にはインクルードは含まれていません。ジャンクが大量に含まれるためです。そして、もしそれがどの公衆にも含まれていないなら...なぜそれはディストリビューションに含まれているのですか?
Chris Beck

10
@ChrisBeck:実装の詳細です。これは「パブリックAPI」の一部ではなく、使用するためのものでもありません。ただし、それでも出荷する必要があります。そうしないと何も機能しません。標準インクルードでは個別に使用することはできませんが、プリコンパイル済みヘッダーで使用できます。冒頭のコメントを参照してください:「これはプリコンパイル済みヘッダーの実装ファイルです。」
オービットのライトネスレース2016年

1
@LightnessRacesinOrbit自分で使用する予定がない場合、その存在はPCHにどのように役立ちますか?または、gccは、状況によっては、PCHの目的のために自動的に切り替えるのに十分スマートですか?
Daniel H

2
@LightnessRacesinOrbit 「「パブリックAPI」の一部ではなく、使用することも意図されていません。」完全に間違っています。これは、プリコンパイル済みヘッダーとして、パブリックでの使用を目的としています。Libstdc ++は、そのヘッダーのプリコンパイルバージョンを(プリ)コンパイルしてインストールするため、それをインクルードすると、G ++は実際にはbits/stdc++.h.gchプリコンパイルバージョンをインクルードします。これは、プリコンパイルされたバージョンを生成できるように存在する必要があるために存在します。
Jonathan Wakely

回答:


311

含める<bits/stdc++.h>ことは、スタックオーバーフローでますます一般的になるように思われます。おそらく、今年度の国家カリキュラムに新しく追加されたものです。

利点は漠然と与えられていると思います:

  • #include一行書くだけ
  • すべての標準ヘッダーを調べる必要はありません

残念ながら、これは遅延ハックであり<string><iostream>やのような個々の標準ヘッダーではなく、GCC内部ヘッダーに直接名前を付け<vector>ます。それは携帯性を台無しにし、ひどい習慣を助長します。

欠点は次のとおりです。

  • それはおそらくそのコンパイラでのみ機能します
  • 内容は標準で設定されていないため、使用時に何が行われるかはわかりません。
  • コンパイラを次のバージョンにアップグレードするだけでも、プログラムが壊れる可能性があります
  • すべての単一の標準ヘッダーをソースコードと共に解析およびコンパイルする必要があります。これは低速であり、特定のコンパイル設定で実行ファイルが大きくなります。

やめろ!


詳しくは:

Quoraが悪い理由の例:


78
「おそらく、現在の学年度に新たに国のカリキュラムに追加されたものだろう」ブラインドが盲人をリードする:(
復活モニカ

14
@KubaOber:その通りです。
オービットのライトネスレース

33
別の質問のワームホールからここに来ただけで、とても良いです。この教育の習慣を悪化させるのは、通常、直接指導が続くことですusing namesapce std;。わずか2行で、事実上すべての素晴らしい識別子が使用されます。それが教えられているのを見ると信じられないほどイライラします。
StoryTeller-Unslander Monica

6
クォーラの例については、時間とともに変化した可能性があります。今日のページと、オンラインプログラミングコンテストの特定のコンテキストに記載されている<bits / stdc ++。h>の長所と短所の両方にアクセスしました。彼らの結論は大丈夫だと思う。
YSC 2018

4
@EvgeniSergeev:2KiBはその効果を判断しようとすると、多くのコード、データ、シンボル情報などになります。追加されているすべてを理解していますか?あなたのコンパイラは?現在のリリースは?その間のすべてのリリース?将来のすべてのリリース?利便性と正確さのどちらかを決定する必要がある場合、有効なオプションは1つだけです。
IInspectable 2018

48

どうして?これは、C ++標準ヘッダーであるかのように使用されますが、標準で言及されていないためです。そのため、コードは構造上、移植性がありません。そのためのドキュメントはcppreferenceにはありません。したがって、存在しない可能性もあります。それは誰かの想像力の象徴です:)

私は、私の恐怖と信じられないことに、すべてのC ++の例にこのヘッダーが含まれているように見える有名なチュートリアルサイトがあることを発見しました。世界は狂っています。それが証明です。


そんな「チュートリアル」を書いている方へ

このヘッダーの使用を中止してください。気にしないで。この狂気を広めないでください。なぜこれが間違っているのかを理解したくないのであれば、私の言葉を信じてください。私は何に対しても権威のある人物として扱われることはまったく問題であり、おそらく半分の時間でそれで満たされますが、この1つの場合のみ例外を設けます。私はここで私が話していることを知っていると主張します。私の言葉を信じてください。お願いします。

PS私は、この邪悪なアイデアが起こったかもしれない忌まわしい「教育基準」と、それを導いた状況を想像することができます。それが実際に必要であるように見えたからといって、それを受け入れられるようにはしません。

PPSいいえ、実用的には必要ありませんでした。C ++標準ヘッダーはそれほど多くはなく、十分に文書化されています。あなたが教えるならば、あなたはそのような「魔法」を加えることによってあなたの学生に害悪をしているのです。魔法のような考え方でプログラマーを生み出すことは、私たちが最後に望んでいることです。生活を楽にするためにC ++のサブセットを学生に提供する必要がある場合は、教えるコースに適用できるヘッダーの短いリストと、学生が使用することを期待するライブラリ構造の簡潔なドキュメントを備えた配布資料を作成してください。


35

Programming Puzzles&Code Golf」というStack Exchangeサイトがあります。そのサイトのプログラミングパズルは、次のパズルの定義に適合しています。

工夫や忍耐強い努力によって解決されるべき困難を提示することによって楽しませるように設計されたおもちゃ、問題、またはその他の工夫。

それらは楽しませるように設計されており、日常の仕事で遭遇する現実の問題によって働くプログラマーが楽しまれるような方法ではありません。

コードゴルフは「参加者が特定のアルゴリズムを実装する最短のソースコードを達成するために努力するレクリエーションのコンピュータプログラミングコンテストの一種です。」PP&CGサイトの回答では、回答のバイト数を指定しているのがわかります。彼らが数バイトを削り取る方法を見つけたとき、彼らは元の数を取り除き、新しいものを記録します。

ご想像のとおり、コードゴルフはプログラミング言語の極度の乱用に報います。1文字の変数名。空白はありません。ライブラリ関数の創造的な使用。文書化されていない機能。非標準のプログラミング方法。恐ろしいハック。

プログラマーがゴルフ形式のコードを含む職場でプルリクエストを送信した場合、そのリクエストは拒否されます。彼らの同僚は彼らを笑いました。彼らの上司はチャットのために机に立ち寄ります。それでも、プログラマーはPP&CGに回答を送信することで自分自身を楽しませます。

これは何と関係がありstdc++.hますか?他の人が指摘したように、それを使用するのは面倒です。移植性がないため、コンパイラで動作するか、コンパイラの次のバージョンで動作するかはわかりません。悪い習慣を助長します。これは非標準であるため、プログラムの動作は予想と異なる場合があります。コンパイル時間と実行可能ファイルのサイズが増える可能性があります。

これらはすべて有効かつ正しい異論です。では、なぜ誰もがこの怪物を使うのでしょうか?

コードゴルフなしでパズルプログラミングするのが好きな人もいます。彼らは集まり、ACM-ICPC、Google Code Jam、Facebook Hacker Cupなどのイベント、またはTopcoderやCodeforcesなどのサイトで競争します。それらのランクは、プログラムの正確さ、実行速度、およびソリューションの提出速度に基づいています。実行速度を最大にするために、多くの参加者がC ++を使用しています。コーディング速度を最大にするために、一部のユーザーはを使用していますstdc++.h

これは良い考えですか?短所のリストをチェックしてみましょう。ポータビリティ?これらのコーディングイベントは、競技者が事前に知っている特定のコンパイラバージョンを使用するため、問題ではありません。標準への準拠?有効期間が1時間未満のコードブロックには関係ありません。コンパイル時間と実行可能サイズ?これらはコンテストの採点規範の一部ではありません。

だから私たちは悪い習慣に取り残されています。これは有効な異論です。このヘッダーファイルを使用することで、参加者は、プログラムで使用している機能を定義している標準ヘッダーファイルを知る機会を避けています。彼らが実際のコードを書いているとき(そしてを使用していないときstdc++.h)は、この情報の検索に時間を費やす必要があるため、生産性が低下します。これがで練習することの欠点ですstdc++.h

これは、stdc++.h他のコーディング標準を使用したり違反したりするような悪い習慣を助長するのであれば、なぜそれが競争プログラミングに参加する価値があるのか​​という疑問を提起します。1つの答えは、PP&CGにプログラムを投稿するのと同じ理由で人々がそれを行うということです。一部のプログラマーは、ゲームのようなコンテキストでコーディングスキルを使用するのが楽しいと感じています。

したがって、使用stdc++.hするかどうかの問題は、プログラミングコンテストでのコーディング速度のメリットが、それを使用することで発達する可能性のある悪い習慣を上回っているかどうかにかかっています。

この質問は、次のように尋ね<bits/stdc++.h>ます。私はそれがポイントを作るために尋ねられて答えられたことを理解し、受け入れられた答えはこの質問に対する唯一の真の答えとなることを意図しています。しかし、問題は「なぜ<bits/stdc++.h>プロダクションコードに#include してはならないのか」ではありません。したがって、答えが異なる可能性がある他のシナリオを検討することは合理的だと思います。


5
私はすでに賛成していますが、「楽しみのために」が競争力のあるプログラミングに参加する正当な理由であることを指摘する価値があるかもしれません。一方、「潜在的な雇用主を感心させる」ことはそうではありません-それは私とあなたの事件を積極的に害します。
Martin Bonnerがモニカをサポート

2
@MartinBonner採用担当マネージャーの中には、競争の激しいプログラミング経験を危険信号と見なしている人がいることを知っています。しかし、トップソフトウェア企業がインタビューでCPスタイルの問題を使用し、プログラミングコンテストを実行して新入社員を見つける限り、CPは意欲的な開発者の間で引き続き人気があります。
-RedGreenCode

@RedGreenCode私はマネージャーではありませんが($ DEITYに感謝します)、私は時々、職務の採用に影響を与えます。そして、私は間違いなく「競争プログラミング」への言及を巨大な赤旗と見なします- 利点ではありません
Jesper Juhl

3
@JesperJuhl社内の技術面接担当者が面接でアルゴリズムパズルを使用すると(多くの場合と同様)、これにより、競争力のあるプログラミング経験を持つ候補者に利点がもたらされます。おそらく、候補者の合理的な選択はCPに参加することですが、履歴書/ CVで言及することは避けてください。
RedGreenCode

2
このヘッダーがいくつかの競争力のあるプログラミングで使用できることは事実ですが、それがどこから来たのかは完全ではありません。それは教室から来ました。そして、その教室で教えた人は誰でも(その後のカスケードによって)数十万ではないにしても数十万の生徒を汚染するのに十分な影響力を持っていました(教師と同僚に知らず知らずにその病気を広めていました)。そして今、それらの学生は、チュートリアルのために行き先でチュートリアルも書いています。片隅で泣きたいだけです。競争の激しいプログラミングサイトでは、非標準ヘッダーを拒否するための正規表現を用意する必要があります。
モニカを

9

N4606から、ワーキングドラフト、プログラミング言語C ++の標準:

17.6.1.2ヘッダー[ヘッダー]

  1. C ++標準ライブラリの各要素は、ヘッダーで(必要に応じて)宣言または定義されます。

  2. 表14に示すように、C ++標準ライブラリは61のC ++ライブラリヘッダーを提供します。

表14 — 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>

<bits / stdc ++。h>はありません。<bits / ...>ヘッダーは実装の詳細であり、通常は警告が表示されるため、これは当然のことです。

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

<bits / stdc ++。h>にも警告が表示されます。

*  This is an implementation file for a precompiled header.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.