以下程序在某些编译器上编译时没有错误(仅警告)。但我们可以预测其产量吗?如果是这样,怎么样?
#include<stdio.h>
void main()
{
printf("%d",fun(5));
}
void fun(int i)
{
if(i%2)
return i;
else
return i+2;
}
答案 0 :(得分:3)
是的,这个可以编译。不,无法安全执行
。由于您没有在fun
上声明main
高于其使用率,因此默认为int
返回类型和任意数量的参数。就像编译器添加了一样:
int fun(); // Implicit declaration for the function used below
void main()
{
printf("%d",fun(5));
}
当编译器遇到你的定义时,它会根据这个隐式声明警告不匹配的声明和定义。
然后它会再次警告您从刚刚声明的函数void
返回值。
请注意,它不会警告您使用void
函数的返回值,因为当它在您的printf中连接fun
调用时,它仍然只有fun
的隐式声明。
您将收到有关main
的返回类型的更多警告,该类型必须为int
。然后编译结束&#34;成功&#34;。
但上述所有问题都是未定义行为的来源。你不应该这样做,并且编译器很友好地警告你(它没有被要求这样做)。如果执行生成的可执行文件,它可以完全执行任何操作。
我尝试了它并打印了#34; 1&#34;。也许你会打印&#34; 5&#34;。它可以印上马铃薯&#34;,或者让我的袜子着火,就标准而言。
底线是:不,我们无法预测具有UB的程序的输出或行为。
编辑:我不应该写,我不应该写,我不应该写...
所以你得到0或1.最有可能发生的事情:
void
函数不会返回任何内容。所以它忽略了你在return
之后所写的内容。int
,因此调用代码会获取它所认为的#34;是你的回报价值。并且恰好将int
- returing函数的返回值存储在先前使用的寄存器中。因此,调用代码获取模数值。你的问题正在受到严厉对待,因为编辑一直在骂你,你在写胡言乱语。
但它仍然很有趣,因为编译器通常不会警告UB,并且可能导致不可预测且难以跟踪的错误。了解他们可能的来源可以帮助您。但是从不依赖于你在这些实验中发现的东西。