将常量定义为 printf 格式参数,为什么要添加'+ 0'?



我正在读一本关于C编程的书《Unix环境中的高级编程》,在"Unix标准化和实现"一章中,它显示了一个在sysconf和pathconf中打印符号值的程序,该程序中的代码有几行如下所示:

#ifdef ARG_MAX
printf ("ARG_MAX defined to be %ldn", (long) ARG_MAX + 0);
#else
printf ("no symbol for ARG_MAXn");
#endif

每当一个定义的常量被用作printf的参数时,它后面总是跟着+ 0,它似乎什么都没做,因为我试图删除它,但什么也没发生。加零有什么意义?

melpomine在注释中提到的空#define是使用+ 0技巧的原因。

如果某个头有#define ARG_MAX(没有值)——这是一种不可能但并非不可能的情况——代码仍将编译,尽管输出是否有用还有另一个讨论。ARG_MAX的空白替换留下仍然有效的(long) + 0。如果如您所料,定义是一个受适当保护的表达式(可能在括号内),则添加0不会更改值。

在通常的事件过程中,当预处理器评估条件表达式时,扩展宏后留下的任何标识符都映射为零(ISO/IEC 9899:2011§6.10.1条件包含):

¶4…由于宏扩展和defined一元运算符已执行,所有剩余的标识符(包括词汇标识符与关键字相同)替换为pp编号0,然后每次预处理令牌被转换为令牌…

虽然这与这个问题没有直接关系,但就是为什么你有时会看到条件表达式,如:

#if ARG_MAX + 0 > 131072

这是因为该代码是从awk程序自动生成的。

图2.12中所示的awk(1)程序构建了一个C程序,该程序打印每个pathconf和sysconf符号的值。

这个程序的重要部分就是这个。

while (getline <"sysconf.sym" > 0) {
printf("#ifdef %sn", $1)
printf("tprintf("%s defined to be %%d\n", %s+0);n", $1, $1)
printf("#elsen")
printf("tprintf("no symbol for %s\n");n", $1)
printf("#endifn")
printf("#ifdef %sn", $2)
printf("tpr_sysconf("%s =", %s);n", $1, $2)
printf("#elsen")
printf("tprintf("no symbol for %s\n");n", $2)
printf("#endifn")
}

由于它不知道这个符号可能包含什么,它可能是在为它辩护,尽管这本书没有解释它的辩护理由。

最新更新