宏和后增量

App*_*ter 4 c macros undefined-behavior

这里有一些奇怪的宏观行为我希望有人可以阐明:

#define MAX(a,b) (a>b?a:b)

void main(void)
{
  int a = 3, b=4;

  printf("%d %d %d\n",a,b,MAX(a++,b++));
}
Run Code Online (Sandbox Code Playgroud)

输出为4 6 5. b的值增加两次,但在MAX显示其值之前不增加.任何人都可以告诉我为什么会这样,以及如何预测这种行为?(应该避免使用宏的另一个例子!)

Ste*_*sop 6

宏进行文本替换.您的代码相当于:

printf("%d %d %d\n",a,b, a++ > b++ ? a++ : b++);
Run Code Online (Sandbox Code Playgroud)

这具有未定义的行为,因为b可能会增加(在第三个参数的末尾),然后使用(在第二个参数中)而没有插入序列点.

但是和任何UB一样,如果你盯着它看一段时间,你可能会想出你的实现已经实现了什么来解释你看到的结果.参数的评估顺序是未指定的,但它看起来好像参数已经按从右到左的顺序进行了评估.因此,首先,ab递增一次.a不大于b,因此b再次递增并且条件表达式的结果是5(也就是说,b在第一个增量之后和第二个增量之前).

这种行为是不可靠的 - 另一个实现或另一天的相同实现可能会因为以不同的顺序评估参数而给出不同的结果,或者理论上甚至可能因序列点问题而崩溃.

  • @Appster:你不能(没有使用你的特定编译器的大量未记录的细节),它是未定义的行为.永远不要写这段代码.如果你的意思是"我怎么能预测它是未定义的",那么简化版本是你永远不应该使用变量并在同一个表达式中增加它.如果面试问题是"这个程序的输出是什么?",那么正确答案是"我不在乎,如果你这样做,那么你就是一个可怜的C程序员".这可能不是最有可能让你找到工作的答案,但这是正确的:-) (2认同)