调用printf(“%d”)两次,const结果

时间:2014-02-11 13:34:34

标签: c printf

我写了以下程序:

#include<stdio.h>

int main(){
        printf("%x\n");
        printf("%x\n");
        return 0;
}

我知道这是未定义的行为,我只是检查会发生什么。编译器是gcc。

示例输出为:

541d3118
7ffffff7

另一个示例输出是:

e0b08078
7ffffff7

当我使用-O3标志编译它时,结果是:

5ec20f18
9

3bedfa08
9

为什么第一个值会改变,而不是第二个值?为什么第二个值在高优化级别上有所不同?

3 个答案:

答案 0 :(得分:5)

您正在调用printf而未指定其中包含%x格式说明符的值。这会调用未定义的行为,因此您观察到的可能是巧合或特定于编译器的实现。无论哪种方式调用未定义的行为都不是代码中的好东西。

答案 1 :(得分:3)

我会从学术角度尝试看你的问题。如你所见,你得到的东西并不可靠(与未定义的行为一样),你永远不应该依赖它。

但是,你有兴趣知道为什么你会看到你所看到的。

本质上,调用函数并将参数传递给它可以通过堆栈工作。 (这仅适用于某些架构,而不适用于所有架构。)

此功能的“常规调用”可能看起来像

push argument 2
push argument 1
call

如果您将其称为

push argument 1
call

该函数将第二个参数看作完全不同的东西,e。 G。返回地址或调用函数的局部变量或当前堆栈中的其他任何内容。

所以这个值取决于之前堆栈上的内容,甚至可能是你所拥有的局部变量和其他情况。

当然,它也可以依赖于所选择的优化级别,因为它控制哪些变量首先放在堆栈上。

这就是为什么你不应该这样做的原因:你绝对无法控制你在这里得到的东西。

答案 2 :(得分:2)

在调用printf时,根据标准,“如果格式的参数不足,则行为未定义”。你正在目睹这种行为。