隐式函数声明有时在C中起作用吗?

时间:2013-07-30 03:39:07

标签: c function forward-declaration implicit-declaration

有人可以向我解释为什么以下编译:

int main()
{
    int a = mymethod(0);
}
int mymethod(int b)
{
    return b;
}

但这不是:

int main()
{
    mymethod(0);
}
void mymethod(int b)
{
    return;
}

我认为在C / C ++中需要前向声明,但这是一个反例。隐式声明如何在C中起作用?

4 个答案:

答案 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;
  }