为什么这段代码会产生看似随机的行为,
std::cout << ( thePointerIsGood = ( NULL != (aPointer = aFunctionThatReturnsAPointer(args)) ) );
当这个做同样事情的多行版本工作正常吗?
aPointer = aFunctionThatReturnsAPointer(args);
thePointerIsGood = (NULL != aPointer);
std::cout << thePointerIsGood;
我正在捕获aPointer
和thePointerIsGood
,因为我稍后会在代码中使用它们。
更新
以上实际上效果很好。但是我能够用这个程序重现一些奇怪的行为,并且我已经标记了错误发生的位置:
// 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
答案 0 :(得分:1)
我的想法是以下是未定义的行为:
std::cout << ( (theValueMatches = ((*aPointer) == 222))
? "Y "
: "N "
)
<< ( (theValueMatches == true)
? "expected"
: "unexpected"
)
<< std::endl
;
因为theValueMatches
在同一个表达式中都被使用并赋值,并且没有定义赋值是在比较true
之前还是之后发生的。如果它看起来是不确定的,那确实让我感到惊讶,因为你希望编译器选择一种方法或另一种方法,虽然我发现我的不是 - 我每次从程序得到相同的输出,有很多意想不到的在那里。
答案 1 :(得分:0)
不能保证表达式的评估顺序。如果你有:
x << (a = b) << a;
然后可以在“(a = b)”之前评估“a”