c++ - Unexpected evaluate result when calling std::set functions in "if" statement -
i found behavior of calling std::set function in "if" statement can't understand, here code.
#include<set> #include<iostream> #include<cstdio> using namespace std; set<int>s;int t; set<int>::iterator i; int main() { while (cin>>t) { if ((i=s.insert(t).first)==s.begin()) /*expected: insert new element, iterator of new inserted element , save i, , compare begin of set see if smallest. */ puts("the new int smallest"); else puts("the new int not smallest"); } return 0; }
if input:
3 2 1
the output be:
the new int not smallest new int not smallest new int not smallest
however, if move insert out of "if":
while (cin>>t) { (i=s.insert(t).first); if (i==s.begin()) puts("the new int smallest"); else puts("the new int not smallest"); }
then can expected output:
the new int smallest new int smallest new int smallest
i tried test using following code:
int a() { puts("fun encountered"); return 1; } int b() { puts("fun b encountered"); return 1; } int main() { int x; if ((x=a())==b()); }
and output is:
fun encountered fun b encountered
seems order expected in first code. confused. reason first code went wrong?
this great reason not write horribly complex code!
from [intro.execution]:
except noted, evaluations of operands of individual operators , of subexpressions of individual expressions unsequenced.
when write:
(i=s.insert(t).first)==s.begin()
you have no guarantee begin()
called before or after insert()
. if it's called before insert()
, inserted element won't equal begin()
since they're pointing different things.
just write assignment , test on separate lines. space isn't premium. not mention that
auto = s.insert(t).first; if (t == s.begin()) { ... }
is easier read , understand anyway, in addition being well-defined behavior.
Comments
Post a Comment