Printf没有参数解释

时间:2014-12-26 18:27:40

标签: c printf

据我所知,如果printf没有参数,则会输出一个意外的值。

示例:

#include <stdio.h>

int main() {
    int test = 4 * 4

    printf("The answer is: %d\n");
    return 0;
}

这会返回一个随机数。在使用不同格式(如%p,%x等)后,它不会打印16(因为我没有将变量添加到参数部分)我想知道的是,这些价值取自哪里?它是堆栈的顶部吗?每次编译时它都不是新值,这很奇怪,它就像一个固定值。

4 个答案:

答案 0 :(得分:5)

printf("The answer is: %d\n");

调用未定义的行为。 C要求转换说明符具有关联的参数。虽然它是未定义的行为并且任何事情都可能发生,但在大多数系统上,您最终都会转储堆栈。它是format string attacks中使用的一种技巧。

答案 1 :(得分:4)

它被称为undefined behavior,它是可怕的(见this answer)。

如果您需要解释,则需要深入了解具体实施细节。因此,请研究生成的源代码(例如,使用gcc -Wall -Wextra -fverbose-asm +优化标志进行编译,然后查看生成的.s汇编文件)和系统的ABI

答案 2 :(得分:2)

printf函数将在堆栈中查找参数,即使您没有提供参数。如果它找不到整数参数,那么将使用那里的任何东西。大多数情况下,您将获得无意义的数据。选择的数据取决于编译器的设置。在一些编译器上,你甚至可能得到16个。

例如:

int printf(char*, int d){...}

这就是printf的工作方式(不仅仅是一个例子)。如果d为null或为空,它不会返回错误,它只是在堆栈上查找应该显示的参数。

答案 3 :(得分:1)

Printf是一个可变参数函数。大多数编译器将参数推送到堆栈然后调用函数,但是,根据机器,操作系统,调用约定,参数个数等,还有其他值被压入堆栈,这可能在函数中是不变的。 / p>

Printf读取此内存区域并将其返回。