Topic: What means i==0 ? i=1 : i=0; really?


Author: Achim Bursian <abu@erlf.siemens.de>
Date: 1999/02/18
Raw View
AllanW@my-dejanews.com wrote:
> > What the programmer wanted to express seems to be  i ? 0 : 1;
>
> Well, now, this isn't the same at all. For one thing, it's an
> expression statement with no side effects. Perhaps you meant
>
>     i = i ? 0 : 1;

Well, that is exactly what I wanted to type. Forgot the "i =", sorry,
that was a typo.

---
Achim Bursian / Siemens AG, A&D MC E35 / Tel.: +49-9131-98-3759
E-Mail: abu@erlf.siemens.de


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Christopher M. Gurnee" <gurnec_at_mediaone_dot_net@127.0.0.1>
Date: 1999/02/19
Raw View
Bjarne Stroustrup wrote in message ...
>Ron Natalie <ron@sensor.com> writes:
>
> > Actually, the bug is in the book.  The assignment operators and
> > the conditional operators are listed backwards in the table on
> > page 121.  It was not Bjarne's intent to change the relative
> > ordering from the way it works in C.  It's in the errata.
>
>Actually, to be really picky (this is comp.std.c++ after all), it is not
>a bug in the book. Immediately after the precedence table, I take pains
>to point out that the C++ grammar cannot be completely specified by a
>set of precedences and give a=b<c?d=e:f=g as an example.
>
>The errata places ?: where it would be in a classic C grammar because that
>is the most common resolution in real code. There, it will confuse fewer
>people who fail to read the grammar. However, both possible placements of
>?: in the precedence table are equally right/wrong according to the grammar
>and the caveat below the table applies as ever.

A short while ago I attempted to derive a precedence table from the grammar
in the standard.  What I came up with placed = and ?: on the same level
(along with throw), grouping (is that the right term?) right-to-left.  Is
this correct?  Your example becomes a=((b<c)?d=e:(f=g)), which I think is
right.

The only exception I had to add to my table involved sizeof and C-style
casting; although they are on the same level, sizeof has a greater
precedence than casting.

Just for reference, I put the table up (as a Word 6 doc, sorry) at:

http://people.ne.mediaone.net/gurnec/cpp_operator_precedence.doc

TIA,
Chris
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Matt Seitz" <mseitz@meridian-data.com>
Date: 1999/02/20
Raw View

Christopher M. Gurnee wrote in message ...
>A short while ago I attempted to derive a precedence table from the grammar
>in the standard.  What I came up with placed = and ?: on the same level
>(along with throw), grouping (is that the right term?) right-to-left.  Is
>this correct?  Your [Dr. Stroustrup's] example becomes a=((b<c)?d=e:(f=g)),
which I think is
>right.


I don't think this is right.  If I'm reading your result correctly, then you
would parse this as:

if(b<c){
    d=e;
    a=d;
}else{
    f=g;
    a=f;
}

According to Dr. Stroustrup's book, the correct result is
(a=b<c)?(d=e):(f=g), which would parse to:

a = (b<c);
if(b<c){
    d=e;
}else{
    f=g;
}




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AJRobb@bigfoot.com (Andrew J Robb)
Date: 1999/02/16
Raw View
i==0 ? i=1 : i=0;

ISO/IEC-14882:1998 5.16
"All side effects of the first expression except for destruction of
temporaries happen before the second or third expression is evaluated.
Only one of the second or third expressions is evaluated."

This seems clear that the statement is well formed and the cfront
compiler was wrong.

I would use:

i = !i;
or
i = (i == 0);


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ian McCulloch" <ipm105@rsphy1.anu.edu.au>
Date: 1999/02/16
Raw View

Achim Bursian wrote in message <36C93553.97689C0C@erlf.siemens.de>...
>Hello, c++ standard gurus!
>I have to maintain some code which contains the bad line
>   i==0 ? i=1 : i=0;
>Ok, let us not argue that this is bad, bad style. What the programmer
>wanted to express seems to be  i ? 0 : 1;
>But I have this line in the code, and my two compilers produce DIFFERENT
>output from it:
>
>=== The first one ====
>// cfront==>  ((*((__1i == 0 )?( (__1i = 1 ), (& __1i )) :(& __1i ))))=
>0 ;
>//         CMP        DWORD PTR [EBP+8],0       ;__1i
>//         JNE        NEAR PTR L10004
>//         MOV        DWORD PTR [EBP+8],1       ;__1i
>//         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
>//         JMP        NEAR PTR L10005
>//      EVEN
>// L10004:
>//         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
>// L10005:
>//         MOV        DWORD PTR [ECX],0
>
>As you see, the target i ALWAYS gets a 0 in the end! It is never 1 after
>the offending line.

One possibility is that cfront is interpreting the statement as

(i == 0 ? i = 1 : i ) = 0;

That is, the left side of the expression returns either i, or i after being
assigned the value 1.  The right hand side of the expression sets the left
side (ie i) to 0.

However, according to C++ PL 3rd ed, assignment has a higher precedence than
?:, so (unless there is a bug in cfront!) that is not what the compiler is
doing.  Now I cannot find a statement anywhere that prohibits the compiler
from evaluating BOTH the options (in an unspecified order), and returning
the appropriate one.  For example, the compiler might interpret the line as

int temp1 = (i = 1);
int temp2 = (i = 0);

i == 0 ? temp1 : temp2;

The above would also give the above behaviour.

Note that the compiler would also be free to produce the same results as
int temp2 = (i = 0);
int temp1 = (i = 1);
i == 0 ? temp1 : temp2;

and always set i = 1.  Or it could even hang at this point and start
reformatting your harddrive:-)

So I reckon it is probably undefined behaviour, so both compilers are
correct.

cheers,
ian mcculloch

PS shoot the person who wrote that line NOW!




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Barry Margolin <barmar@bbnplanet.com>
Date: 1999/02/16
Raw View
In article <36C986E2.4EEB74A@sensor.com>, Ron Natalie  <ron@sensor.com> wrote:
>Achim Bursian wrote:
>>
>> Hello, c++ standard gurus!
>> I have to maintain some code which contains the bad line
>>    i==0 ? i=1 : i=0;
>> Ok, let us not argue that this is bad, bad style. What the programmer
>> wanted to express seems to be  i ? 0 : 1;
>> But I have this line in the code, and my two compilers produce DIFFERENT
>> output from it:
>>
>> === The first one ====
>> // cfront==>  ((*((__1i == 0 )?( (__1i = 1 ), (& __1i )) :(& __1i ))))=
>
>CFRONT is giving you a big hint here.  ? bind tighter than =
>(despite an error in the table in Stroustrup's 3rd edition).
>What you have written means:
>
> ((i == 0) ? i = 1 : 0) = 0;
>
>Frankly, I'm not sure it should have even compiled.

Actually, shouldn't that be:

 ((i == 0) ? i = 1 : i) = 0;

Apparently the ?: operator is returning the lvalue, which the assignment
then assigns 0 to.

--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1999/02/17
Raw View
"Ian McCulloch" <ipm105@rsphy1.anu.edu.au> writes:

>Achim Bursian wrote in message <36C93553.97689C0C@erlf.siemens.de>...
>>Hello, c++ standard gurus!
>>I have to maintain some code which contains the bad line
>>   i==0 ? i=1 : i=0;
>>Ok, let us not argue that this is bad, bad style. What the programmer
>>wanted to express seems to be  i ? 0 : 1;
>>But I have this line in the code, and my two compilers produce DIFFERENT
>>output from it:

>One possibility is that cfront is interpreting the statement as

>(i == 0 ? i = 1 : i ) = 0;

>That is, the left side of the expression returns either i, or i after being
>assigned the value 1.  The right hand side of the expression sets the left
>side (ie i) to 0.

>However, according to C++ PL 3rd ed, assignment has a higher precedence than
>?:, so (unless there is a bug in cfront!) that is not what the compiler is
>doing.

In fact, the language definition has changed over time in the
interpretation of such expressions.

Originally, C++ followed the C syntax rule:
    conditional_expression:
 logical_or_expression
 logical_or_expression ? expression : conditional_expression

But C++ now has this syntax rule instead:
    conditional_expression:
 logical_or_expression
 logical_or_expression ? expression : assignment_expression

Also changed is the interpretation of the result. Now, if both
legs of the conditional_expression are lvalues, the result is
also an lvalue. You can now write
 b ? x : y = z
which will be interpreted the same as this version:
 *(b ? &x : &y) = z
Under the old rules, it would have been interpreted as
 b ? x : (y=z)

Evidently your two compilers don't implement the same version of
the rules for conditional expressions.

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Ron Natalie <ron@sensor.com>
Date: 1999/02/17
Raw View
Barry Margolin wrote:
>
> >
> >       ((i == 0) ? i = 1 : 0) = 0;
> >
> >Frankly, I'm not sure it should have even compiled.
>
> Actually, shouldn't that be:
>
>         ((i == 0) ? i = 1 : i) = 0;
>
> Apparently the ?: operator is returning the lvalue, which the assignment
> then assigns 0 to.
>
>
Yes, I mistyped the expression when I put the parens in.
As a result it's perferctly valid, the second and third
expression are lvalues.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: AllanW@my-dejanews.com
Date: 1999/02/17
Raw View
In article <36C93553.97689C0C@erlf.siemens.de>,
  bursian@bigfoot.de wrote:

> Hello, c++ standard gurus!
> I have to maintain some code which contains the bad line
>    i==0 ? i=1 : i=0;

This is equivalent to
    if (i != 0)
        i=0;
    else
        i=1;

> Ok, let us not argue that this is bad, bad style.

Okay. If this code actually has a purpose, I would be inclined to
change it to

    i = !i;

or else document why this was wrong.

> What the programmer wanted to express seems to be  i ? 0 : 1;

Well, now, this isn't the same at all. For one thing, it's an
expression statement with no side effects. Perhaps you meant

    i = i ? 0 : 1;

or else you meant it to be a snippet, as in

    if (i ? 0 : 1) { /* ... */ }

> But I have this line in the code, and my two compilers produce DIFFERENT
> output from it:
>
> === The first one ====
> // cfront==>  ((*((__1i == 0 )?( (__1i = 1 ), (& __1i )) :(& __1i ))))=
> 0 ;

This is different than either of the lines you listed above. This
version is equivalent to:

    int *p; // For exposition only
    if (__1i==0) {
        __1i = 1;
        p = & __1i;
    }
    else
    {
        p = & __1i;
    }
    (*p) = 0;

As shown below:

**** if (__1i == 0)
> //         CMP        DWORD PTR [EBP+8],0       ;__1i
> //         JNE        NEAR PTR L10004
****     __1i = 1;
> //         MOV        DWORD PTR [EBP+8],1       ;__1i
****     p = &__1i;
> //         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
**** else
> //         JMP        NEAR PTR L10005
> //      EVEN
> // L10004:
****     p = &__1i;
> //         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
> // L10005:
**** *p = 0;
> //         MOV        DWORD PTR [ECX],0
>
> As you see, the target i ALWAYS gets a 0 in the end! It is never 1 after
> the offending line.

That's because no matter which path is taken, p has the address of __1i,
and we always set *p=0.

> === The other compiler ===
> //    CODE32:00015E   09 C0                    OR    EAX,EAX
> //    CODE32:000160   75 07                    JNE   NEAR PTR   L20002
> //    CODE32:000162   B8 01 00 00 00           MOV   EAX,1
> //    CODE32:000167   EB 02                    JMP   NEAR PTR   L20003
> //                                   L20002:
> //    CODE32:000169   31 C0                    XOR   EAX,EAX
> //                                   L20003:
>
> Here, it is treated like  i ? 0 : 1

It seems to be. Depends on what happened just before this
snippet, and what happens next.

> Which compiler is right, according to the standard?

The second compiler seems to be correct, if the compiler has
"optimized" i to use register EAX, or if you pruned the code
tree a bit too far. Otherwise, neither one is correct because
the value of i is not set correctly.

----
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Rod Spade <rodspade@paonline.com>
Date: 1999/02/17
Raw View
My first guess would be that this is equivalent to
    i = !i;

Achim Bursian wrote:
>
> Hello, c++ standard gurus!
> I have to maintain some code which contains the bad line
>    i==0 ? i=1 : i=0;
> Ok, let us not argue that this is bad, bad style. What the programmer
> wanted to express seems to be  i ? 0 : 1;


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/02/17
Raw View
Achim Bursian wrote:
>
> Hello, c++ standard gurus!
> I have to maintain some code which contains the bad line
>    i==0 ? i=1 : i=0;

C/C++ is no longer described in terms of operator precedence. That
information is now described through the grammar itself. Here are the
grammar rules I used to parse your example:

Conditional expression:
 logical-or-expression ? expression : assignment-expression
logical-or-expression:
 logical-and-expression
logical-and-expression:
 inclusive-or-expression
inclusive-or-expression:
 exclusive-or-expression
exclusive-or-expression:
 and-expression
and-expression:
 equality-expression == relational-expression

Thus, the subject statement is equivalent to:

 (i==0) ? i=1 : i=0;

expression:
 assignment-expression
assignment-expression:
 logical-or-expression assignement-operator assignment-expression

Which means it's equivalent to:

 (i==0) ? (i=1) : (i=0);


Which is, as you said, a very clumsy way to write "i = i ? 0 : 1;"
....
> But I have this line in the code, and my two compilers produce DIFFERENT
> output from it:
>
> === The first one ====
> // cfront==>  ((*((__1i == 0 )?( (__1i = 1 ), (& __1i )) :(& __1i ))))=
> 0 ;

in other words:

 *( (i==0) ? (i=1,&i) : &i )=0

Which corresponds to parsing the original text as:

 ((i==0)?(i=1):i)=0

Which is incorrect, by my reading of the grammar.

....
> === The other compiler ===
....
> Here, it is treated like  i ? 0 : 1
> Which compiler is right, according to the standard?

I'd say it's the other compiler.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Ron Natalie <ron@sensor.com>
Date: 1999/02/17
Raw View
>
> One possibility is that cfront is interpreting the statement as
>
> (i == 0 ? i = 1 : i ) = 0;

It is and it is the correct thing to do.

> However, according to C++ PL 3rd ed, assignment has a higher precedence than
> ?:, so (unless there is a bug in cfront!) that is not what the compiler is
> doing.

Actually, the bug is in the book.  The assignment operators and
the conditional operators are listed backwards in the table on
page 121.  It was not Bjarne's intent to change the relative
ordering from the way it works in C.  It's in the errata.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Achim Bursian <abu@erlf.siemens.de>
Date: 1999/02/16
Raw View
Hello, c++ standard gurus!
I have to maintain some code which contains the bad line
   i==0 ? i=1 : i=0;
Ok, let us not argue that this is bad, bad style. What the programmer
wanted to express seems to be  i ? 0 : 1;
But I have this line in the code, and my two compilers produce DIFFERENT
output from it:

=== The first one ====
// cfront==>  ((*((__1i == 0 )?( (__1i = 1 ), (& __1i )) :(& __1i ))))=
0 ;
//         CMP        DWORD PTR [EBP+8],0       ;__1i
//         JNE        NEAR PTR L10004
//         MOV        DWORD PTR [EBP+8],1       ;__1i
//         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
//         JMP        NEAR PTR L10005
//      EVEN
// L10004:
//         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
// L10005:
//         MOV        DWORD PTR [ECX],0

As you see, the target i ALWAYS gets a 0 in the end! It is never 1 after
the offending line.

=== The other compiler ===
//    CODE32:00015E   09 C0                    OR    EAX,EAX
//    CODE32:000160   75 07                    JNE   NEAR PTR   L20002
//    CODE32:000162   B8 01 00 00 00           MOV   EAX,1
//    CODE32:000167   EB 02                    JMP   NEAR PTR   L20003
//                                   L20002:
//    CODE32:000169   31 C0                    XOR   EAX,EAX
//                                   L20003:

Here, it is treated like  i ? 0 : 1

Which compiler is right, according to the standard?


---
Achim Bursian / Siemens AG, A&D MC E35 / Tel.: +49-9131-98-3759
E-Mail: abu@erlf.siemens.de
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Jonathan H Lundquist" <fluxsmith@fluxsmith.com>
Date: 1999/02/16
Raw View
The meaning of the line given is:
if ( i == 0 )
   i = 1;
else
   i = 0;

The first compiler apparently has a code generation bug.

Achim Bursian <abu@erlf.siemens.de> wrote in message
>I have to maintain some code which contains the bad line
>   i==0 ? i=1 : i=0;
>...two compilers produce DIFFERENT
>output from it:
>
>=== The first one ====
>// cfront==>  ((*((__1i == 0 )?( (__1i = 1 ), (& __1i )) :(& __1i ))))=
>0 ;
>//         CMP        DWORD PTR [EBP+8],0       ;__1i
>//         JNE        NEAR PTR L10004
>//         MOV        DWORD PTR [EBP+8],1       ;__1i
>//         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
>//         JMP        NEAR PTR L10005
>//      EVEN
>// L10004:
>//         LEA        ECX,DWORD PTR [EBP+8]     ;__1i
>// L10005:
>//         MOV        DWORD PTR [ECX],0
>
>As you see, the target i ALWAYS gets a 0 in the end! It is never 1 after
>the offending line.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Ron Natalie <ron@sensor.com>
Date: 1999/02/16
Raw View
Achim Bursian wrote:
>
> Hello, c++ standard gurus!
> I have to maintain some code which contains the bad line
>    i==0 ? i=1 : i=0;
> Ok, let us not argue that this is bad, bad style. What the programmer
> wanted to express seems to be  i ? 0 : 1;
> But I have this line in the code, and my two compilers produce DIFFERENT
> output from it:
>
> === The first one ====
> // cfront==>  ((*((__1i == 0 )?( (__1i = 1 ), (& __1i )) :(& __1i ))))=

CFRONT is giving you a big hint here.  ? bind tighter than =
(despite an error in the table in Stroustrup's 3rd edition).
What you have written means:

 ((i == 0) ? i = 1 : 0) = 0;

Frankly, I'm not sure it should have even compiled.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Mike Smith" <kld_msmith@NOSPAMearthlink.net>
Date: 1999/02/16
Raw View
Achim Bursian wrote in message <36C93553.97689C0C@erlf.siemens.de>...
>Hello, c++ standard gurus!
>I have to maintain some code which contains the bad line
>   i==0 ? i=1 : i=0;
>Ok, let us not argue that this is bad, bad style. What the programmer
>wanted to express seems to be  i ? 0 : 1;

No, what the programmer wanted to express was

i = !i;

--
Mike Smith.  No, the other one.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]