这个无辜的程序是否会调用未定义的行为:
int main(void) {
printf("%d\n", 1);
return 0;
}
答案 0 :(得分:10)
是没有正确的原型(来自标准头printf()
或来自正确编写的声明)调用<stdio.h>
会调用未定义的行为。
如C11附录J(仅提供信息)中所述
J2未定义的行为
- 对于在函数原型定义函数的范围内调用没有函数原型的函数,原型以省略号结尾或者升级后的参数类型与参数类型不兼容(6.5 .2.2)。
本附件不是规范性的,但清楚地将上述代码记录为未定义行为的示例。
在更实用的词汇中,在没有printf
原型的情况下,编译器生成调用序列,好像printf
被定义为int printf(const char*, int)
,这可能是完全不同的,与之不兼容标准库中printf
的实际实现,定义为int printf(const char restrict *format, ...)
。
古代ABI足够常规,这不会引起问题,但现代(例如64位)ABI使用更有效的调用序列,使上述代码绝对不正确。
因此,这个着名的经典C程序也会失败,没有#include <stdio.h>
或至少是printf
的原型:
int main(void) {
printf("Hello world\n"); // undefined behavior
return 0;
}