C语言random()函数引入时间及C89不识别的原因与解决
关于C89下random()函数的使用问题
问题1:random()何时引入C语言,为何C89标准不识别它?
random()并非C标准库函数,它是POSIX标准定义的函数,并未纳入C89标准规范,因此C89不识别该函数。
实际开发问题
我正在开发要求使用C89标准和-pedantic编译选项的操作系统项目,当前使用macOS系统。练习中发现rand()存在诸多问题,其macOS手册称它为“bad number generator”,因此改用random()函数。但用-std=c89、-pedantic、-Wall和-Werror编译时,编译器因random()和srandom()的隐式声明报错;移除-Werror后,虽有警告但可正常编译运行,能生成预期随机数。我已包含stdlib.h仍出警告,想知道C89是否支持random()及如何消除警告。另外,手册提到的替代方案arc4random()不具备跨平台性。
测试代码
#include <stdio.h> #include <stdlib.h> int main() { int test; srandom(5); test = random() % 190; printf("Hello World %d\n", test); return 0; }
编译输出
main.c:15:5: warning: implicit declaration of function ‘srandom’; did you mean ‘srand’? [-Wimplicit-function-declaration] 15 | srandom(5); | ^~~~~~~ | srand main.c:17:12: warning: implicit declaration of function ‘random’; did you mean ‘rand’? [-Wimplicit-function-declaration] 17 | test = random() % 190; | ^~~~~~ | rand Hello World 115
解答
1. C89支持random()吗?
不支持。random()和srandom()是POSIX标准定义的函数,压根没被纳入C89(或者任何版本的C标准)的标准库。C标准里规定的随机数函数只有rand()和srand(),这就是为啥你包含了stdlib.h还会出隐式声明警告——C89的stdlib.h里根本没有这两个函数的声明。
2. 怎么消除警告(还要保留C89和-pedantic选项)?
想在C89编译模式下用POSIX函数又不触发警告,你得这么做:
- 定义POSIX相关宏,让头文件把
random()和srandom()的声明暴露出来。在macOS上,编译的时候加上-D_POSIX_C_SOURCE=199309L(或者更早的兼容版本,比如199009L),或者-D_XOPEN_SOURCE=500这类宏,这样stdlib.h就会包含POSIX扩展的函数声明了。 - 编译命令里继续保留
-std=c89和-pedantic就行,只要宏定义对了,-pedantic不会再针对这些POSIX函数报错。
举个例子,修改后的编译命令:
gcc -std=c89 -pedantic -Wall -Werror -D_POSIX_C_SOURCE=199309L main.c -o main
额外说明
- 这种方法能保证代码在POSIX兼容系统上的可移植性,但如果你的项目要跑在非POSIX系统(比如Windows)上,这个方案就不好使了——这时候要么忍了
rand()的缺点,要么自己写一个符合C89标准的高质量随机数生成器。 arc4random()是BSD和macOS独有的函数,确实没跨平台性,不适合你的项目需求。
内容的提问来源于stack exchange,提问作者rith
相关产品推荐
相关产品推荐

