没有正确的原型调用printf会调用未定义的行为吗?

时间:2016-07-31 17:15:24

标签: c printf language-lawyer undefined-behavior function-prototypes

这个无辜的程序是否会调用未定义的行为:

int main(void) {
    printf("%d\n", 1);
    return 0;
}

1 个答案:

答案 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;
}