2009-11-23 81 views
8

我有以下的C代码:为什么gcc报告“函数的隐式声明”round'“?

#include <math.h> 

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

    return (int) whatever; 
} 

当我编译,我得到了警告:

round_test.c: In function ‘main’: 
round_test.c:6: warning: implicit declaration of function ‘round’ 
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’ 

我生疏C,但我认为的#include带来的声明对于round()进入范围。我检查了我的ANSI标准(C99是我唯一的副本),它证实了round()函数存在于math.h头文件中。我在这里错过了什么?

编辑:编译器是Ubuntu上的GCC 4.3.2(intrepid,IIRC)。运行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); 

所以在头文件中显然没有找到定义。

回答

17

我看到你使用的是gcc。

默认情况下,gcc使用类似于C89的标准。您可能要“逼”它使用C99标准

gcc -std=c99 -pedantic ... 

报价从GCC Manual

默认情况下(它遵循的部件),GCC提供了一些 扩展的C语言上极少出现与标准C 冲突的情况。请参阅C 语言族的扩展。使用上面列出的-std 选项将禁用 这些扩展,它们与选择的C标准版本冲突 。 您也可以选择具有-std = gnu89(对于带有GNU 扩展的C89)或-std = gnu99(对于具有GNU扩展的C99 )的扩展 版本的C语言显式地 。默认,如果 没有C语言方言选项 给出,是-std = gnu89;当C99支持完成时,在将来的某些版本 中,这会将 更改为-std = gnu99。作为C99 标准一部分的一些功能被接受为 C89模式的扩展。

+1

谢谢,-std = c99似乎解决了它。我没有意识到round()是C99的补充(当然,我所有的参考都是C99,而忽略了这一点) – 2009-11-23 15:32:55

+0

(惊讶的样子)round()真的是C99的补充吗? – 2009-11-23 15:43:56

+0

对,C89没有描述'round()'函数(当然编译器可以提供它作为扩展)。 – pmg 2009-11-23 15:50:48

3

你的gcc安装,系统头文件或编译选项必须有错误。

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

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

我在Ubuntu 9.10(Karmic)。这里'#include '加载/usr/include/math.h加载包含声明的/usr/include/bits/mathcalls.h。 – 2009-11-23 15:41:30

0

您输入的代码在MacOS X 10.5.8上用GCC 4.0.1编译干净。如果用选项'-Wall -Wextra'激励,它会抱怨未使用的参数argc和argv - 不重要。

你在机器上看过<math.h>吗?

您是否尝试过使用'-stc = c99'等选项?

3

你需要告诉你想要C99 GCC,而且要在libm中链接:

gcc -std=c99 -lm round_test.c 
-2

你需要用数学库链接。所以当你编译时,一定要添加-lm标志。

+1

感谢您的输入,但这是一个编译问题,而不是链接问题。我意识到我遗漏了我的编译器命令(我的坏),但我正在用gcc -c编译。 – 2009-11-23 15:57:23

0

C99是答案,但整个故事稍微复杂一点。我一直在玩这个游戏的原因是,我试图编译一个为Windows编写的库,它有自己的round()的“优化”定义。我得到一个链接器错误告诉我,定义与内置冲突,所以我删除了定义(和声明)。一旦我做完了,我开始得到“隐式声明错误”。

似乎默认的编译模式(没有-std = c99标志)既不符合C89也不符合C99:如果它符合C89,则应该能够提供round()的自定义定义而不会发生冲突,并且如果它符合C99的声明应该在math.h中。

+1

默认模式是'-std = gnu89' :) – pmg 2009-11-23 15:56:47

相关问题