从random()到int的转换结果导致GCC说"警告:隐式函数定义".为什么?

Bre*_*dan 2 c gcc c99 gcc-warning

可能重复:
为什么在设置-std = c99时gcc不能找到random()接口?

我是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'
Run Code Online (Sandbox Code Playgroud)

如果我移除-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));
Run Code Online (Sandbox Code Playgroud)

所以我只是想知道是否有人知道这是为什么,因为我认为这可能很有趣.

Jon*_*ler 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=c99makefile某物中删除了.

我说'标准C没有定义它'; 它没有,但POSIX确实如此.因此,通过包含正确的标题(即<stdlib.h>),并通过确保看到声明,该函数从C库中获取(它不是纯粹的标准C库,而是包含许多POSIX函数,以及GLIBC特有的许多其他功能.因此,它起作用,因为库包含该函数.您可能希望/需要编译-std=gnu99或指定#define _XOPEN_SOURCE 700#define _POSIX_C_SOURCE 200809L类似的东西(在包含任何系统头之前)以获得random()可见的声明-std=c99.我使用标题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 */
Run Code Online (Sandbox Code Playgroud)

这是相当保守的,并没有请求POSIX 2008支持,因为我工作的一些机器没有那个 - 仍然!你可以使用它作为你的版本的基础,如果你愿意,可以更积极.我曾经有过直接在程序节,而是变成了一场噩梦修复时,它是安全的改变到2008年POSIX(在许多源文件理智地保持了意见本来是太傻了-这样的文件通常只包含#define _XOPEN_SOURCE 600与最小或没有评论,但是当变化的时候它仍然是一个改变的小提琴).