它是完全有效的代码,因此编译器不必发出诊断,尽管在这种情况下进行诊断会有所帮助。这是许多开发人员更喜欢的原因之一,clang
因为他们倾向于在诊断方面超出要求。
对于诊断消息的标准规则,我们可以转到草案 C++ 标准部分1.4
实施合规性,其中说(强调我的):
可诊断规则集由本国际标准中的所有句法和语义规则组成,但那些包含“不需要诊断”的明确表示法或被描述为导致“未定义行为”的规则除外。</p>
尽管该国际标准仅规定了对 C++ 实现的要求,但如果将这些要求表述为对程序、程序部分或程序执行的要求,则通常更容易理解。此类要求具有以下含义:
如果程序不包含违反本国际标准规则的行为,则符合要求的实现应在其资源限制内接受并正确执行2该程序。
如果程序包含违反任何可诊断规则或出现在本标准中描述为“有条件支持”的构造,而实现不支持该构造,则符合要求的实现应发出至少一个诊断消息。
如果一个程序违反了不需要诊断的规则,则本国际标准对该程序的实现没有要求。
该程序没有违反句法或语义规则,因此不需要诊断。
我们有以下代码:
if (some_condition) (p1, p2, color);
^ ^ ^
1 2 3
1
是一个表达式语句,在此上下文中对于和if 语句有效。我们可以通过语法看到这一点:
if ( condition ) statement
和:
statement:
attribute-specifier-seqopt expression-statement
和:
expression-statement:
expressionopt;
和:
primary-expression:
( expression )
2
和都是逗号运算符3
,它将评估左操作数并丢弃该值,然后再次评估右操作数,这里没有任何无效。
那么5.18
逗号运算符部分说的是什么:
一对用逗号分隔的表达式从左到右计算;左边的表达式是丢弃的值表达式(第 5 条)。83
丢弃的值表达式在部分5
中介绍:
在某些情况下,表达式只出现在它的副作用上。这样的表达式称为弃值表达式。
因此,由于左侧表达式的结果值被丢弃了,所以我们必须只关心副作用。在您的特定情况下,评估变量除了生成一个值因此警告之外没有其他影响,但是如果您在它们的位置使用了一个函数,例如:
bool func()
{
//...
}
并将您的代码更改为:
if (some_condition) (func(), func(), func() );
既clang
不会也gcc
不会提供警告,因为可能func
会执行一些您关心的副作用。