【问题标题】:Why clang on Mac automatically includes some missing headers?为什么 Mac 上的 clang 会自动包含一些缺失的标头?
【发布时间】:2017-04-10 17:09:54
【问题描述】:

我注意到 clang++ 包含一个缺失的标头 - Mac 上的 <limits>,而 g++ 在 Linux 上显示有关它的错误。现在我想知道为什么 clang 会这样做,而 gcc 不会。以及如何强制 clang 不这样做。

这是一个示例代码,它在 Mac 上由 clang 编译,但在 Linux 上不是由 gcc 编译:

#include <iostream>
using namespace std;

int main()
{
    cout << "int max: " << numeric_limits<int>::max() << endl;
}

UPD

我查看了图书馆,这就是我发现的。

&lt;iostream&gt; 内部包含&lt;istream&gt;,它为不同类型定义了&gt;&gt; 运算符。 &lt;istream&gt; 想知道 shortintstreamsize 类型的限制。

clang++ 使用 libc++ 标准库,该库使用来自&lt;limits&gt; 中的&lt;istream&gt; 中的std::numeric_limits 类模板用于此目的。这就是包含&lt;iostream&gt; 时自动包含此标头的原因。

g++ 使用 libstdc++ 标准库,它使用来自&lt;ext/numeric_traits.h&gt;__gnu_cxx::__numeric_traits 类模板,而不是在&lt;istream&gt; (&lt;bits/istream.tcc&gt;) 中使用&lt;limits&gt;。该标题中还有一条注释解释了为什么他们不使用&lt;limits&gt;

&lt;limits&gt; 很大,我们避免包含它

使用的编译器:

> clang++ --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)

$ g++ --version
g++ (Debian 4.9.2-10) 4.9.2

【问题讨论】:

    标签: c++ gcc include clang


    【解决方案1】:

    在 C++ 中,与 C 不同,标准头文件允许#include 其他标准头文件。这有时会导致像您所看到的那样的神秘错误:一个编译器的 &lt;iostream&gt; 包含 &lt;limits&gt; 而另一个不包含。解决方案是始终包含您使用的任何名称所需的标题。在这种情况下,这意味着在您的代码中使用#include &lt;limits&gt;,即使它可以像使用一个编译器一样编译。 #include 已经被拉入的标头没有任何害处,因此两个编译器都可以。有时很烦人,但事情就是这样。

    【讨论】:

    【解决方案2】:

    clang 版本的 &lt;iostream&gt; 标头可能是 #includes &lt;limits&gt; 标头,因此您会自动将其作为 #includeing &lt;iostream&gt; 标头的一部分。

    对此你无能为力。这就是编译器库的实现方式。你可以简单地添加

    #include <limits>
    

    到这个文件,它应该在两个平台上编译。

    【讨论】:

    • Sam Varshavchik,只是想让您知道,您的回答很有帮助,我投了 ++ 票,而不是 --。谢谢你的提示。
    猜你喜欢
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多