这不是关于如何解决"隐含的函数声明的问题" C程序中出现的警告,已经多次answered次。
我知道这是一个编译器警告,我想知道为什么这是警告而不是错误?如果编译器无法看到该函数,那么在运行时调用该函数会发生什么?链接器最终是否解决了这个问题?或者我们是否假设调用产生此类警告的函数的行为未知?
答案 0 :(得分:2)
为什么这是警告而不是错误?
因为有很多遗留代码是以这种方式编写的。编译器错误会破坏它。
如果编译器无法看到该函数,那么在运行时调用该函数会发生什么?链接器最终是否解决了这个问题?
让我们看一下这个例子:
int main()
{
foo();
return 0;
}
在工作时,编译器会生成自己的函数签名,如int foo(...)
,并将使用它。顺便说一句,它可以导致非常奇怪的错误。所以目标文件将包含这个函数的调用,它没问题。当您尝试链接它时,您将收到一个错误:未定义的引用`foo'。但是如果你有另一个带有foo
定义的模块,链接器将按名称找到它并链接它。
或者我们要假设调用一个函数的行为 产生这样的警告是未知的?
正如我所说,它可能导致一些奇怪的错误。想象一下,您有int i = foo()
和foo
之类的代码没有签名。在另一个模块中,您有以下内容:int * foo(){...}
。在64位模式下构建应用程序时,只会将i
的64位指针置为32位。所以你可能会说你的程序的行为可能是未知的。
答案 1 :(得分:0)
由于主流编译器带来的有害传统,包括你正在使用的传统。值得庆幸的是,他们通常可以选择使其成为错误,例如gcc和兼容编译器的-Werror=implicit-function-declaration
。
答案 2 :(得分:-1)
该标准对诊断实施的要求非常少:
5.1.1.3诊断
1如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现-defined。在其他情况下不需要产生诊断信息。 9) 9)意图是实施应确定每次违规的性质,并在可能的情况下进行本地化。当然,只要仍然正确地翻译了有效的程序,实现就可以自由地产生任意数量的诊断。它也可能成功翻译无效程序。