Thread overview
dmd-2.067.0-b1
Feb 13, 2015
Dennis Ritchie
Feb 13, 2015
tcak
Feb 13, 2015
anonymous
Feb 13, 2015
Dennis Ritchie
Feb 13, 2015
Gary Willoughby
Feb 14, 2015
RuZzz
February 13, 2015
This is a bug?

import std.stdio;

void main() {
    int a = 0;

    writeln( (a < 10) ? a = 1 : a = 2 );    // prints 2

    writeln( (a < 10) ? a = 1 : (a = 2) );  // prints 1
}

Even C++ output:
1
1
February 13, 2015
On Friday, 13 February 2015 at 09:38:04 UTC, Dennis Ritchie wrote:
> This is a bug?
>
> import std.stdio;
>
> void main() {
>     int a = 0;
>
>     writeln( (a < 10) ? a = 1 : a = 2 );    // prints 2
>
>     writeln( (a < 10) ? a = 1 : (a = 2) );  // prints 1
> }
>
> Even C++ output:
> 1
> 1

About 2 years ago, I had a problem with similar structure.

My guess is that the first one is accepted as this.

((a < 10) ? a = 1 : a)   =   ( 2 )

Thereby it gives this result. Vague definitions are always error prone.
February 13, 2015
On 2/13/15 7:38 AM, tcak wrote:
> On Friday, 13 February 2015 at 09:38:04 UTC, Dennis Ritchie wrote:
>> This is a bug?
>>
>> import std.stdio;
>>
>> void main() {
>>     int a = 0;
>>
>>     writeln( (a < 10) ? a = 1 : a = 2 );    // prints 2
>>
>>     writeln( (a < 10) ? a = 1 : (a = 2) );  // prints 1
>> }
>>
>> Even C++ output:
>> 1
>> 1
>
> About 2 years ago, I had a problem with similar structure.
>
> My guess is that the first one is accepted as this.
>
> ((a < 10) ? a = 1 : a)   =   ( 2 )
>
> Thereby it gives this result. Vague definitions are always error prone.

Yes, the operator precedence (curiously not defined in the spec) is here:

http://wiki.dlang.org/Operator_precedence

Conditional operator is above assignment operators.

C++ operator precedence is here:

http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

Note they are the same, but I think C++ ?: = operator in this case does not result in lvalue. So it must be that the = cannot bind to the result of the operator, therefore it binds to the a. Interesting...

-Steve
February 13, 2015
On Friday, 13 February 2015 at 13:25:55 UTC, Steven Schveighoffer wrote:
> Yes, the operator precedence (curiously not defined in the spec) is here:
>
> http://wiki.dlang.org/Operator_precedence
>
> Conditional operator is above assignment operators.

It's specified through the grammar [1]:

----
AssignExpression:
    ConditionalExpression
    ConditionalExpression = AssignExpression
    [...]

ConditionalExpression:
    OrOrExpression
    OrOrExpression ? Expression : ConditionalExpression
----

The third operand of ConditionalExpression cannot be an AssignExpression without parentheses.

So `foo ? bar : baz = qux` can only be interpreted as `(foo ? bar : baz) = qux`.

[1] http://dlang.org/expression.html
February 13, 2015
On Friday, 13 February 2015 at 09:38:04 UTC, Dennis Ritchie wrote:
> This is a bug?
>
> import std.stdio;
>
> void main() {
>     int a = 0;
>
>     writeln( (a < 10) ? a = 1 : a = 2 );    // prints 2
>
>     writeln( (a < 10) ? a = 1 : (a = 2) );  // prints 1
> }
>
> Even C++ output:
> 1
> 1

Maybe a similar issue as this: http://forum.dlang.org/thread/wlpmjgbkdzcyuuyafzwk@forum.dlang.org
February 13, 2015
On Friday, 13 February 2015 at 13:25:55 UTC, Steven Schveighoffer wrote:
> On 2/13/15 7:38 AM, tcak wrote:
>> On Friday, 13 February 2015 at 09:38:04 UTC, Dennis Ritchie wrote:
>>> This is a bug?
>>>
>>> import std.stdio;
>>>
>>> void main() {
>>>    int a = 0;
>>>
>>>    writeln( (a < 10) ? a = 1 : a = 2 );    // prints 2
>>>
>>>    writeln( (a < 10) ? a = 1 : (a = 2) );  // prints 1
>>> }
>>>
>>> Even C++ output:
>>> 1
>>> 1
>>
>> About 2 years ago, I had a problem with similar structure.
>>
>> My guess is that the first one is accepted as this.
>>
>> ((a < 10) ? a = 1 : a)   =   ( 2 )
>>
>> Thereby it gives this result. Vague definitions are always error prone.
>
> Yes, the operator precedence (curiously not defined in the spec) is here:
>
> http://wiki.dlang.org/Operator_precedence
>
> Conditional operator is above assignment operators.
>
> C++ operator precedence is here:
>
> http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence
>
> Note they are the same, but I think C++ ?: = operator in this case does not result in lvalue. So it must be that the = cannot bind to the result of the operator, therefore it binds to the a. Interesting...
>
> -Steve

Thanks.
February 13, 2015
On 2/13/15 9:01 AM, anonymous wrote:
> On Friday, 13 February 2015 at 13:25:55 UTC, Steven Schveighoffer wrote:
>> Yes, the operator precedence (curiously not defined in the spec) is here:
>>
>> http://wiki.dlang.org/Operator_precedence
>>
>> Conditional operator is above assignment operators.
>
> It's specified through the grammar [1]:
>
> ----
> AssignExpression:
>      ConditionalExpression
>      ConditionalExpression = AssignExpression
>      [...]
>
> ConditionalExpression:
>      OrOrExpression
>      OrOrExpression ? Expression : ConditionalExpression
> ----
>
> The third operand of ConditionalExpression cannot be an AssignExpression
> without parentheses.
>
> So `foo ? bar : baz = qux` can only be interpreted as `(foo ? bar : baz)
> = qux`.
>
> [1] http://dlang.org/expression.html

Right, but C++ seems to treat it differently, but has the same order of precedence. It seems that C++ can do lvalues as a result of assignment, but for some reason it doesn't do the same as D.

Indeed, if you do:

(a < 10) ? 5 : a = 1;

In D, this results in an error, in C++, this just results in the rvalue 5.

OK, so I just looked for more information, and found that in some references, the ?: is given the same precedence as the assignment operator (and ordered right to left), which would explain the behavior. So likely the wikipedia reference is just wrong.

e.g.: http://en.cppreference.com/w/cpp/language/operator_precedence

Walter (or other language gurus), any reason that D does it this way? The C++ way seems more natural to me.

-Steve
February 14, 2015
It is your profile?
http://www.cyberforum.ru/members/491746.html