random() 是什么时候在 C 语言中引入的,为什么标准 89 无法识别它?

When was random() introduced in C and why does standard 89 not recognise it?

提问人:rith 提问时间:12/1/2022 更新时间:12/1/2022 访问量:102

问:

我正在做一个操作系统项目,要求是使用 C89 和迂腐的标志。

由于我在 macOS 上,因此在一些练习中,我遇到了相当多的功能问题。事实上,它的 macOS 手册页称其为“坏数字生成器”。因此,为了避免出现问题,我已改用 .现在,由于我正在使用 、 和 进行编译,因此由于有关于 的隐式声明的警告,它拒绝正常运行。如果我删除 ,它确实会生成警告,但它会编译(如预期的那样),但更有趣的是,它工作得很好。它按预期生成一个数字。我做错了什么?C89支持与否?我应该包括什么才能使警告消失?手册页只提及了哪些内容。rand()random()-std=c89-pedanticwallwerrorrandom()werrorrandomstdlib.h

手册页中提到的一个可行的替代方案是,但是我很确定它不存在跨平台。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
C 随机 STD C89

评论

0赞 Adrian Mole 12/1/2022
random并且不是 C 标准的一部分,尽管它们(我认为)在 POSIX 标准中。请尝试改用 和 (标准 C 函数)。srandomrandsrand

答:

4赞 P.P 12/1/2022 #1

两者都不是 C 标准的一部分。它们是 POSIX 函数,所以编译 with 在编译时不会提供他们的原型。randomsrandom-std=c89

您可以在源文件的顶部定义以下内容之一,以使其原型可用:

#define _DEFAULT_SOURCE

#define _XOPEN_SOURCE 600

这将启用 POSIX 以及其他扩展。有关这些宏的详细信息,请查看功能测试宏

评论

0赞 rith 12/1/2022
谢谢!这样就解决了。由于我还需要为_GNU_SOURCE添加定义,因此它们是否相互冲突?
2赞 P.P 12/1/2022
没有这样的冲突。 将启用与这两者中的任何一个相同的功能以及更多功能。因此,如果您要使用它,那么您将不需要其中任何一个。_GNU_SOURCE
1赞 Lundin 12/1/2022 #2

C89 是否支持随机?

事实并非如此。

现在,由于我正在使用 -std=c89、-pedantic、wall 和 werror 进行编译,因此由于有关于 random() 隐式声明的警告,它拒绝正常运行。

这是因为当您进入严格符合模式时,编译器将不允许将非标准函数放在标准库中的极其愚蠢的做法。如公认的答案中所述 是否允许编译器将函数添加到标准标头? 一个符合要求的实现不允许喷出可能与应用程序冲突的标识符(“影响严格符合要求的程序的行为”)。

问题的根源是POSIX,这是一个与ISO 9899不协调的破碎标准。

评论

0赞 supercat 1/12/2023
哪个先来:POSIX 还是 C89?如果 POSIX 包含 C89 中不存在的函数,那是谁的错?
0赞 Lundin 1/12/2023
@supercat 您的意思是 POSIX 自 1988 年以来一直没有得到维护,甚至没有将 ISO 9899 列为规范参考?要么是 34 年没有维护的可怕废话,要么是无视自己列出的规范参考的可怕废话。是哪一种废话?
0赞 supercat 1/13/2023
在POSIX之后发布的C89标准意味着,符合C的实现应该与现有的POSIX程序不兼容。有可能使C标准允许POSIX兼容,但不可能以与现有POSIX程序兼容的方式修改POSIX标准,并且标准禁止这种兼容性的意图。此外,许多设计精良的东西基本上可以无限期地达到其预期目的,而不需要破坏兼容性的更新。即使需要更新版本的 POSIX......
0赞 supercat 1/13/2023
...要完成 1988 年无法想象的事情,这并不意味着不需要做 1988 年标准中没有规定的任何事情的程序不应该在旧版本或新版本的标准下同样出色地工作。如果将定义行为和 UB 之间的转换视为中断性变更,那么 C 标准中充斥着无端的中断性变更。
0赞 supercat 1/13/2023
如果 C89 标准规定,实现的行为可能与定义了其他非保留形式的符号一样,除非在预处理器宏以 1 到 89 范围内的整数定义的情况下,并且没有采取任何其他措施来邀请此类定义,这将避免破坏现有实现上的任何现有程序,同时仍然允许程序员编写可以保证没有符号冲突的程序。__STDC_NO_SYMBOLS_BEYOND