难道没有一个适当的原型调用的printf未定义行为? [英] Does calling printf without a proper prototype invoke undefined behavior?

查看:224
本文介绍了难道没有一个适当的原型调用的printf未定义行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  INT主要(无效){
    的printf(%d个\\ N,1);
    返回0;
}


解决方案

是调用的printf()没有一个适当的原型(从标准头 <文件stdio.h方式> 或适当书面声明)调用未定义的行为

由于记录在C11附录J(资料只)


  

J2未定义行为


  
  

      
  • 有关的函数的调用,而不在范围上一个函数原型所在的函数与函数原型定义,要么以省略号原型结束或类型的参数升级后不与参数类型兼容(6.5 2.2)。

  •   

本附件是不规范的,但很明显记录了超过code作为未定义行为的例子。

在更务实的话,在没有原型为的printf ,编译器生成调用序列,如果的printf 定义为 INT的printf(为const char *,INT)这可能是完全不同的,并与实际执行的printf 标准库,定义为 INT的printf(为const char *限制格式,...)

古老的ABI者经常不够,这会不会造成问题,但现代的(如64位)的ABI使用更有效的调用,使上述code序列肯定不正确。

因此​​,这个著名的经典的C程序就会失败过,没有的#include< stdio.h中> 或至少一个适当的原型的printf

  INT主要(无效){
    的printf(世界,你好\\ n); //未定义行为
    返回0;
}

Does this innocent looking program invoke undefined behavior:

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

解决方案

Yes invoking printf() without a proper prototype (from the standard header <stdio.h> or from a properly written declaration) invokes undefined behavior.

As documented in C11 Annex J (informative only)

J2 Undefined Behavior

  • For call to a function without a function prototype in scope where the function is defined with a function prototype, either the prototype ends with an ellipsis or the types of the arguments after promotion are not compatible with the types of the parameters (6.5.2.2).

This annex is not normative, but clearly documents the above code as an example of undefined behavior.

In more pragmatic words, in the absence of a prototype for printf, the compiler generates the calling sequence as if printf was defined as int printf(const char*, int) which may be quite different and incompatible with the actual implementation of printf in the standard library, defined as int printf(const char restrict *format, ...).

Ancient ABIs were regular enough that this would not cause a problem, but modern (eg 64-bit) ABIs use more efficient calling sequences that make the above code definitely incorrect.

As a consequence, this famous classic C program would fail too, without the #include <stdio.h> or at least a proper prototype for printf:

int main(void) {
    printf("Hello world\n");  // undefined behavior
    return 0;
}

这篇关于难道没有一个适当的原型调用的printf未定义行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆