可能重复:
Why can’t gcc find the random() interface when -std=c99 is set?
我是C的新手,所以我刚进入man stdlib.h
,搜索“随机”,看到random()
返回long
,因为这只是一次学习练习,以为我只是转换为int(而不是费心去查找返回int
- rand()
的那个)。
无论如何,程序编译并正确运行。但是:
$ gcc -std=c99 part1.c
part1.c: In function 'main':
part1.c:44:5: warning: implicit declaration of function 'random'
如果删除-std=99
标志,它就会消失。这是“违规”代码:
int test6[1000];
for(i = 0; i < 1000; i++)
{
test6[i] = (int) random();
printf("it is %d\n", test6[i]); //check random() is working (it isn't seeded)
}
printf("%d\n", largest(test6, 1000));
所以我只是想知道是否有人知道这是为什么,因为我认为这可能很有趣。
答案 0 :(得分:6)
您收到warning: implicit function definition
消息,因为在使用函数random()
之前未声明该函数。它不是标准的C函数(不在ISO / IEC 9899:2011或其前身版本中)。你需要知道哪个头声明了它;你可能需要#define
才能使声明可见。
在C99中,你必须在使用之前声明所有功能;这就是-std=c99
模式对象(尽管已经发出强制诊断,它可以继续编译,可能会使函数返回int
的向后兼容假设)的原因。在旧版本的C中,您不必预先声明函数;未声明的函数被隐式声明为extern int function();
,这意味着'具有未指定(但不是可变)参数列表的函数返回int
'。这就是编译继续做出这种假设的原因;它曾经是标准的假设。使用C99和C2011,这是正式的错误。
我的困惑是程序仍然可以正常编译和运行(
random()
也会返回伪随机数)!我在文件顶部有#include <stdlib.h>
。我的#include
可能无法正常工作,但是make
正在做一些聪明的事情来找出它的位置吗?另一件事(我忘了提问),我认为,当我将演员表移到int
时,警告最初消失了。我不能复制它,所以我想必须有一些其他的解释。也许我不小心从-std=c99
或其他东西中删除了makefile
。
我说'标准C没有定义它';它没有,但POSIX确实如此。因此,通过包含正确的标头(<stdlib.h>
),并确保看到声明,该函数从C库中获取(它不是纯粹的标准C库,而是包含很多POSIX的功能,以及GLIBC特有的许多其他功能。因此,它起作用,因为库包含该函数。您可能希望/需要使用-std=gnu99
进行编译或指定#define _XOPEN_SOURCE 700
或#define _POSIX_C_SOURCE 200809L
或类似的内容(在包含任何系统标头之前)以在random()
下显示-std=c99
的声明{1}}。我使用标题posixver.h
将信息输入我的程序。
/*
@(#)File: $RCSfile: posixver.h,v $
@(#)Version: $Revision: 1.1 $
@(#)Last changed: $Date: 2010/08/29 00:27:48 $
@(#)Purpose: Request appropriate POSIX and X/Open Support
@(#)Author: J Leffler
*/
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2001 support. With
** C89 support only, it requests POSIX 1997 support. Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/
/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600 /* SUS v3, POSIX 1003.1 2004 (POSIX 2001 + Corrigenda) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
#endif /* JLSS_ID_POSIXVER_H */
这是相当保守的,并没有请求POSIX 2008支持,因为我工作的一些机器没有那个 - 仍然!你可以使用它作为你的版本的基础,如果你愿意,可以更积极。我曾经直接在程序中使用了这个节,但是当安全地更改为POSIX 2008时,这就变成了一个噩梦(并且在许多源文件中明智地维护这些注释本来就很愚蠢 - 因此文件通常只包含{ {1}}只有极少或没有评论,但在变革的时候它仍然是一个改变的小提琴。)