错误的printf类型仍然打印正确的值

Byt*_*e95 6 c printf

我刚刚遇到这种奇怪的情况,我无法解释它.我真的很好奇,最重要的事情发生了什么.我有这个示例代码:

#include <stdio.h>
#include <stdint.h>

int main()
{
    int64_t qty = 900;
    double  p   = 74.45;

    printf( "%f|%ld\n", p, qty );
    printf( "%f|%ld\n", qty, p );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,在第二个printf中,我提供了错误订单中的参数,更不用说类型错误了.但是,我仍然得到两个CORRECT输出?奇怪的是......用gcc 7.2编译:

$ ./a.out
74.450000|900
74.450000|900
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

int*_*jay 4

传递错误的参数类型会printf导致未定义的行为。当你有未定义的行为时,任何事情都可能发生,包括看似“正确”的行为。

在这种情况下,在此体系结构上,整数和浮点值很可能被传递到不同寄存器中的变量参数函数。因此printf打印第一个浮点寄存器%f和 第一个整数寄存器%ld,无论它们传入的顺序如何,最终都是正确的。

然而,永远不应该依赖这一点,甚至可能会根据编译器、优化等在此特定架构上给出错误的结果。