我期待以下代码中的错误,但在运行输出为5后,任何人都可以告诉原因。
#include <stdio.h>
void main()
{
int k = m();
printf("%d", k);
}
void m()
{
printf("hello");
}
因为返回类型是无效的,但是当我们将它声明为main时,它会给出错误。
答案 0 :(得分:6)
此程序无效(进一步说明原因如下)。
在C89中调用m()
时,或在C99中启动程序时,会导致未定义的行为。这意味着一切都会发生。换句话说,编译器只需要处理正确的程序;如果你犯了一个错误,那么你可以得到垃圾结果(这不仅限于无效输出)。
在C89中,此代码实际上不需要任何编译器诊断 1 。它只会导致未定义的行为。 (无论如何,有用的编译器可能会给你一个警告。)
这是因为行int k = m();
导致函数m()
的隐式声明返回int
并采用未指定的参数。但是,m
的实际函数体返回void
。这意味着如果调用m
,则会触发未定义的行为。
实际上,您可能遇到的是main
函数在特定寄存器中查找从m
返回的值,但m
的函数体未设置那个注册,碰巧偶然包含5
。不要依赖这种行为。
由于您未使用函数原型,因此编译器不需要诊断此错误。如果您确实使用了函数原型(例如void m(void)
),或者将void m()
移到main()
之前,那么编译器需要进行诊断。 (如果你继续运行你的程序,忽略这个消息,那么程序的整个行为是未定义的。)
在C99中,删除了函数的隐式声明,并且行int k = m();
必须提供诊断。
1 需要诊断表示代码根据标准C有错误,编译器必须向您报告消息。编译器可以选择将此消息分类为“警告”并生成可执行文件,但是在这种情况下代码仍然不正确,应该修复。