简体   繁体   English

与赋值表达式的C ++比较是右侧表达式

[英]C++ comparison with an assignment expression be the right hand side expression

I am currently working with a problem about data structure using C++. 我目前正在处理使用C ++的数据结构问题。 I am going to check whether the nodes in a singly linked list are sorted in ascending order or not. 我将检查单链表中的节点是否按升序排序。 Here comes some details of my code 这里有我的代码的一些细节

Node.cpp Node.cpp

class Node
{
   public:
     double data;       
     Node* next;    
};

For the part that problem occurs, 对于问题发生的部分,

double preValue = sLL.head->data;       
Node *curNode = sLL.head->next;     

    do
    {
        if (preValue > (preValue = curNode->data))  // Problem occur in this line   
            return false;
    }while (curNode = curNode->next);

As the order of evaluation of '>' operator is evaluating the left hand side expression and then the right hand side expression 由于'>'运算符的评估顺序是评估左侧表达式然后右侧表达式

AND

the assignment operator would return a reference of the lvalue. 赋值运算符将返回左值的引用。

Therefore, preValue > (preValue = curNode->data) should compares the last node and the current node and assign the data of the next node after the comparison is done. 因此, preValue > (preValue = curNode->data)应比较最后一个节点和当前节点,并在完成比较后分配下一个节点的数据。 Therefore, I think my implementation should be valid. 因此,我认为我的实施应该是有效的。

However, the result of if(preValue > (preValue = curNode->data)) is out of my expected, when comparing a preValue which is bigger than the new preValue , it keeps returning false. 然而,结果if(preValue > (preValue = curNode->data))是我的预料,一比较时的preValue比新的更大的preValue ,它一直返回false。

I have tried to print out the return value of the if statement, it always return 0 whenever the left expression if greater or smaller than the right expression. 我试图打印出if语句的返回值,只要左表达式大于或小于右表达式,它总是返回0。 I cannot understand why this happen. 我不明白为什么会这样。 Could anyone tell me what mistake did I made? 谁能告诉我我犯了什么错误?

ps the program work fine with the following implementation ps该程序可以正常使用以下实现

double preValue = list.head->data;      
Node *curNode = list.head->next;            

do
{
    if (preValue > curNode->data)       // Check ascending order
        return false;

    preValue = curNode->data;

}while (curNode = curNode->next);       

This line is Undefined Behavior: 这一行是未定义的行为:

if (preValue > (preValue = curNode->data))  // Problem occur in this line

because you're assigning to a variable ( preValue ) and reading from that same variable, and the read is not used to determine the value written . 因为您要分配给变量( preValue )并从同一个变量读取 ,并且读取不用于确定写入的值

From C++03 §5/4 [expr] : 来自C ++03§5/ 4 [expr]

[...] Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. [...]在前一个和下一个序列点之间,标量对象的表达式评估最多只能修改一次存储值。 Furthermore, the prior value shall be accessed only to determine the value to be stored. 此外,只能访问先前值以确定要存储的值。 The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; 对于完整表达式的子表达式的每个允许排序,应满足本段的要求; otherwise the behavior is undefined. 否则行为未定义。

A sequence point occurs after full expressions (ie semicolon-terminated expressions or statements), as well as after the first operands of the && , || 序列点出现在完整表达式(即以分号结尾的表达式或语句)之后,以及在&&||的第一个操作数之后。 , ?: , and , operators. ?: ,和,运营商。 All other operators (including the > operator) do not have sequence points between the evaluations of their arguments. 所有其他运算符(包括>运算符)在其参数的求值之间没有序列点。 Sequence points also occur in a few other places not relevant to this question. 序列点也出现在与此问题无关的其他几个地方。

The fix, as you said, is to just break it apart so that the assignment happens in a separate statement from the comparison. 正如您所说,修复方法是将其拆分,以便赋值在比较的单独语句中进行。

When I compile this code with GCC with the -Wall compiler flag, I get this warning: 当我使用-Wall编译器标志使用GCC编译此代码时,我收到此警告:

warning: operation on ‘preValue’ may be undefined [-Wsequence-point]

I highly recommend you always compile with -Wall and -Werror so that these errors get flagged immediately by the compiler and you can correct them. 我强烈建议您始终使用-Wall-Werror编译,以便编译器立即标记这些错误,您可以更正它们。

This line 这条线

if (preValue > (preValue = curNode->data)) 

is an undefined behaviour. 是一种未定义的行为。 See the concepts of sequence points . 请参阅序列点的概念。 An expression can modify its objects only once between two sequence points and '>' is not a sequence point. 表达式只能在两个序列点之间修改其对象一次,而“>”不是序列点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM