D Logic bug

Jonathan Marler johnnymarler at gmail.com
Thu Oct 11 23:17:15 UTC 2018


On Thursday, 11 October 2018 at 21:57:00 UTC, Jonathan M Davis 
wrote:
> On Thursday, October 11, 2018 1:09:14 PM MDT Jonathan Marler 
> via Digitalmars-d wrote:
>> On Thursday, 11 October 2018 at 14:35:34 UTC, James Japherson
>>
>> wrote:
>> > Took me about an hour to track this one down!
>> >
>> > A + (B == 0) ? 0 : C;
>> >
>> > D is evaluating it as
>> >
>> > (A + (B == 0)) ? 0 : C;
>> >
>> >
>> > The whole point of the parenthesis was to associate.
>> >
>> > I usually explicitly associate precisely because of this!
>> >
>> > A + ((B == 0) ? 0 : C);
>> >
>> > In the ternary operator it should treat parenthesis directly 
>> > to the left as the argument.
>> >
>> > Of course, I doubt this will get fixed but it should be 
>> > noted so other don't step in the same poo.
>>
>> In c++ the ternary operator is the second most lowest 
>> precedence operator, just above the comma.  You can see a 
>> table of each operator and their precendence here, I refer to 
>> it every so often: 
>> https://en.cppreference.com/w/cpp/language/operator_precedence
>>
>> Learning that the ternary operator has such a low precedence 
>> is one of those things that all programmers eventually run 
>> into...welcome to the club :)
>>
>> It looks like D has a similar table here 
>> (https://wiki.dlang.org/Operator_precedence).  However, it 
>> doesn't appear to have the ternary operator in there. On that 
>> note, D would take it's precedence order from C/C++ unless 
>> there's a VERY good reason to change it.
>
> The operator precedence matches in D. Because in principle, C 
> code should either be valid D code with the same semantics as 
> it had in C, or it shouldn't compile as D code, changing 
> operator precedence isn't something that D is going to do 
> (though clearly, the ternary operator needs to be added to the 
> table). It would be a disaster for porting code if we did.
>
> - Jonathan M Davis

I had a look at the table again, looks like the ternary operator 
is on there, just called the "conditional operator".  And to 
clarify, D's operator precedence is close to C/C++ but doesn't 
match exactly.  This is likely a result of the grammar 
differences rather than an intention one.  For example, the 
"Conditional operator" in D actually has a higher priority than 
an assignment, but in C++ it's the same and is evaluated 
right-to-left.  So this expression would be different in C++ and 
D:

a ? b : c = d

In D it would be:

(a ? b : c ) = d

And in C++ would be:

a ? b : (c = d)

Check it out:

---
import core.stdc.stdio;
void main()
{
     int a = 2, b = 3;
     printf("expr = %d\n", 1 ? a : b = 4);
}
---
prints "expr = 4"

it evaluates the conditional (1 ? a : b) into the expression a, 
which is actually an rvalue! and then assigns it to 4 because of 
the "= 4" and then returns the value 4 to printf.

Here's the C++ version:

#include <stdio.h>

int main(int argc, char *argv[])
{
     int a = 2, b = 3;
     printf("expr = %d\n", 1 ? a : b = 4);
}

This one prints "expr = 2"

It simply returns the value of `a` because the "b = 4" at the end 
is all part of the "else" contition in the ternary operator.



More information about the Digitalmars-d mailing list