源代码在没有正确#include 的情况下编译

source is compiled without proper #include

我有一个非常简单的 C++ 源代码,如下所示:

#include <iostream>
int main() {
    srand(time(NULL));
}

我正在使用 g++ 编译,如下所示:

g++ ./test.cpp

但它成功编译,尽管 time() 函数在 ctime 中定义并且它不包含在 #include

我的大学教授 运行 使用 visual studio (vc++) 编写代码,但他无法 运行 不包含 ctime 的代码]

我是不是遗漏了什么?

顺便说一句,我的 g++ 版本是:

g++ (Ubuntu 11.2.0-7ubuntu2) 11.2.0

首先,在我的平台上,当我删除#include <iostream>没有编译成功 我正在使用 WSL2 ubuntu 20.04,我使用的编译器是 g++ 和 clang++。
无论是哪个编译器,它都会给出错误:

>>> g++ t.cpp
t.cpp: In function ‘int main()’:
t.cpp:2:16: error: ‘NULL’ was not declared in this scope
    2 |     srand(time(NULL));
      |                ^~~~
t.cpp:1:1: note: ‘NULL’ is defined in header ‘<cstddef>’; did you forget to ‘#include <cstddef>’?
  +++ |+#include <cstddef>
    1 | int main() {
t.cpp:2:11: error: ‘time’ was not declared in this scope
    2 |     srand(time(NULL));
      |           ^~~~
t.cpp:2:5: error: ‘srand’ was not declared in this scope
    2 |     srand(time(NULL));
      |     ^~~~~
>>>clang t.cpp
t.cpp:2:16: error: use of undeclared identifier 'NULL'
    srand(time(NULL));
               ^
1 error generated.

我想你可以使用编译选项-E来提示编译器只做预处理并查看预处理后的文件。
像这样:
g++ t.cpp -E -o pre_proccessed.cpp 确定编译器在编译过程中是否做了你怀疑它做了的事情,“自动包含文件”

但是,当我添加 #include <iostream> 它确实成功了。
所以,我这样做了:

>>>g++ t.cpp -E  -o t_.cpp
>>>cat t_.cpp | grep srand
extern void srandom (unsigned int __seed) throw ();
extern int srandom_r (unsigned int __seed, struct random_data *__buf)
extern void srand (unsigned int __seed) throw ();
extern void srand48 (long int __seedval) throw ();
extern int srand48_r (long int __seedval, struct drand48_data *__buffer)
  using ::srand;

这就解释了为什么它编译成功了,因为这个平台包含的iostream文件里面有这个函数的定义。
另外,看看这个problam

其实stl是允许互相包含的
但是即使它在这个头文件中定义,你也不能依赖它,某些版本的 iostream 实现不包括这个。

你应该做的是在使用srand的时候主动包含cstdlib文件,不用担心多重包含问题,std,stl本身可以很好的处理多重包含,并且现代编译器也可以很好地处理这个问题。

首先明确包含你需要的东西,
(感谢 darkblueflow 指出)
其次 #include 订单很重要,

信不信由你,他们可以影子声明, 如果第一种情况不起作用就切换

#include <cstdlib>
#include <ctime>

// differs from

#include <ctime>
#include <cstdlib>

// in some aspects

你最好的办法是明确地包含 headers 记住这一点 this 祝你好运