有人可以向我解释为什么以下编译:
int main()
{
int a = mymethod(0);
}
int mymethod(int b)
{
return b;
}
但这不是:
int main()
{
mymethod(0);
}
void mymethod(int b)
{
return;
}
我认为在C / C ++中需要前向声明,但这是一个反例。隐式声明如何在C中起作用?
答案 0 :(得分:4)
我假设当你说它在第二个代码示例中不起作用时,你的意思是你得到一个编译时错误。
原因是当存在隐式函数声明时,假定它采用固定数量的参数,并返回int
。但是,mymethod()
首先被隐式声明,然后声明返回void
。这是一个错误,因为新声明与先前的(隐式)声明不匹配。
C90(ANSI C89)允许隐式函数声明。从C89,第3.3.2.2节:
如果括号中的括号参数列表之前的表达式 函数调用仅包含标识符,如果不包含 声明对于此标识符是可见的,标识符是 在包含的最里面的块中隐式声明 函数调用,声明
extern int identifier();出现了。
然而,自C99起,这项津贴已被删除(因此在C11中也不允许)。 C ++从不允许隐式函数声明。
答案 1 :(得分:3)
编译器生成的隐式声明将假定函数的返回类型为int
,有时这不是您想要的。避免使用它。
请注意,隐式声明仅适用于C89,它在C99中删除。 C ++也不支持它。
这可以在C11(ISO / IEC 9899:201x)标准中确认。
在C11转发部分,它列出了第三版(即C11)和第二版(即C99)的所有主要变更,其中一个是:
第二版的主要变化包括:
...
- 删除隐式函数声明
同样在Rationale for International Standard Programming Languages C§6.5.2.2函数调用
中C99的新功能:在C99中删除了隐式声明函数的规则。其结果是保证生成可以捕获其他类别编程错误的诊断。发出诊断后,实现可以选择采用隐式声明并继续转换,以支持利用此功能的现有程序。
答案 2 :(得分:1)
默认假设是函数返回int。所以第一个工作(幸运的是)因为情况就是这样。一般情况下,它没有。
答案 3 :(得分:1)
对于C99中的隐式函数,函数必须在被调用之前声明。同时声明编写适当的函数原型。默认方法声明原型具有返回类型“int”,这就是为什么它工作正常(在您的示例的第一种情况下)有一个警告(如“c99中函数的隐式声明无效”)。 但在第二种情况下,您已经更改了默认原型,因此您需要声明其原型。
例如:
//Function prototype declaration
void mymethod(int);
//Implementations
int main()
{
mymethod(0);
}
void mymethod(int b)
{
return;
}