代码之家  ›  专栏  ›  技术社区  ›  mahdiolfat

为什么“函数的隐式声明”只是一个警告?

  •  6
  • mahdiolfat  · 技术社区  · 9 年前

    这不是一个关于如何解决C程序中出现的“函数隐式声明”警告的问题 answered 已经很多次了。

    我知道这是一个编译器警告,我想知道的是为什么这是警告而不是错误?如果编译器看不到函数,那么在运行时调用函数时会发生什么?链接器最终解决了这个问题吗?或者我们应该假设调用产生此类警告的函数的行为是未知的吗?

    3 回复  |  直到 8 年前
        1
  •  4
  •   alexanius    9 年前

    为什么这是警告而不是错误?

    因为有很多遗留代码是这样编写的。编译器错误将破坏它。

    如果编译器看不到函数,那么在运行时调用函数时会发生什么?链接器最终解决了这个问题吗?

    让我们看看这个例子:

    int main()
    {
        foo();
        return 0;
    }
    

    在工作时,编译器生成自己的函数签名,如 int foo(...) 并将使用它。顺便说一下,它可能会导致非常奇怪的错误。因此,对象文件将包含此函数的调用,这是正常的。当您尝试链接它时,您将得到一个错误:未定义对“foo”的引用。但是如果你有另一个模块 foo 定义时,链接器将按名称查找并链接它。

    产生这样的警告是未知的吗?

    正如我所说,这可能会导致一些奇怪的错误。假设您有如下代码 int i = foo() 没有签名。在另一个模块中,您有以下内容: int * foo(){...} 。在64位模式下构建应用程序时,您将 i 64位指针中只有32位。因此,您可能会说,实际上您的程序的行为可能是未知的。

        2
  •  2
  •   R.. GitHub STOP HELPING ICE    9 年前

    因为主流编译器继承了有害的传统,包括您正在使用的传统。谢天谢地,他们通常可以选择使其成为错误,比如 -Werror=implicit-function-declaration 用于gcc和兼容编译器。

        3
  •  0
  •   John Bode    9 年前

    该标准对诊断实施的要求很少:



    9)
    9) 其目的是,实现应该识别每个违反的性质,并在可能的情况下对其进行本地化。当然,只要有效的程序仍然被正确翻译,实现就可以自由地生成任意数量的诊断。它还可以成功转换无效程序。