Printf没有参数说明

我理解如果printf没有给出参数,它会输出一个意外的值。

例:

#include  int main() { int test = 4 * 4 printf("The answer is: %d\n"); return 0; } 

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

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

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

它被称为未定义的行为 ,它是可怕的 (见这个答案 )。

如果您需要解释,则需要深入了解实现特定的详细信息。 因此,研究生成的源代码(例如使用gcc -Wall -Wextra -fverbose-asm +优化标志进行编译,然后查看生成的.s程序集文件)和系统的ABI 。

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

例如:

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

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

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

Printf读取这个内存区域并返回它。