C 为什么此代码中没有违反序列点规则的情况?
使用的编译器:gcc 8.2 命令行:-墙 我目前对序列点冲突的理解是,代码在某种程度上取决于给定表达式中操作数/子表达式的求值顺序。这是因为表达式中操作数的求值顺序未指定,如前所述。 因此,代码如下:C 为什么此代码中没有违反序列点规则的情况?,c,compiler-warnings,sequence-points,C,Compiler Warnings,Sequence Points,使用的编译器:gcc 8.2 命令行:-墙 我目前对序列点冲突的理解是,代码在某种程度上取决于给定表达式中操作数/子表达式的求值顺序。这是因为表达式中操作数的求值顺序未指定,如前所述。 因此,代码如下: a = 5; b = a + ++a; 是违规行为,并被-wsequencepoint捕获,因为结果中存在歧义,即应该是(5+6)还是(6+6)? 我认为下面的代码中也存在类似的歧义,因为我们无法知道第二个++a是否会在第一个之前进行评估: #define MIN(a, b) (((a) &l
a = 5;
b = a + ++a;
是违规行为,并被-wsequencepoint捕获,因为结果中存在歧义,即应该是(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;
}
定义最小值(a,b)((a)<(b))?(a):(b))
int use()
{
int-min;
INTA=4,b=5;
最小值=最小值(++a,b);
//最小值=(++a)
我显然遗漏了一些东西,因为此代码没有在-wsequencepoint上警告我。有人能帮我理解什么吗?
请注意,我特意将MIN定义为原样。根据ISO C11标准,三元/条件运算符谓词的求值与其任何一个备选值之间存在一个序列点,以求值的为准。因此,两个
++a
通过中间的序列点彼此排序
§6.5.15条件运算符
语法
一,
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
[……]
语义学
根据ISO C11标准,三元/条件运算符谓词的求值与其任一备选值之间存在一个序列点,以求值的为准。因此,两个
++a
通过中间的序列点彼此排序
§6.5.15条件运算符
语法
一,
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
[……]
语义学
三元运算符的谓词求值和它的任何一个可选值之间都有一个序列点。@Iwillnotexistidownotexist Cool,我不知道这一点。如果你想写下这个作为答案,我可以接受。请在你的答案中包含一个链接,链接到一个同样说明这一点的来源。虽然序列点规则并不总是合乎逻辑的,但这一条是合乎逻辑的。实现首先需要知道要评估两个备选方案中的哪一个,并且必须完全评估其中一个而不是另一个。这不是像“代码>+/<代码>之类的操作符。哪里没有特别的原因应该被首先评估。不管怎样,我认为这是一种糟糕而混乱的编码风格。”以上是MIN宏的正确实现。这是使用is这样一个宏时遇到的问题之一,而不是使用具有副作用的表达式。三元运算符的谓词求值与其任何一个备选值之间都有一个序列点。@Iwillnotexistidoxist很酷,我不知道这一点。如果你想写下这个作为答案,我可以接受。请在你的答案中包含一个链接,链接到一个同样说明这一点的来源。虽然序列点规则并不总是合乎逻辑的,但这一条是合乎逻辑的。实现首先需要知道要评估两个备选方案中的哪一个,并且必须完全评估其中一个而不是另一个。这不是像“代码>+/<代码>之类的操作符。哪里没有特别的原因应该被首先评估。不管怎样,我认为这是一种糟糕而混乱的编码风格。”以上是MIN宏的正确实现。这是使用is这样一个宏时遇到的问题之一,而不是使用有副作用的表达式。