为啥 rand() 编译时不包含 cstdlib 或使用命名空间 std?

Posted

技术标签:

【中文标题】为啥 rand() 编译时不包含 cstdlib 或使用命名空间 std?【英文标题】:Why does rand() compile without including cstdlib or using namespace std?为什么 rand() 编译时不包含 cstdlib 或使用命名空间 std? 【发布时间】:2016-03-10 07:21:02 【问题描述】:

根据我正在阅读的书,rand() 在 C++ 中需要 #include <cstdlib> 但是,我能够在 Visual Studio 2015 中编译以下使用 rand() 而没有 #include <cstdlib>using namespace std; 的代码。 为什么这两个不需要编译?我应该包含 cstdlib 吗?

C++ 代码:

#include <iostream>

int main()

    std::cout << rand() << std::endl;

【问题讨论】:

您可以使用/showIncludes 选项(在“C/C++ | 高级| 显示包含”下的iDE 项目属性中)进行编译,以查看stdlib 是如何被包含的。 @MichaelBurr 我现在看到,Visual Studio 中的输出显示 iostream 包含 cstdlib。有没有办法知道哪些文件被直接包含,哪些被间接包含?我只是好奇 使用/showIncludes 选项的输出缩进级别指示哪个标头包含哪个其他标头。例如,在 VS 2015 更新 1 中,&lt;iostream&gt; 仅直接包含 &lt;istream&gt; - 拉入的所有其他标头都间接包含在 istream 或层次结构更深的标头中。 【参考方案1】:

有两个问题在起作用:

    标准库头文件可能包含其他标准库头文件。所以iostream 可能直接或间接包含cstdlib。 允许具有 C 标准库等效项(例如 cstdlib)的头文件将 C 标准库名称带入全局命名空间,即在 std 命名空间之外(例如 rand。)这是正式的从 C++11 开始就被允许,并且在以前基本上是被容忍的。

【讨论】:

“直接或间接”是什么意思? @JorgeLuque 我的意思是例如iostream 可能包括utility,其中可能包括limits,其中可能包括cstdint,其中可能包括cstdlib【参考方案2】:

iostream 可以直接或间接包含cstdlib。这会将std::rand()::rand() 带入范围。您使用的是后者。

但是,是的,如果你想使用rand,你不应该指望这一点并且总是包括cstdlib。并且在C++ 代码中不要使用rand,有更好的方法来生成随机数。

【讨论】:

::rand()rand() 一样吗?这是否被视为在全局命名空间中? 是的 ::rand() 在您的情况下与 rand 相同。【参考方案3】:

对于您在代码中使用的内容,您绝对应该使用相关的包含文件。当您将编译器/库更新到新版本时,它可以让您免于意外。我认为在rand 前面添加std:: 比使用using namespace std; 更好 - 但无论哪种方式,最好不要依赖它在没有命名空间的情况下存在,尽管这往往是它的方式适用于大多数地方以允许 C 代码向后兼容。

【讨论】:

以上是关于为啥 rand() 编译时不包含 cstdlib 或使用命名空间 std?的主要内容,如果未能解决你的问题,请参考以下文章

rand随机函数

为啥在编译时不检查 lambda 返回类型?

为啥我的 Linux 编译的二进制文件在 Windows 上运行时不起作用?

为啥maven编译时不需要jdbc的驱动包

为啥 Keras (Tensorflow 2.0) 模型在绘制时不包含矩阵乘法的变量?

intellij IDEA为啥运行时不编译grails或groovy了。