8

在下面的:

printf("Example%s\n",NULL);
printf("%s\n",NULL);

我得到的输出为:

Example(null)
Segmentation Fault

当我在 GDB 中尝试回溯时,它显示printf()已转换为puts(). 但我似乎无法理解为什么会发生这种情况。

顺便说一句,我找到了这篇文章,但似乎仍然没有意义。

4

1 回答 1

15

该标准说,将NULL指针作为参数传递给printf带有%s说明符的 a 是未定义的行为1(即任何事情都可能发生),因此这两种行为都是合法的。

在第一种情况下,标准库(特别是printf代码)通过打印来帮您一个忙(null)

相反,在第二种情况下,优化器知道您printf可以替换为 a puts(更有效),而不会对程序的“可观察行为”进行任何更改,因此它会替换它。但是,puts碰巧不包含 的NULL-checking 代码printf,因此您会遇到分段错误。


  1. C99,§7.19.6.1,¶8:

    参数应该是指向字符类型数组的初始元素的指针。

    ¶9:

    如果任何参数不是相应转换规范的正确类型,则行为未定义。

    你属于最后一种情况,因为NULL不是“指向字符类型数组的初始元素的指针。

于 2012-04-10T21:13:54.650 回答