在3个不同的系统上尝试过:CentOS,Ubuntu和Windows(MinGW);所以我不认为这是一种异常(未定义的行为)
int hello(void)
{
(void)printf("HELLO WORLD\n");
}
int main(void)
{
printf("%d\n",hello());
return 0;
}
输出是:
HELLO WORLD
12
即使使用不同的文本,它也会返回正确的值。有什么解释吗?
答案 0 :(得分:5)
是的, 是 undefined behaviour。
如果到达结尾}
,没有return
,则使用返回的值为UB。
从C11
开始,章节§6.9.1,函数定义
如果到达了终止函数的
}
,则使用函数调用的值 调用者,行为未定义。
你不应该通过查看UB的结果来判断 UB。毕竟,它是 undefined 。
答案 1 :(得分:1)
构建代码时,您可能会收到警告:
warning: no return statement in function returning non-void [-Wreturn-type]
在功能中
int hello(void)
{
(void)printf("HELLO WORLD\n");
}
由于没有return
声明。这就是为什么你会得到Undefined Behavior
答案 2 :(得分:1)
虽然每个人都指出整个业务都是未定义的行为,但只有一个人回答了实际问题。然而,问题更加错误,并且出于某种原因,没有人会解决它。
在3个不同的系统上尝试过:CentOS,Ubuntu和Windows(MinGW);所以我不认为这是一个异常(未定义的行为)
这种推理存在严重缺陷(您测试的系统数量无法告诉您这是否已定义)。不仅如此,您的测试显然是肤浅的。在我的系统上使用-O2编译代码突然使其打印为0,并且系统可能会发生相同的事情。
它可能由意外工作的原因是你的系统返回值保存在EAX中,返回main()之后没有被修改,编译器发出代码从EAX移动值到另一个printf的第一个参数。
如前所述,并证明-O2失败,这是不可靠的。
最后一句话更加错误:
即使使用不同的文本,它也会返回正确的值。任何 解释
什么?
让我们来看看有问题的功能:
int hello(void)
{
(void)printf("HELLO WORLD\n");
}
该函数没有return语句,因此无论得到什么结果都不是“正确的值”。特别是,您没有要求语言返回printf返回的值。碰巧在你的测试中你获得了printf返回的值,但这不是你要求的,因此它在任何意义上都不是“正确的”。严格地说,人们可能想知道在这种情况下是否保证返回被称为last的函数的返回值,但是它被解释并证明了没有。
答案 3 :(得分:0)
12正好是第一个printf的返回值。
可能printf("HELLO WORLD\n");
的结果将留在EAX
注册。
因此,当第二个printf期望返回值时,它是函数的最后返回值(EAX
)。