后缀增量运算符评估

Postfix increment operator evaluation

后缀 increment/decrement 运算符是在表达式求值之后求值还是在整个语句求值之后求值?

#include<stdio.h>

void main()
{
  int a=0;
  int b=0;

  printf("%d %d",a||b,b++);  // Output is 1 0

}

我的编译器从右到左评估 printf 参数。表达式 a||b 的答案是 1,这意味着 b 在 a||b 被计算之前已经递增(即 b 在计算表达式 b++ 之后立即递增)

我在这里读到 Incrementing in C++ - When to use x++ or ++x? 后缀 increment/decrement 在整个语句之后计算。

哪个是正确的?

您链接到的问题的最佳答案不准确。 x++ 中的增量仅保证在确定表达式的值之后发生,有时在评估包含表达式之前发生,但对于何时发生没有其他保证。

特别是,由于同一函数调用的参数的副作用顺序不确定,该程序具有未定义的行为。

未指定函数参数的计算顺序。在将控件传递给被调用函数之前应用与参数评估相关的所有副作用。

来自 C 标准(6.5.2.2 函数调用)

10 There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call.

这是一个演示程序

#include <stdio.h>

struct 
{
    int x;
} a = { 0 };

void f( int x )
{
    printf( "x = %d\n", x );
    printf( "a.x = %d\n", a.x );
}

int main(void) 
{
    f( a.x++ );
}

它的输出是

x = 0
a.x = 1

由于此调用中的副作用,因此一个参数依赖于另一个参数的副作用,并且副作用的评估相对于参数不确定地排序

printf("%d %d",a||b,b++);  

程序有未定义的行为。

当副作用在操作数计算之间排序时,C 中有四个运算符。它们是逻辑与运算符 (&&)、逻辑或运算符 (||) 逗号运算符 (,) 和条件运算符 (?:)。

例如

#include <stdio.h>

int main(void) 
{
    int x = 0;

    printf( "x = %d\n", x++ == 0 ? x : x - 1 );
}

程序输出为

x = 1

表达式 x++ 求值的副作用在求值表达式 x 之前排序?签名。