为什么gcc报告“隐含的函数声明’轮”?

我有以下C代码:

#include  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是我唯一的副本),它确认了math.h标头中存在round()函数。 我在这里想念的是什么?

编辑:编译器是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); 

所以这个定义显然没有在标题中找到。

我看到你正在使用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。 作为C99标准一部分的某些function在C89模式下被接受为扩展。

gcc安装,系统头文件或编译选项必定存在问题。

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

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

你需要告诉gcc你想要C99,并且想要在libm中链接:

 gcc -std=c99 -lm round_test.c 

您键入的代码使用GCC 4.0.1在MacOS X 10.5.8上完全编译。 如果使用选项’-Wall -Wextra’进行刺激,它会抱怨未使用的参数argc和argv – 不是材料。

你在机器上看过了吗?

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

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

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

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