c++ - 不可预测的 boolean 比较 C++

标签 c++ comparison boolean

为什么这段代码会产生看似随机的行为,

std::cout << ( thePointerIsGood = ( NULL != (aPointer = aFunctionThatReturnsAPointer(args)) ) );

当这个做同样事情的多行版本工作正常时?

aPointer = aFunctionThatReturnsAPointer(args);
thePointerIsGood = (NULL != aPointer);
std::cout << thePointerIsGood;

我正在捕获 aPointerthePointerIsGood 因为我稍后会在代码中使用它们。

更新

以上实际上工作得很好。但是我能够用这个程序重现一些奇怪的行为,我已经标记了错误发生的地方:

// Compiled with:
//   gcc test.cpp -c -o test.o; gcc -lstdc++ test.o -o test

#include <iostream>
#include <cstdlib>

  class
AClass
  { public
    : // Operators ///////////////////////////////////////
      ;  const  bool  operator==  (  const  int  rhs  )  ;
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  }
  ;

  class
AHelperClass
  { public
    : // Functions //////////////////////////////////////////////////////
      ;  static  AClass*  AFunctionThatReturnsAPointer  (  int  arg  )  ;
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  }
  ;

  const
  bool
  AClass::
operator==
  (  const  int  rhs  )
  { return (rhs == 222); }

  AClass*
  AHelperClass::
AFunctionThatReturnsAPointer
  (  int  arg  )
  { return ( (arg == 777)
           ? new AClass
           : NULL
           )
           ;
  }

  int
main
  (     int  argc
  ,  char**  argv
  )
  { // Variables //////////////////
    ;  AClass*  aPointer          ;
    ;     bool  thePointerIsGood  ;
    ;     bool  theValueMatches   ;
    ;      int  i                 ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    for ( i = 0
        ; i < 10
        ; i++
        )
        { // First a good pointer
          std::cout << ( ( thePointerIsGood = ( NULL != ( aPointer = AHelperClass::AFunctionThatReturnsAPointer(777) ) ) )
                       ? "Y  "
                       : "N  "
                       )  
                    << ( (thePointerIsGood == true)
                       ? "expected    "
                       : "unexpected  " 
                       )
                    ;

          if ( !thePointerIsGood )
             { std::cout << std::endl; }
          else
             { // This is where the error is, thanks to Peter for pointing it out
               std::cout << ( (theValueMatches = ((*aPointer) == 222))
                            ? "Y  "
                            : "N  "
                            )
                         << ( (theValueMatches == true)
                            ? "expected"
                            : "unexpected"
                            )
                         << std::endl
                         ;
             }


          delete aPointer;

          // Now a NULL pointer
          std::cout << ( ( thePointerIsGood = ( NULL != ( aPointer = AHelperClass::AFunctionThatReturnsAPointer(877) ) ) )
                       ? "Y  "
                       : "N  "
                       )  
                    << ( (thePointerIsGood == false)
                       ? "expected    "
                       : "unexpected  " 
                       )
                    ;

          if ( !thePointerIsGood )
             { std::cout << std::endl; }
          else
             { std::cout << ( (theValueMatches = ((*aPointer) == 222))
                            ? "Y  "
                            : "N  "
                            )
                         << ( (theValueMatches == true)
                            ? "expected"
                            : "unexpected"
                            )
                         << std::endl
                         ;
             }


          delete aPointer;
        }

    return 0;
  }

这为我产生了以下输出(一切都应该说是预期的)

Y  expected    Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  
Y  unexpected  Y  expected
N  unexpected  

最佳答案

我的想法是以下是未定义的行为:

std::cout << ( (theValueMatches = ((*aPointer) == 222))
                            ? "Y  "
                            : "N  "
                            )
                         << ( (theValueMatches == true)
                            ? "expected"
                            : "unexpected"
                            )
                         << std::endl
                         ;

因为 theValueMatches 在同一个表达式中被使用和赋值,并且没有定义赋值发生在与 true 比较之前还是之后。如果它看起来是不确定的,它确实让我感到惊讶,因为你希望编译器选择一种或另一种方法,虽然我观察到我的不是 - 我每次都从程序中得到相同的输出,有很多意想不到的在那里。

关于c++ - 不可预测的 boolean 比较 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9761581/

相关文章:

c++ - std::vector 构造函数中的 bad_alloc

c++ - 关于c++的派生问题

javascript - 正确使用比较运算符

java - 如何将 PyObject 转换为 java boolean 类型

c# - 具有 10 个元素的随机 boolean 数组,其中 10 个元素中有 3 个为真

java - Java中如何检查文本框中是否输入了某个值

c++ - 错误 : 'A' is an inaccessible base of 'B'

c++ - 模板类成员函数之间的循环依赖

cakephp - cakePHP 框架的缺点

javascript - javascript 中的 2 个字符串之间的比较不起作用