为什么 C 可以在没有库的情况下编译 time()?
Why can C compile time() without its library?
当我使用time()
函数(即,只是随机化rand()
的种子)但不包含头文件time.h
时,它适用于 C。例如:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
srand(time(NULL));
for(i=0;i<10;i++){
printf("t%d",rand()%10);
}
printf("n");
return 0;
}
当我尝试编译上面的代码时,g++
无法编译它,因为不包括time.h
。但gcc
可以。
$gcc ra.c
$./a.out
4 5 2 4 8 7 3 8 9 3
$g++ ra.c
ra.c: In function ‘int main()’:
ra.c:8:20: error: ‘time’ was not declared in this scope
srand(time(NULL));
^
它与 gcc 的版本有关还是只是 C/C++ 之间的差异?
您应该包含 time(2) 的<time.h>
并打开警告。在 C 语言中,假定没有可见原型的函数返回int
(自 C99 以来已弃用)。因此,使用gcc
进行编译似乎很好,而g++
则不然。
编译方式:
gcc -Wall -Wextra -std=c99 -pedantic-errors file.c
你会看到gcc
也对此有所抱怨。
C89/C90(通常,但不正确地称为"ANSI C")有一个"隐式int
"规则。如果调用的函数没有可见声明,编译器将有效地创建隐式声明,假设该函数采用调用中出现的类型的参数并返回int
。
time
函数接受类型time_t*
的参数并返回类型为time_t
的值。所以打个电话
time(NULL)
如果没有可见的声明,编译器将生成代码,就好像它接受NULL
类型的参数(可能是int
)并返回int
结果一样。鉴于
srand(time(NULL))
然后,time(NULL)
返回的值将从int
隐式转换为 'unsig
如果int
、time_t
和time_t*
都恰好是32位,那么调用很可能有效。如果它们的大小不同,则可能会表现得很糟糕。(如果NULL
是类型void*
,则void*
和time_t*
虽然它们不兼容,但可能具有相同的表示形式 - 但返回类型仍然可能是个问题。
当然,解决方案是不要那样做。如果使用标准库函数,请始终为声明它的标头提供#include
指令。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在已经使用Git的情况下减少编译时间
- 模板方法访问正向声明的类仅在没有此指针的情况下无法编译
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- 如何在不需要LIBCD.lib的情况下在Visual Studio 6中编译C项目
- 我可以在不使用Qt for Webassembly的情况下使用Emscripten编译Qt吗?
- C++项目编译强制使用 /clr 选项,尽管在没有公共语言运行时支持的情况下执行它
- 我可以在不创建项目的情况下在Visual Studio 2019中编译和运行HelloWorld.cpp吗?
- C++11 - 获取编译时的所有类变量,并在没有 Boost 的情况下为它们调用方法
- 在我的 CLR 项目中添加包含会导致无法在启用 /clr 的情况下编译 WLR
- 如何在没有Cygwin或Visual Studio的情况下编译Magick++?
- 在哪种情况下,C++会在编译时进行数组边界检查?
- 如何在不制作Visual Studio 2017项目的情况下编译C++文件?
- 如何减少编译时间:在包含未触及的头文件的情况下
- 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此大括号初始化列表代码
- 如何在不退出和失去断点的情况下重新加载重新编译的二进制文件
- 在没有 -g 选项的情况下编译,但我想获得更详细的调试信息
- 在没有 AVX 的情况下编译提升
- 如何在Ubuntu中不加编译器硬化的情况下编译宝石
- 即使我传递了无效的类型参数,我为什么还能在没有错误的情况下编译此代码