据我所知,如果printf没有参数,则会输出一个意外的值。
示例:
#include <stdio.h>
int main() {
int test = 4 * 4
printf("The answer is: %d\n");
return 0;
}
这会返回一个随机数。在使用不同格式(如%p,%x等)后,它不会打印16(因为我没有将变量添加到参数部分)我想知道的是,这些价值取自哪里?它是堆栈的顶部吗?每次编译时它都不是新值,这很奇怪,它就像一个固定值。
答案 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读取此内存区域并将其返回。