#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位编译器。
答案 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,函数调用
如果定义的函数的类型与(类型的)类型不兼容 表达式)表示被称为被调用函数的表达式,行为是 未定义。