October 11, 2018
On Thursday, October 11, 2018 8:35:34 AM MDT James Japherson via Digitalmars-d 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.

When parens are used to affect operator precedence, it's _always_ by enclosing the expression. There may be a language out there that does it a different way, but if so, I've never heard of it. Certainly, major languages like C, C++, Java, and C# all do it the way that D does, and they all have the same kind of precedence for the ternary operator that D does. I honestly have no clue how you could ever have gotten the idea that putting parens in front of something could affect operator precedence, since I don't think that I've ever seen anything work that way in any language ever.

By putting the parens around (B == 0), you've told the compiler to treat that as a single expression regardless of what operator precendence would otherwise do. You haven't told it to do anything to any other operators. So,

A + B == 0

has gone from being equivalent to

(A + B) == 0

to

A + (B == 0)

but that has no effect whatsoever on the ternary operator or any other operator that has lower precedence. So, really, it seems to me that your misunderstanding of operator precedence and parens goes well beyond the ternary operator. Normally, if someone were going to be confused by the operator precedence of the ternary operator, I'd expect them to be confused about the precendence of stuff that happens to the right of the ternary operator when it's in a more complicated expression, not about what happens with parens used in the condition. That stuff is the same as you'd get in any if statement or while loop condition.

- Jonathan M Davis



October 11, 2018
On 10/11/18 7:17 PM, Jonathan Marler wrote:

> 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:
> 

Not in my C/D code. It would have copious parentheses everywhere :)

That case is actually very strange, I don't know if it's something that's really common.

-Steve
October 12, 2018
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;

That's why shouldn't compose it like that.
It's been a constant source of bugs in C/C++ code:
https://www.viva64.com/en/b/0583/#ID0E1CAC
October 12, 2018
On Thursday, 11 October 2018 at 23:29:05 UTC, Steven Schveighoffer wrote:
> On 10/11/18 7:17 PM, Jonathan Marler wrote:
>
>> 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:
>> 
>
> Not in my C/D code. It would have copious parentheses everywhere :)
>

Good :)

> That case is actually very strange, I don't know if it's something that's really common.
>

Yes, that explains why myself, Jonathan Davis and certainly others didn't know there were actually differences between C++ and D Operator precedence :)  I wasn't sure myself but having a quick look at each's operator precedence table made it easy to find an expression that behaves differently in both.

October 11, 2018
On 10/11/18 9:16 PM, Jonathan Marler wrote:
> On Thursday, 11 October 2018 at 23:29:05 UTC, Steven Schveighoffer wrote:
>> On 10/11/18 7:17 PM, Jonathan Marler wrote:
>>
>>> 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:
>>>
>>
>> Not in my C/D code. It would have copious parentheses everywhere :)
>>
> 
> Good :)

Yep. General rule of thumb for me after having been burned many many times -- Always use parentheses to define order of operations when dealing with bitwise operations (and, or, xor) and for the ternary operator.

I think I do make an exception when it's a simple assignment. i.e.:

a = cond ? 1 : 2;

> 
>> That case is actually very strange, I don't know if it's something that's really common.
>>
> 
> Yes, that explains why myself, Jonathan Davis and certainly others didn't know there were actually differences between C++ and D Operator precedence :)  I wasn't sure myself but having a quick look at each's operator precedence table made it easy to find an expression that behaves differently in both.
> 

I actually was curious whether DMC followed the rules (hey, maybe Walter just copied his existing code!), but it does follow C's rules.

-Steve
October 12, 2018
On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler wrote:
> 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)

That's https://issues.dlang.org/show_bug.cgi?id=14186
October 12, 2018
On 10/12/18 6:06 AM, Kagamin wrote:
> On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler wrote:
>> 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)
> 
> That's https://issues.dlang.org/show_bug.cgi?id=14186

Wow, interesting that C precedence is different from C++ here.

-Steve
October 12, 2018
On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler wrote:
> 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:
>>> > [...]
>>>
>>> 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.

Please do not conflate C and C++. It is specifically on order of precedence of the ternary that the 2 languages differ. It is C++ and only C++ which has the unconventionnal order of precedence where the ternary has the same priority as the assign operators. ALL other C derived languages have a higher priority for the ternary than the assignments.
October 12, 2018
On Thursday, 11 October 2018 at 23:17:57 UTC, Jonathan M Davis wrote:
> On Thursday, October 11, 2018 8:35:34 AM MDT James Japherson via Digitalmars-d wrote:

> Certainly, major languages like C, C++, Java, and C# all do it the way that D does, and they all have the same kind of precedence for the ternary operator that D does.

No, the off man out is C++. it's the only one with the priority of the ternary equal to assignments. All other languages do it like C, i.e. with a higher priority for ?:

C++ is the annoying one (as always) here.
October 12, 2018
On Friday, 12 October 2018 at 13:15:22 UTC, Steven Schveighoffer wrote:
> On 10/12/18 6:06 AM, Kagamin wrote:
>> On Thursday, 11 October 2018 at 23:17:15 UTC, Jonathan Marler wrote:
>>> [...]
>> 
>> That's https://issues.dlang.org/show_bug.cgi?id=14186
>
> Wow, interesting that C precedence is different from C++ here.
>

It's C++ which the anormal one.