为什么这段代码中没有违反序列点规则?
Why are there no sequence point rule violations in this code?
使用的编译器:gcc 8.2
命令行:-Wall
我目前对序列点违规的理解是代码在某种程度上取决于给定表达式中 operands/sub-expressions 的求值顺序。之所以如此,是因为未指定表达式中操作数的求值顺序,如 here 所述。
因此,代码如下:
a = 5;
b = a + ++a;
是一个违规并被 -Wsequence-point 捕获,因为结果有歧义,即它应该是 (5 + 6) 还是 (6 + 6) ?
我认为下面的代码中存在类似的歧义,因为我们不知道第二个 ++a 是否会在第一个之前被评估:
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
int use()
{
int min;
int a = 4, b = 5;
min = MIN(++a, b);
//min = ((++a) < b) ? (++a) : b;
return min;
}
我显然遗漏了一些东西,因为这段代码没有在 -Wseqeuence-point 上警告我。有人可以帮我理解什么吗?
请注意,我故意按原样定义了 MIN。
根据 ISO C11 标准,在 ternary/conditional 运算符谓词的求值与其任一备选项(以求值者为准)之间存在一个序列点。因此,两个 ++a
通过中间序列点相对于彼此排序。
§6.5.15 Conditional operator
Syntax
1.
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
[...]
Semantics
- The first operand is evaluated; there is a sequence point between its evaluation and the evaluation of the second or third operand (whichever is evaluated). The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.
使用的编译器:gcc 8.2
命令行:-Wall
我目前对序列点违规的理解是代码在某种程度上取决于给定表达式中 operands/sub-expressions 的求值顺序。之所以如此,是因为未指定表达式中操作数的求值顺序,如 here 所述。 因此,代码如下:
a = 5;
b = a + ++a;
是一个违规并被 -Wsequence-point 捕获,因为结果有歧义,即它应该是 (5 + 6) 还是 (6 + 6) ? 我认为下面的代码中存在类似的歧义,因为我们不知道第二个 ++a 是否会在第一个之前被评估:
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
int use()
{
int min;
int a = 4, b = 5;
min = MIN(++a, b);
//min = ((++a) < b) ? (++a) : b;
return min;
}
我显然遗漏了一些东西,因为这段代码没有在 -Wseqeuence-point 上警告我。有人可以帮我理解什么吗? 请注意,我故意按原样定义了 MIN。
根据 ISO C11 标准,在 ternary/conditional 运算符谓词的求值与其任一备选项(以求值者为准)之间存在一个序列点。因此,两个 ++a
通过中间序列点相对于彼此排序。
§6.5.15 Conditional operator
Syntax
1.
conditional-expression: logical-OR-expression logical-OR-expression ? expression : conditional-expression
[...]
Semantics
- The first operand is evaluated; there is a sequence point between its evaluation and the evaluation of the second or third operand (whichever is evaluated). The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.