【问题标题】:Why does gcc report "implicit declaration of function ‘round’"?为什么 gcc 报告“函数‘round’的隐式声明”?
【发布时间】:2009-11-23 15:21:27
【问题描述】:

我有以下 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 上的 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);

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

【问题讨论】:

    标签: c gcc compiler-warnings


    【解决方案1】:

    我看到你在使用 gcc。

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

    gcc -std=c99 -pedantic ...
    

    引用GCC Manual

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

    【讨论】:

    • 谢谢,-std=c99 似乎解决了它。我没有意识到 round() 是 C99 的补充(当然,我所有的参考文献都是 C99 并且忽略了这一点)
    • (惊讶的样子)round() 真的是 C99 的加法吗?
    • 对,C89 没有描述round() 函数(当然编译器可以将它作为扩展提供)。
    • 看起来像 - 来自 Ubuntu 8.04 联机帮助页 - round()、roundf()、roundl():_XOPEN_SOURCE >= 600 || _ISOC99_SOURCE;或 cc -std=c99
    • 还需要-lm链接libm才能得到实际的功能。
    【解决方案2】:

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

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

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

    【讨论】:

    • 我使用的是 Ubuntu 9.10 (Karmic)。这里 #include &lt;math.h&gt; 加载 /usr/include/math.h 加载 /usr/include/bits/mathcalls.h 包含声明。
    【解决方案3】:

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

    gcc -std=c99 -lm round_test.c
    

    【讨论】:

      【解决方案4】:

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

      你在你的机器上查看过&lt;math.h&gt;吗?

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 默认模式是-std=gnu89 :)
        【解决方案6】:

        您需要链接到数学库。所以编译的时候一定要加上-lm标志。

        【讨论】:

        • 感谢您的输入,但这是编译问题,而不是链接问题。我意识到我遗漏了我的编译器命令(我的错),但我正在使用 gcc -c 进行编译。
        猜你喜欢
        • 1970-01-01
        • 2020-07-28
        • 2019-09-17
        • 2019-10-13
        • 1970-01-01
        • 2013-11-27
        • 1970-01-01
        • 2012-01-16
        相关资源
        最近更新 更多