2

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

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

4 回答 4

5

我假设当您说它在第二个代码示例中不起作用时,您的意思是您遇到了编译时错误。

原因是当有一个隐式函数声明时,它假定采用固定数量的参数,并返回int。但是,mymethod()是先隐式声明,然后再声明为 return void。这是一个错误,因为新声明与先前的(隐式)声明不匹配。

C90 (ANSI C89) 允许隐式函数声明。从 C89,第 3.3.2.2 节:

如果函数调用中带括号的参数列表之前的表达式仅包含一个标识符,并且如果该标识符没有可见的声明,则该标识符被隐式声明,就好像在包含函数调用的最里面的块中,声明

外部 int 标识符();
出现了。

但是,从 C99 开始,该允许已被删除(因此在 C11 中也被禁止)。C++ 从不允许隐式函数声明。

于 2013-07-30T03:44:13.390 回答
3

编译器生成的隐式声明将假定函数的返回类型是int,这有时不是您想要的。避免使用它。

请注意,隐式声明仅在 C89 中有效,在 C99 中已被删除。C++ 也不支持它。

这可以在 C11(ISO/IEC 9899:201x) 标准中得到确认。

在 C11 Forward 部分,它列出了第三版(即 C11)和第二版(即 C99)的所有主要变化,其中之一是:

第二版的主要变化包括:

...

— 删除隐式函数声明

同样在国际标准编程语言 C §6.5.2.2 函数调用的基本原理中

C99 的一个新特性:在 C99 中删除了函数隐式声明的规则。其效果是保证生成将捕获额外类别的编程错误的诊断。发出诊断后,实现可以选择采用隐式声明并继续翻译,以支持利用此功能的现有程序。

于 2013-07-30T03:46:22.427 回答
1

默认假设是函数返回一个 int。所以第一个工作(幸运的是)因为情况就是这样。一般来说,它不会。

于 2013-07-30T03:43:29.760 回答
1

对于 C99 中的隐式函数,必须在调用它之前声明该函数。在声明编写正确的函数原型时。默认方法声明原型具有返回类型“int”,这就是为什么它可以正常工作(在您的示例的第一种情况下)并带有一个警告(例如“函数的隐式声明在 c99 中无效”)。但是在第二种情况下,您更改了默认原型,因此您需要声明其原型。

例如:

//Function prototype declaration
  void mymethod(int);  

//Implementations
  int main()
  {
    mymethod(0);
  }

  void mymethod(int b)
  {
     return;
  }
于 2013-07-30T04:53:20.620 回答