【问题标题】:Why should I not #include <bits/stdc++.h>?为什么我不应该#include <bits/stdc++.h>?
【发布时间】:2022-01-11 17:33:24
【问题描述】:

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

#include <bits/stdc++.h>

我的老师告诉我这样做,但在 cmets 部分我被告知我不应该这样做。

为什么?

【问题讨论】:

  • 嗯。我应该知道在某个地方会有一个包含版本的using namespace std;
  • 为什么这个头文件还存在?肯定没有一个标准实际上包括这个,因为它会带来很多垃圾?如果它没有被任何公共包含...那么为什么它会在发行版中发布?
  • @ChrisBeck:这是一个实现细节。它不是“公共 API”的一部分,也不是供使用的。但它仍然必须运送,否则任何事情都不会奏效。标准包含可能不会单独使用它,但它可以用于预编译头文件。查看顶部的注释,上面写着:“这是一个预编译头文件的实现文件。”.
  • @LightnessRacesinOrbit “它不是“公共 API”的一部分,也不打算使用。” 完全错误,它是作为预编译头文件供公众使用的。 Libstdc++(预)编译并安装该头文件的预编译版本,因此如果您包含它,那么 G++ 实际上将包含bits/stdc++.h.gch,而不是预编译版本。它之所以存在是因为它必须存在才能生成它的预编译版本。
  • @JonathanWakely 标准库的公共 API,我的意思是;不是 libstdc++。每天(以及在他们的项目中)在 Stack Overflow 上使用它的人并没有因为您正在谈论的原因或用例而使用它。当然,我的评论可能措辞更准确,但请注意,我确实指出了它用于预编译头文件。随意写一个有竞争力的答案。

标签: c++ portability turbo-c++ c++-faq implementation-defined-behavior


【解决方案1】:

包括&lt;bits/stdc++.h&gt; 似乎在 Stack Overflow 上越来越常见,也许是本学年新添加到国家课程中的内容。

我想这些优势是这样模糊地给出的:

  • 您只需要写一个#include 行。
  • 您无需查找所有内容都在哪个标准标头中。

不幸的是,这是一个懒惰的 hack,直接命名 GCC 内部标头而不是单独的标准标头,如 &lt;string&gt;&lt;iostream&gt;&lt;vector&gt;。它破坏了便携性并养成了糟糕的习惯。

缺点包括:

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

不要这样做!


更多信息:

Quora 不好的例子:

【讨论】:

  • “也许是本学年国家课程中新增加的东西”盲人领盲:(
  • 刚刚通过另一个问题的虫洞来到这里,非常好。使这种教学习惯变得更糟的是,它通常后面跟着一个直接的using namesapce std;。只有两行,几乎每一个漂亮的标识符都被使用了。看到它被教授令人难以置信的沮丧。
  • 关于 quora 示例,它可能会随着时间而变化。我今天访问了该页面,了解 的优点和缺点,其中列出了在线编程竞赛的特定上下文。我觉得他们的结论还可以。
  • @EvgeniSergeev:在尝试确定其效果时,2KiB 是大量的代码、数据、符号信息等。您了解正在添加的所有内容吗?对于您的编译器?当前版本?中间的所有版本?所有未来的版本?如果您需要在方便性和正确性之间做出决定,那么只有一个有效选项。
  • 希望不是课程,而只是散布在“竞赛”网站或其他东西上的货物崇拜……尽管遗憾的是,无论哪种方式都不会让我感到惊讶。
【解决方案2】:

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

我发现 - 令我惊恐和难以置信 - 有一个著名的教程网站,每个 C++ 示例似乎都包含此标头。世界疯了。这就是证据。


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

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

附:我完全可以想象这种邪恶想法可能发生的可恶“教学标准”,以及导致它的环境。仅仅因为它似乎有实际需要并不能让人接受——即使回想起来也不行。

附言不,没有实际需要。没有那么多 C++ 标准头文件,而且它们有据可查。如果你教书,你就会通过添加这样的“魔法”来伤害你的学生。培养具有神奇思维方式的程序员是我们最不想要的。如果您需要为学生提供 C++ 的子集以使他们的生活更轻松,只需制作一份讲义,其中包含适用于您教授的课程的简短标题列表,以及您希望学生使用的库结构的简明文档。

【讨论】:

  • 那个著名的站点是每个 C++ 示例看起来都像 C 程序的站点?
  • 他在谈论 GeeksForGeeks
  • 包含该标题以及using namespace std; 会很有趣。然后像用户定义的gcdswap 或名为data 的变量这样简单的事情会表现得很奇怪或根本无法编译,让编码人员摸不着头脑,想知道问题可能出在哪里。
  • 我说的是典型的“知名网站”。不幸的是,其中有很多。而且他们总是看起来像盲人带领盲人:(
【解决方案3】:

有一个名为 Programming Puzzles & Code Golf 的 Stack Exchange 站点。该网站上的编程难题符合puzzle的这个定义:

一种玩具、问题或其他设计,旨在通过提出需要通过聪明才智或耐心努力来解决的困难来娱乐。

它们的设计目的是为了娱乐,而不是像在职程序员可能会因日常工作中遇到的现实问题而感到有趣。

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 &lt;bits/stdc++.h&gt;?”我意识到有人提出并回答了这一点,并且接受的答案旨在成为该问题的唯一真实答案。但问题不是“为什么我不应该在生产代码中#include &lt;bits/stdc++.h&gt;?”因此,我认为考虑其他可能答案可能不同的场景是合理的。

【讨论】:

  • 我已经投了赞成票,但可能值得指出的是,“为了好玩”是参加竞争性编程的一个很好的理由。另一方面,“给潜在雇主留下深刻印象”不是 - 它会积极地伤害你的情况。
  • @MartinBonner 我知道一些招聘经理将竞争性编程经验视为危险信号。但只要顶级软件公司在面试中使用 CP 式的问题并举办编程竞赛来寻找新员工,CP 将继续受到有抱负的开发人员的欢迎。
  • @JesperJuhl 如果贵公司的技术面试官在他们的面试中使用算法谜题(就像许多人一样),那么具有竞争性编程经验的候选人就会有优势。也许候选人的理性选择是参加CP,但避免在简历/简历中提及。
  • 虽然这个头文件确实可以在一些竞争性编程中找到用途,但它并不完全是从哪里来的。它来自一间教室。在那间教室里教书的人有足够的影响力来污染——通过随后的级联效应——数以万计甚至数十万的学生(通过教育那些在不知不觉中一直在传播这种疾病的老师和同龄人)。现在,这些学生也正在编写​​教程,以获取教程。我只想在角落里哭。竞争性编程网站应该只有一个正则表达式来拒绝任何非标准标题
  • @YunfeiChen 有些人认为它会鼓励候选人在工作中需要改掉的坏习惯(比如使用#include &lt;bits/stdc++.h&gt; 或编写不可读的代码)。零编程经验也是一个危险信号,但这就是我们进行面试的原因。
【解决方案4】:

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

那里没有 。这并不奇怪,因为 标头是实现细节,通常带有警告:

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

也带有警告:

*  This is an implementation file for a precompiled header.

【讨论】:

    【解决方案5】:

    我们不使用的原因:

    #include <bits/stdc++.h>
    

    是因为效率。 让我打个比方: 对于那些了解 Java 的人: 如果你问你的导师以下是否是一个好主意,除非他们是一个糟糕的导师,否则他们会说不:

    import java.*.*
    

    #include... 基本上是做同样的事情...这不是不使用它的唯一原因,但它是不使用它的主要原因之一。 对于现实生活中的类比: 想象一下你有一个图书馆,你想从图书馆借几本书,你会把整个图书馆搬到你家旁边吗?这将是昂贵且低效的。如果你只需要 5 本书,那就只拿出 5 本书……而不是整个图书馆……

    #include <bits/stdc++.h>
    

    看起来很方便程序看起来我只需要键入一个包含语句就可以了,移动整个图书馆也是如此,看起来我只需要移动一个整个图书馆而不是 5 本书,一本接一本。对您来说看起来很方便,对于实际必须搬家的人来说?没那么多,猜猜在 C++ 中进行移动的人将是您的计算机...计算机不会喜欢为您编写的每个源文件移动整个库:).....

    【讨论】:

    • 这几乎肯定是没有人认真提出标准“包含所有内容”标头的根本原因。所以有一个合理的说法,称它为“我们不使用它的“ 原因”。
    猜你喜欢
    相关资源
    最近更新 更多