为什么我不应该#include <bits stdc++.h=""></bits>

c++ portability turbo-c++ c++-faq implementation-defined-behavior


我用我的代码发布了一个问题,该代码的唯一 #include 指令如下:

#include <bits/stdc++.h>

老师让我这样做,但在评论区,我被告知不应该。

Why?




Answer 1 Lightness Races in Orbit


在Stack Overflow上看到包含 <bits/stdc++.h> 似乎越来越普遍,这也许是本学年国家课程中新增的内容。

我想,这样做的好处是隐隐约约约的。

  • 您只需要写一条 #include
  • 你不需要查找所有的东西都在哪个标准的标题中

不幸的是,这是一个懒惰的黑客,直接命名GCC内部标头,而不是单独的标准标头,如 <string><iostream><vector> 。它破坏了便携性并养成了可怕的习惯。

其弊端包括:

  • 它可能只适用于该编译器
  • 当你使用它的时候,你不知道它会做什么,因为它的内容不是由一个标准设置的
  • 即使只是将你的编译器升级到自己的下一个版本,也可能会破坏你的程序。
  • 每一个标准的标题都必须与你的源代码一起解析和编译,这样做的速度很慢,而且在特定的编译设置下,会导致可执行文件很笨重。

不要做!


更多信息:

举例说明为什么Quora是坏的。




Answer 2 Reinstate Monica


为什么?因为使用它的方式就像它应该是C ++标准头文件一样,但是没有标准提到它。因此,您的代码在构造上不可移植。在cppreference上找不到任何文档。因此它可能不存在。这是某人的想象力的虚构:)

令我震惊和怀疑的是,我发现有一个著名的教程站点,每个C ++示例似乎都包含此标头。世界疯了。那就是证明。


对于任何编写此类“教程”的人

请停止使用此标题。忘掉它。不要传播这种疯狂。如果您不愿意理解为什么这样做是错误的,请相信我。我根本不能被视为任何事物上的权威人物,而且我可能有一半时间都饱受权威的束缚,但仅在这种情况下,我会例外。我声称我知道我在说什么。相信我。我恳求你。

P.S.S.我完全可以想象到这种可恶的 "教学标准 "可能发生在什么地方,以及导致这种邪恶的想法的情况。只是因为似乎有实际的需要,并不意味着它可以接受----即使现在回想起来也不行。

P.P.P.S.不,没有实际需要。没有那么多的C++标准头文件,而且有很好的文档。如果你在教学中加入这样的 "魔力",是对学生的一种伤害。用神奇的心态来培养程序员,是我们最不希望看到的。如果你需要给学生提供一个C++的子集,让他们的生活更轻松,只需制作一份讲义,上面有适用于你所教课程的简短的标题列表,并附上你期望学生使用的库结构的简明文档。




Answer 3 RedGreenCode


有一个叫做Programming Puzzles&Code Golf的Stack Exchange网站。该站点上的编程难题符合以下这个难题的定义:

玩具、问题或其他旨在通过提出困难,通过巧思或耐心的努力来解决的玩具、问题或其他的小玩意,以达到娱乐的目的。

它们是为了娱乐而设计的,而不是以工作中的程序员在日常工作中遇到的现实问题为乐趣的方式。

Code Golf是“一种娱乐性计算机编程竞赛,参赛者努力实现实现特定算法的最短源代码。” 在PP&CG网站上的答案中,您会看到人们在他们的答案中指定了字节数。当他们找到一种方法来减少一些字节时,他们将删除原始数字并记录新的数字。

正如你所期望的那样,代码打高尔夫球会奖励极端的编程语言滥用。一个字母的变量名。没有留白空间。库函数的创造性使用。未被记录的功能。非标准的编程实践。骇人听闻的黑客。

如果程序员在工作中提交包含高尔夫风格代码的拉取请求,该请求将被拒绝。他们的同事会嘲笑他们。他们的经理将坐在他们的办公桌旁聊天。即使这样,程序员也可以通过向PP&CG提交答案来娱乐自己。

这与 stdc++.h 什么关系?正如其他人指出的那样,使用它是懒惰的。它是不可移植的,因此您不知道它是否可在您的编译器或下一版本的编译器上运行。它养成不良习惯。这是非标准的,因此您的程序的行为可能与您期望的不同。它可能会增加编译时间和可执行文件的大小。

这些反对意见都是有道理的,也是正确的。那么,为什么有人要用这种怪胎呢?

事实证明,有些人喜欢没有代码高尔夫的编程难题。他们聚在一起,参加诸如ACM-ICPC,Google Code Jam和Facebook Hacker Cup之类的活动,或在Topcoder和Codeforces之类的网站上竞争。他们的排名取决于程序的正确性,执行速度以及提交解决方案的速度。为了最大化执行速度,许多参与者使用C ++。为了最大化编码速度,其中一些使用 stdc++.h

这样做是不是很好呢?下面我们来看看缺点有哪些?可移植性?没有关系,因为这些编码活动使用的是参赛者事先知道的特定编译器版本。是否符合标准?对于使用寿命不到一小时的代码块来说,没有关系。编译时间和可执行大小?这些并不在比赛的评分标准中。

所以我们留下了不良习惯。这是一个有效的反对意见。通过使用此头文件,参赛者可以避免了解哪个标准头文件定义了他们在程序中使用的功能。当他们编写实际代码(而不使用 stdc++.h )时,他们将不得不花时间查找这些信息,这意味着他们的工作效率将降低。这是使用 stdc++.h 进行练习的缺点。

这就提出了一个问题,即如果它鼓励使用 stdc++.h 等不良习惯并违反其他编码标准,那么为什么值得参加竞争性编程。一个答案是人们之所以这么做是因为他们在PP&CG上发布程序的原因相同:一些程序员发现在类似游戏的环境中使用他们的编码技能很有趣。

因此,是否使用 stdc++.h 归结为编程竞赛中的编码速度收益是否超过了使用它可能产生的不良习惯。

这个问题问:“为什么不#include <bits/stdc++.h> ?” 我意识到有人提出并回答了这个问题,所接受的答案旨在成为该问题的唯一真实答案。但是问题不是“为什么我不应该在生产代码中#include <bits/stdc++.h> ?” 因此,我认为考虑答案可能不同的其他情况是合理的。




Answer 4 Bulletmagnet


摘自N4606,工作草案,程序设计语言C++标准。

17.6.1.2 标头[标头]

  1. C++标准库中的每一个元素都在一个标题中声明或定义(根据需要)。

  2. C++标准库提供了61个C++库头,如表14所示。

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