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 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 (intrepid, IIRC) 上的 GCC 4.3.2。运行 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);

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

4

6 回答 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。作为 C99 标准一部分的某些功能在 C89 模式中被接受为扩展。

于 2009-11-23T15:27:26.600 回答
3

您的 gcc 安装、系统头文件或编译选项一定有问题。

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

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__));
于 2009-11-23T15:26:01.923 回答
3

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

gcc -std=c99 -lm round_test.c
于 2009-11-23T15:29:12.307 回答
0

您键入的代码可以在带有 GCC 4.0.1 的 MacOS X 10.5.8 上干净地编译。如果使用选项“-Wall -Wextra”进行刺激,它会抱怨未使用的参数 argc 和 argv - 不重要。

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

您是否尝试过诸如“-stc=c99”之类的选项?

于 2009-11-23T15:27:25.073 回答
0

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

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

于 2009-11-23T15:55:16.217 回答
-2

您需要与数学库链接。所以编译的时候一定要加上-lmflag。

于 2009-11-23T15:33:00.660 回答