【问题标题】:Adding/Removing headers has no effect添加/删除标题无效
【发布时间】:2022-01-05 07:18:06
【问题描述】:

我在我的代码中使用了std::invalid_argument 异常类。所以我还在预编译的头文件中包含了头文件<exception>(在我的例子中是pch.h)。但后来我从 pch.h 中删除了<exception>,代码在 GCC 11.2 上成功编译,我很惊讶。

这里有一些例子:

#include <exception> // removing this does not have any effects
#include <array> // the same here
.
.
.
throw std::invalid_argument( exceptionMsg ); // somewhere in the code
.                                            // how does this work?
.
.
std::array<int, 4> buffer { }; // somewhere in the code
.                              // how does array work without #include <array> ??
.
.

同样,我从 pch.h 中删除了&lt;iterator&gt;&lt;array&gt;&lt;cstring&gt; 等,但仍然没有问题。这怎么可能?

因此,如果在编译代码时包含标头没有帮助,那么它们的目的是什么?如果编译器不抱怨,删除这些#includes 是否安全?

【问题讨论】:

  • 标准标头可能包括其他标准标头,这取决于实现。始终包含必要的标题。此外,您可能会遇到重建问题,请在测试之间尝试完全清洁。我们希望看到minimal reproducible example,这样我们就可以自己检查任何问题。你如何在 GCC 中使用预编译头文件,文件名 pch.h 在 MSVC 中通常用于预编译头文件?
  • 仅供参考,std::invalid_argument&lt;stdexcept&gt; 中定义,而不是&lt;exception&gt;
  • 如果您对标头感到困惑,首先要做的是摆脱pch.h。它不是真正的标题,它可以做可恶的事情。从来没有必要。它用于在某些情况下加快编译速度。如果你不知道它为什么会出现,那就摆脱它。
  • @Pete Becker 我使用它的原因与您提到的相同。另一个人告诉我,我必须检查我在代码中使用的所有标识符,然后根据它们添加必要的标头,我做到了。希望以后不会造成太大的麻烦。

标签: c++ stl header-files precompiled-headers


【解决方案1】:

但后来我从 pch.h 中删除,代码在 GCC 11.2 上成功编译,我很惊讶。

这并不罕见。你会习惯的。

这怎么可能?

当您仍然包含的标头之一碰巧还包含您未直接包含的标头时,可能会发生这种情况。

如果编译器不抱怨,删除这些#include 是否安全?

没有。不直接包含您所依赖的标头是不安全的。当一个标头停止包含另一个标头时,该标头可能最终根本不包含在内,如果您依赖该标头,那么您的程序将停止编译。为避免这种情况发生,请始终直接包含您依赖的所有标头。

【讨论】:

  • 有什么方法可以检查我是否包含了所有必要的标题?还是比这更复杂?
  • @digito_evo 通读您使用的所有标识符,检查文档以了解其声明/定义的位置,并检查您是否已包含该标识符。步骤很简单,但除非你能记住很多标识符,否则工作量很大。
  • 我明白了。我的另一个问题是,C++20 中的 modules 解决了这些问题吗?
  • @digito_evo 模块应该可以避免这个问题。但在你使用的所有东西都被模块化之前,它不会解决任何问题。而且由于标准库在 C++20 中不是模块化的,特别是没有得到解决。
  • 那是可悲的。我希望他们在 C++23 出来之前完全实现它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多