Thread overview
Equality operator chaining?
Nov 10, 2013
bearophile
Nov 10, 2013
Øivind
Nov 10, 2013
bearophile
Nov 10, 2013
Meta
Nov 10, 2013
bearophile
Nov 11, 2013
Walter Bright
Nov 11, 2013
Shammah Chancellor
November 10, 2013
Few days ago I have suggested a small language enhancement:
http://d.puremagic.com/issues/show_bug.cgi?id=11410


In Python this code is allowed:

>>> x = 3
>>> y = 4
>>> z = 5
>>> x < y < z
True



It is compilable in C too:


int main() {
    int x = 3;
    int y = 4;
    int z = 5;
    int b = x < y < z;
    return 0;
}


But GCC tells us with a warning that code doesn't work as expected by a Python programmer:

test.c:5:15: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
     int b = x < y < z;


So D disallows that code, giving:

test.d(5): Error: semicolon expected, not '<'
test.d(5): Error: found '<' instead of statement

- - - - - - - - - - - - - -

GCC accepts this code:


int main() {
    int x = 4;
    int y = 4;
    int z = 4;
    int b = x == y == z;
    return 0;
}


With a warning:

test.c:5:15: warning: suggest parentheses around comparison in operand of '=='
[-Wparentheses]
     int b = x == y == z;


While DMD refuses that code:

test.d(5): Error: semicolon expected, not '=='
test.d(5): Error: found '==' instead of statement


In D I find several situations where a chained equality is handy:

if (n == foo(n) == bar(n) && ...

It avoids code like this, that needs an auxiliary variable:

aux = foo(n);
if (n == aux && aux == bar(n) && ...


Is this idea going to cause troubles with operator overloading or something else? Do you like it? Is it important enough?

Bye,
bearophile
November 10, 2013
>     int b = x == y == z;

Although GCC accepts the code, I don't think it does what you think here. It will basically z will be compared with '1', which is the value of (4 == 4), and b will become 0, or false.





November 10, 2013
Øivind:

> Although GCC accepts the code, I don't think it does what you think here. It will basically z will be compared with '1', which is the value of (4 == 4), and b will become 0, or false.

OK, so it's like in the chained < comparisons.

So I presume D disallows the chained equality for the same reasons it disallows the chained < comparisons.

Bye,
bearophile
November 10, 2013
On Sunday, 10 November 2013 at 19:32:58 UTC, bearophile wrote:
> Øivind:
>
>> Although GCC accepts the code, I don't think it does what you think here. It will basically z will be compared with '1', which is the value of (4 == 4), and b will become 0, or false.
>
> OK, so it's like in the chained < comparisons.
>
> So I presume D disallows the chained equality for the same reasons it disallows the chained < comparisons.
>
> Bye,
> bearophile

I was re-reading TDPL recently, and Andrei explicitly mentions this. The reason D disables this instead of allowing it is because it was deemed a bad idea to allow the code to compile with different semantics than the equivalent C code.
November 10, 2013
Meta:

> I was re-reading TDPL recently, and Andrei explicitly mentions this. The reason D disables this instead of allowing it is because it was deemed a bad idea to allow the code to compile with different semantics than the equivalent C code.

I understand, I close down the ER...

Bye,
bearophile
November 11, 2013
On 2013-11-10 18:45:14 +0000, bearophile said:
> It avoids code like this, that needs an auxiliary variable:
> 
> aux = foo(n);
> if (n == aux && aux == bar(n) && ...
> 
> 
> Is this idea going to cause troubles with operator overloading or something else? Do you like it? Is it important enough?
> 
> Bye,
> bearophile

if( n == (foo(n) == bar(n)))  is legal.

November 11, 2013
On 11/10/2013 11:08 AM, "Øivind" wrote:
>>     int b = x == y == z;
>
> Although GCC accepts the code, I don't think it does what you think here. It
> will basically z will be compared with '1', which is the value of (4 == 4), and
> b will become 0, or false.

Which is exactly why D rejects this code.

And, if D accepted the code, but gave it Python semantics, then C code that did work would silently break.

So no, D's behavior should not be changed.

(This is an old topic, we've gone over it before.)