如果用错误的格式字符串调用printf会发生什么?

或者换句话说:可能错误printf/ fprintf十进制整数(%d,%u,%ld,%lld)格式化字符串导致程序崩溃或导致未定义的行为?


Cosinder的以下代码行:


#include <iostream>

#include <cstdio>


int main() {

    std::cout << sizeof(int) << std::endl

              << sizeof(long) << std::endl;


    long a = 10;

    long b = 20;

    std::printf("%d, %d\n", a, b);


    return 0;

}

在32位架构上的结果:


4

4

10, 20

64位体系结构的结果:


4

8

10, 20

无论如何,程序都会打印出预期的结果。我知道,如果该long值超出int范围,程序将打印错误的数字-这很丑陋,但不会影响程序的主要目的-但是除此之外,还会发生意外情况吗?


喵喵时光机
浏览 519回答 3
3回答

慕标琳琳

如果用错误的格式字符串调用printf会发生什么?什么都可能发生。这是未定义的行为!未定义的行为意味着任何事情都可能发生。它可能会向您显示预期的结果,也可能不会,或者可能导致崩溃。任何事情都有可能发生,您只能怪自己,不要怪自己。参考:c99标准:7.19.6.1:第9段:如果转换规范无效,则行为未定义。225)如果任何参数都不是对应coverage规范的正确类型,则行为未定义。

扬帆大鱼

哦,是的-printf取决于格式字符串,以确定接下来要获取的变量的大小和类型。当格式字符串错误时,它可能会尝试获取一个甚至不存在的变量,从而可能产生所有后果。

天涯尽头无女友

这是未定义的行为-规范中没有任何内容告诉编译器设计器(或C库设计器)应如何处理,因此允许他们执行任何操作。在实践中,完全取决于数字的解释是其中之一,最有可能的是,这样做绝对不会给您带来任何好处。真正糟糕的是,当您将字符串与整数格式混合时-字符串会很好地打印为(奇怪的,也许是)数字,但是当数字作为字符串传递时,数字不太可能“起作用”-因为字符串是指向第一个地址的指针字符-大多数数字在典型系统中不是有效的指针,因此会崩溃。但是,没有任何保证。在您的64位示例中,很明显该数字是“ little endian”。尝试使用0x100000000进行同样的操作,它会显示0-因为其余的数字都会丢失。
打开App,查看更多内容
随时随地看视频慕课网APP