2014-09-22 41 views
8

一个朋友告诉我,后:是`C == C++`未定义的行为?

int C = anything; 

C == C++将具有值true。这是作为一个笑话,对经常声称的“C与C++不一样”的反驳。

但是,由于==不是序列点,我认为这实际上是未定义的行为。该程序可能首先评估C++,以便C > C++C == C++都未定义。但是,C >= C++将始终评估为true。当操作数翻转时(C++ <= C始终为真,其他所有内容都未定义)当然也是如此。

这种分析是否正确?

+5

所有的'C == C++','C> = C++'等都是未定义的。 – 2014-09-22 00:55:44

+0

[尝试它](http://ideone.com/eknvOx)显示,至少使用Ideone当前使用的特定编译器版本和设置,结果恰好出现错误。 – user2357112 2014-09-22 00:56:46

+0

警告告诉它很清楚:http://coliru.stacked-crooked.com/a/1125dd5ddf7c41f9 – Csq 2014-09-22 00:56:48

回答

13

所有病例导致undefined behavior和不可预知的结果。

draft C++11 standard告诉我们,除非另有说明,否则操作数的评估顺序是不确定的,如果相同的标量对象被非顺序和副作用修改的次数多于我们未定义的行为。如果我们需要修改对象并且必须为另一个操作数计算对象的值,那么它也是未定义的。这是覆盖在草案C++ 11标准部1.9

除非另有说明,个体经营者 的和个别表达式子表达式的操作数的评价是未测序。注:在执行程序期间多次评估的表达式中,在不同的评估中不需要一致地执行对其子表达式的评估,其子表达式不需要一致地执行 。 - 结束符]运算符的运算结果的值计算 在运算符的结果之前被排序。如果标量对象上的副作用是 相对于同一标量对象的另一副作用或使用相同标量对象的值计算的值不相关,则行为不确定。

无论是相等运算符或关系运算符在区段5.9关系运算符5.10相等运算指定操作数测序。

clang还提供了一个预警这种情况下,它看起来像在默认情况下,它应该类似于以下(see it live)的东西:

warning: unsequenced modification and access to 'C' [-Wunsequenced] 
    if(C == C++) 
     ~ ^

这也是C++ 03未定义行为没有使用排序关系的概念,但只是sequence points。在C++草案标准03的相关部分将Chapter 5表达式它说:

除非另有说明,个体经营者 和个人表达的子表达式的操作数的计算顺序,以及订单 在其中发生的副作用是未指定的.57)在 前一个和下一个序列点之间,通过评估表达式,一个标量对象最多应该修改其存储的 值。 此外,只有在访问先前值时才能确定要存储的值。对于完整的 表达式的子表达式的每个允许排序,本段的要求应满足 ;否则行为是不确定的。

这是更简单的理由,因为多个修改或修改和使用相同序列点内的标量的值是未定义的行为,无需弄清操作的顺序。

1

你是对的。即使编译器是这么说的:编制

#include <iostream> 

int main() 
{ 
    int C = 0; 
    if (C == C++) { 
    ... 

结果:

main.cpp: In function 'int main()': 
main.cpp:6:17: warning: operation on 'C' may be undefined [-Wsequence-point] 
    if (C == C++) { 
       ^

Coliru

+0

对于一个编译器(和一组设置)这可能是正确的。标准没有要求编译器诊断这一点。而一些编译器则没有。 – Peter 2015-07-17 09:01:05