源代码在没有正确#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
祝你好运
我有一个非常简单的 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 祝你好运