当我们将返回类型为void的函数调用返回值赋给int变量时会发生什么?

时间:2017-02-16 09:25:01

标签: c variable-assignment void forward-declaration function-call

#include<stdio.h>
int main()
{
   //void foo();
   int c= 5;
   c=foo();
   printf("\n%d",c);
   return 0;
}
void foo()
{
  printf("I am foo");
}

当我评论原型声明时,它会给出输出:

  

我是foo

     

8

使用原型时会出错:

  

虚假价值不应该被忽视,因为它应该是。

我的问题是,当没有原型声明时,内部会发生什么导致输出?它背后的原因是什么?

我正在使用Dev C ++编辑器和TDM-GCC 4.9.2 64位编译器。

3 个答案:

答案 0 :(得分:3)

成功构建它的唯一原因是隐式int规则(现在已在最新版本的C标准中删除)。

编译器看不到foo的前向声明,因此它假定其返回类型为int。然后它继续构建并调用您的void foo()。毕竟说完了,程序的行为是不确定的。

答案 1 :(得分:1)

Gcc编译器发出警告并成功运行,返回带有空格的字符数,但有些编译器会出错。

pp.c:10:6: warning: conflicting types for ‘foo’ [enabled by default]
 void foo()
      ^
pp.c:6:6: note: previous implicit declaration of ‘foo’ was here
    c=foo();

答案 2 :(得分:1)

  

没有原型声明时

嗯,这是无效的C.

详细说明,

  • 第1点:您不能使用之前未声明的函数。这违反了C标准规则。注意

  • 第2点:一旦添加了前向声明,就会出现编译错误,因为void类型不能是赋值运算符的RHS操作数这是赋值运算符的约束违规。

注意:

在C99之前,允许在没有已知原型的情况下调用函数,假设该函数将返回int并且将接受任意数量的参数。但是,根据C99及更高版本,这是完全禁止的,因为“隐含的int规则”已从标准中删除。 (请参阅前言,第5段,_“删除隐式int”_ C99标准中)

在您的情况下,由于遗留原因,编译器仍然支持隐式int规则,因此它编译得很好,但编译器和实际函数定义的假设是不匹配的。这会调用undefined behavior

引用C11,章节§6.5.2.2,函数调用

  

如果定义的函数的类型与(类型的)类型不兼容   表达式)表示被称为被调用函数的表达式,行为是   未定义。