为什么gcc会报告“隐式声明函数'round'”?

9
我有以下的C代码:
#include <math.h>

int main(int argc, char ** argv)
{
    double mydouble = 100.0;
    double whatever = round(mydouble);

    return (int) whatever;
}

当我编译这个程序时,我收到以下警告:
round_test.c: In functionmain’:
round_test.c:6: warning: implicit declaration of functionround
round_test.c:6: warning: incompatible implicit declaration of built-in functionround

我对C语言有点生疏,但我认为#include将round()的声明引入了作用域。我已经查过了我的ANSI标准(我只有C99的副本),它证实round()函数存在于math.h头文件中。我错过了什么吗?
编辑:编译器是Ubuntu上的GCC 4.3.2(intrepid,如果我没记错)。运行gcc -E命令会显示:
$ gcc -E round_test.c | grep round
# 1 "round_test.c"
# 1 "round_test.c"
# 2 "round_test.c" 2
    double whatever = round(mydouble);

所以很明显在头部找不到定义。
6个回答

17

我看到你在使用gcc。

默认情况下,gcc使用类似于C89的标准。你可能想要“强制”它使用C99标准(它符合的部分)。

gcc -std=c99 -pedantic ...

引用自GCC手册

默认情况下,GCC提供了一些C语言扩展,但在极少数情况下会与C标准冲突。请参见扩展到C语言系列。使用上述列出的-std选项将禁用这些扩展,其中它们与所选的C标准版本冲突。您还可以使用-std = gnu89(对于带有GNU扩展的C89)或-std = gnu99(对于带有GNU扩展的C99)显式选择扩展版本的C语言。如果没有给出任何C语言方言选项,则默认值为-std = gnu89;当C99支持完整时,这将更改为-std = gnu99。在C89模式下,接受C99标准的某些功能作为扩展。


1
谢谢,-std=c99 似乎解决了这个问题。我没有意识到 round() 是 C99 的新增功能(当然,我的所有参考资料都是 C99 的,却忽略了这一点)。 - Tim Martin
没错,C89没有描述round()函数(当然编译器可以作为扩展提供它)。 - pmg
1
看起来是这样的 - 来自Ubuntu 8.04手册 - round(), roundf(), roundl(): _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE; 或者 cc -std=c99 - Douglas Leeder
2
还需要使用-lm来链接libm以获取实际函数。 - Douglas Leeder
@Tim:如果你想要C89标准的纯文本版本,请查看http://flash-gordon.me.uk/ansi.c.txt。 - pmg
显示剩余2条评论

3

你的gcc安装、系统头文件或编译选项可能存在问题。

尝试使用-E编译选项。它将显示预处理器输出,包括哪些头文件被包含以及其中包含的内容。在我的Ubuntu Linux系统上,它大约有1000行输出,其中包括以下内容:

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__));

我正在使用Ubuntu 9.10(Karmic)。在这里#include <math.h>加载了/usr/include/math.h,它又加载了/usr/include/bits/mathcalls.h,其中包含声明。 - Jason Orendorff

3

您需要告诉gcc您想要使用C99,并且您想要链接libm:

gcc -std=c99 -lm round_test.c

0

您输入的代码在MacOS X 10.5.8上使用GCC 4.0.1编译干净。如果使用“-Wall -Wextra”选项进行编译,则会抱怨未使用的参数argc和argv-这不是问题。

您是否查看了您机器上的<math.h>

您尝试过使用“-stc=c99”等选项吗?


0
C99是答案,但完整的故事要複雜一些。我玩這個的原因是嘗試編譯一個為Windows寫的函式庫,它有自己"優化"版round()的定義。我得到了連結錯誤告訴我定義與內建的衝突,所以我刪除了定義(和聲明)。一旦我這樣做了,我就開始收到"隱含聲明錯誤"

看來默認的編譯模式(不帶-std=c99標記)既不符合C89也不符合C99:如果它符合C89,你應該能夠提供一個自定義round()的定義而不發生衝突;如果它符合C99,則聲明應該在math.h中。


2
默认模式是-std=gnu89 :) - pmg

-2

你需要链接数学库。因此,在编译时,请确保添加-lm标志。


1
谢谢你的输入,但这是一个编译问题,而不是链接问题。我意识到我漏掉了编译器命令(我的错),但我正在使用gcc -c编译。 - Tim Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接