Jump to page: 1 2
Thread overview
Lots of bool operations shouldn't compile
Feb 28, 2006
Don Clugston
Feb 28, 2006
Oskar Linde
Feb 28, 2006
Don Clugston
Feb 28, 2006
Oskar Linde
Mar 01, 2006
Don Clugston
Mar 02, 2006
Thomas Kuehne
Mar 02, 2006
Thomas Kuehne
Mar 02, 2006
Don Clugston
Mar 02, 2006
Kyle Furlong
Mar 02, 2006
Don Clugston
Mar 03, 2006
Kyle Furlong
Mar 03, 2006
Don Clugston
Mar 03, 2006
Thomas Kuehne
Mar 01, 2006
Kyle Furlong
February 28, 2006
Four examples, although it's only one bug. Almost all operations on bool should be disabled, but I found the ones below a little amusing. None of them should compile, but they all evaluate as "true".

void main()
{
    if (true >= ireal.nan) { writefln("This is kind of ridiculous"); }
    if (false >= ireal.nan) { writefln("This is kind of ridiculous"); }
    if (true <> -2i) { writefln("NCEG operators too ??!!"); }
    if (false != -2i) { writefln("and again"); }
}
February 28, 2006
Don Clugston skrev:
> Four examples, although it's only one bug. Almost all operations on bool should be disabled, but I found the ones below a little amusing. None of them should compile, but they all evaluate as "true".
> 
> void main()
> {
>     if (true >= ireal.nan) { writefln("This is kind of ridiculous"); }
>     if (false >= ireal.nan) { writefln("This is kind of ridiculous"); }
>     if (true <> -2i) { writefln("NCEG operators too ??!!"); }
>     if (false != -2i) { writefln("and again"); }
> }

According to the specification, booleans are a numeric type. true == 1 and false == 0. So this error is not specific to bool.

Try s/true/1/g and s/false/0/g and you will get the same results.

The first two comparisons should be false I guess since they are unordered. The other two are correct.

(If it is wise to have bool as a numeric type is a different question.)

/Oskar


February 28, 2006
Oskar Linde wrote:
> Don Clugston skrev:
>> Four examples, although it's only one bug. Almost all operations on bool should be disabled, but I found the ones below a little amusing. None of them should compile, but they all evaluate as "true".
>>
>> void main()
>> {
>>     if (true >= ireal.nan) { writefln("This is kind of ridiculous"); }
>>     if (false >= ireal.nan) { writefln("This is kind of ridiculous"); }
>>     if (true <> -2i) { writefln("NCEG operators too ??!!"); }
>>     if (false != -2i) { writefln("and again"); }
>> }
> 
> According to the specification, booleans are a numeric type. true == 1 and false == 0. So this error is not specific to bool.
> 
> Try s/true/1/g and s/false/0/g and you will get the same results.
> 
> The first two comparisons should be false I guess since they are unordered. The other two are correct.

OK, there's another bug in there, comparing an int with an imaginary real should also not be legal.

    if (1 > -2i) { assert(0); }
    if (1 > ireal.nan) { assert(0); }

Reals and ireals cannot be compared. Ever.

> (If it is wise to have bool as a numeric type is a different question.)

I think it's very hard to justify numeric operations on bools.
(which is an _entirely_ different issue to implicit "!is null" in conditionals, I wholeheartedly support if (p), while(1){} and assert(0) ).
But I note that
bool b = 7;
is currently disallowed, while
b+=5;
compiles.
There's no reason to write b++, it's just letting bugs in. Write b=true instead. I hope that all such bug-breeding nonsense disappears. With a one bit integer, it wasn't clear how such things should behave (every other integral types wraps around, so b=5 should mean b=0 -- yuck!), but hopefully it can be cleared up now.

February 28, 2006
Don Clugston skrev:
> Oskar Linde wrote:
>> Don Clugston skrev:
>>> Four examples, although it's only one bug. Almost all operations on bool should be disabled, but I found the ones below a little amusing. None of them should compile, but they all evaluate as "true".
>>>
>>> void main()
>>> {
>>>     if (true >= ireal.nan) { writefln("This is kind of ridiculous"); }
>>>     if (false >= ireal.nan) { writefln("This is kind of ridiculous"); }
>>>     if (true <> -2i) { writefln("NCEG operators too ??!!"); }
>>>     if (false != -2i) { writefln("and again"); }
>>> }
>>
>> According to the specification, booleans are a numeric type. true == 1 and false == 0. So this error is not specific to bool.
>>
>> Try s/true/1/g and s/false/0/g and you will get the same results.
>>
>> The first two comparisons should be false I guess since they are unordered. The other two are correct.
> 
> OK, there's another bug in there, comparing an int with an imaginary real should also not be legal.
> 
>     if (1 > -2i) { assert(0); }
>     if (1 > ireal.nan) { assert(0); }
> 
> Reals and ireals cannot be compared. Ever.

You are right. I didn't notice.

> 
>> (If it is wise to have bool as a numeric type is a different question.)
> 
> I think it's very hard to justify numeric operations on bools.
> (which is an _entirely_ different issue to implicit "!is null" in conditionals, I wholeheartedly support if (p), while(1){} and assert(0) ).
> But I note that
> bool b = 7;
> is currently disallowed, while
> b+=5;
> compiles.
> There's no reason to write b++, it's just letting bugs in. Write b=true instead. I hope that all such bug-breeding nonsense disappears. With a one bit integer, it wasn't clear how such things should behave (every other integral types wraps around, so b=5 should mean b=0 -- yuck!), but hopefully it can be cleared up now.

I fully agree.

(But note that the current D bool is (sans bugs) semantically identical (as far as I can tell) to C99 and C++ bool, who both allows b+=5, et.al.)

/Oskar
March 01, 2006
Don Clugston wrote:
> Four examples, although it's only one bug. Almost all operations on bool should be disabled, but I found the ones below a little amusing. None of them should compile, but they all evaluate as "true".
> 
> void main()
> {
>     if (true >= ireal.nan) { writefln("This is kind of ridiculous"); }
>     if (false >= ireal.nan) { writefln("This is kind of ridiculous"); }
>     if (true <> -2i) { writefln("NCEG operators too ??!!"); }
>     if (false != -2i) { writefln("and again"); }
> }

This kind of absurdity is exactly what Derek and others of us have been arguing against. These are a direct result of a non type safe boolean.
March 01, 2006
Oskar Linde wrote:

> (But note that the current D bool is (sans bugs) semantically identical (as far as I can tell) to C99 and C++ bool, who both allows b+=5, et.al.)

I just tried that in MSVC, and you're right. I didn't know that. It's probably a legacy of the pre-bool days when ints or BOOL were used. In practice, I doubt it's really much of a problem. But there doesn't seem to be any rational reason to allow them.

BTW, MSVC accepts
bool b = true;
b /= false;  // crashes at run time with a div by zero error
but gives a warning for
bool b = true/false; // Can this be constant folded? What the heck does it set it to?

Also accepts b/=6.5;
Wonder what b/=real.nan does.
March 02, 2006
Don Clugston schrieb am 2006-02-28:

[snip]

> OK, there's another bug in there, comparing an int with an imaginary real should also not be legal.
>
>      if (1 > -2i) { assert(0); }
>      if (1 > ireal.nan) { assert(0); }
>
> Reals and ireals cannot be compared. Ever.

Sure you can. Floats and imaginary floats can both be implicitly promoted to complex floats.

# import std.stdio;
#
# int main(){
#     creal a = 1;
#     creal b = 1i;
#
#     writefln("a: %s", a);
#     writefln("b: %s", b);
#
#     writefln("1 == 1i: %s", (1 == 1i) ? true : false);
#     writefln("1 == 0i: %s", (1 == 0i) ? true : false);
#     writefln("0 == 1i: %s", (1 == 0i) ? true : false);
#     writefln("0 == 0i: %s", (0 == 0i) ? true : false);
#
#     return 0;
# }

Thus

>      if (1 > -2i) { assert(0); }
>      if (1 > ireal.nan) { assert(0); }

are interpreted as

>      if (1 + 0i > 0 - 2i) { ... }
>      if (1 + 0i > 0 + ireal.nan) { ... }

The remaining question is: Is the second example unordered (due to the
inan) or ordered?

std.typeinfo.ti_creal._compare(creal, creal): ordered
std.conv.feq(creal, creal): unordered

http://www.digitalmars.com/d/float.html seems silent on this regard.

Thomas


March 02, 2006
Don Clugston schrieb am 2006-03-01:
> Oskar Linde wrote:
>
>> (But note that the current D bool is (sans bugs) semantically identical (as far as I can tell) to C99 and C++ bool, who both allows b+=5, et.al.)
>
> I just tried that in MSVC, and you're right. I didn't know that. It's probably a legacy of the pre-bool days when ints or BOOL were used. In practice, I doubt it's really much of a problem. But there doesn't seem to be any rational reason to allow them.
>
> BTW, MSVC accepts
> bool b = true;
> b /= false;  // crashes at run time with a div by zero error
> but gives a warning for
> bool b = true/false; // Can this be constant folded? What the heck does
> it set it to?
>
> Also accepts b/=6.5;
> Wonder what b/=real.nan does.

That's interresting:

b /= 6.5; // compiles
b = b / 6.5; // fails to compile

Bool is an integer type and thus floats are not implicitly converted to integral types.

Added to DStress as http://dstress.kuehne.cn/nocompile/o/opAddAssign_19_A.d http://dstress.kuehne.cn/nocompile/o/opAddAssign_19_B.d http://dstress.kuehne.cn/nocompile/o/opAddAssign_19_C.d http://dstress.kuehne.cn/nocompile/o/opAddAssign_19_D.d http://dstress.kuehne.cn/nocompile/o/opAddAssign_19_E.d http://dstress.kuehne.cn/nocompile/o/opAddAssign_19_F.d http://dstress.kuehne.cn/nocompile/o/opAdd_09_A.d http://dstress.kuehne.cn/nocompile/o/opAdd_09_B.d http://dstress.kuehne.cn/nocompile/o/opAdd_09_C.d http://dstress.kuehne.cn/nocompile/o/opAdd_09_D.d http://dstress.kuehne.cn/nocompile/o/opAdd_09_E.d http://dstress.kuehne.cn/nocompile/o/opAdd_09_F.d http://dstress.kuehne.cn/nocompile/o/opDivAssign_19_A.d http://dstress.kuehne.cn/nocompile/o/opDivAssign_19_B.d http://dstress.kuehne.cn/nocompile/o/opDivAssign_19_C.d http://dstress.kuehne.cn/nocompile/o/opDivAssign_19_D.d http://dstress.kuehne.cn/nocompile/o/opDivAssign_19_E.d http://dstress.kuehne.cn/nocompile/o/opDivAssign_19_F.d http://dstress.kuehne.cn/nocompile/o/opDiv_14_A.d http://dstress.kuehne.cn/nocompile/o/opDiv_14_B.d http://dstress.kuehne.cn/nocompile/o/opDiv_14_C.d http://dstress.kuehne.cn/nocompile/o/opDiv_14_D.d http://dstress.kuehne.cn/nocompile/o/opDiv_14_E.d http://dstress.kuehne.cn/nocompile/o/opDiv_14_F.d http://dstress.kuehne.cn/nocompile/o/opMulAssign_19_A.d http://dstress.kuehne.cn/nocompile/o/opMulAssign_19_B.d http://dstress.kuehne.cn/nocompile/o/opMulAssign_19_C.d http://dstress.kuehne.cn/nocompile/o/opMulAssign_19_D.d http://dstress.kuehne.cn/nocompile/o/opMulAssign_19_E.d http://dstress.kuehne.cn/nocompile/o/opMulAssign_19_F.d http://dstress.kuehne.cn/nocompile/o/opMul_09_A.d http://dstress.kuehne.cn/nocompile/o/opMul_09_B.d http://dstress.kuehne.cn/nocompile/o/opMul_09_C.d http://dstress.kuehne.cn/nocompile/o/opMul_09_D.d http://dstress.kuehne.cn/nocompile/o/opMul_09_E.d http://dstress.kuehne.cn/nocompile/o/opMul_09_F.d http://dstress.kuehne.cn/nocompile/o/opSubAssign_19_A.d http://dstress.kuehne.cn/nocompile/o/opSubAssign_19_B.d http://dstress.kuehne.cn/nocompile/o/opSubAssign_19_C.d http://dstress.kuehne.cn/nocompile/o/opSubAssign_19_D.d http://dstress.kuehne.cn/nocompile/o/opSubAssign_19_E.d http://dstress.kuehne.cn/nocompile/o/opSubAssign_19_F.d http://dstress.kuehne.cn/nocompile/o/opSub_09_A.d http://dstress.kuehne.cn/nocompile/o/opSub_09_B.d http://dstress.kuehne.cn/nocompile/o/opSub_09_C.d http://dstress.kuehne.cn/nocompile/o/opSub_09_D.d http://dstress.kuehne.cn/nocompile/o/opSub_09_E.d http://dstress.kuehne.cn/nocompile/o/opSub_09_F.d

Thomas


March 02, 2006
Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Don Clugston schrieb am 2006-02-28:
> 
> [snip]
> 
>> OK, there's another bug in there, comparing an int with an imaginary real should also not be legal.
>>
>>      if (1 > -2i) { assert(0); }
>>      if (1 > ireal.nan) { assert(0); }
>>
>> Reals and ireals cannot be compared. Ever.
> 
> Sure you can. Floats and imaginary floats can both be implicitly promoted
> to complex floats.

That only gives you == and !=.

<snip>
> Thus
> 
>>      if (1 > -2i) { assert(0); }
>>      if (1 > ireal.nan) { assert(0); }
> 
> are interpreted as
> 
>>      if (1 + 0i > 0 - 2i) { ... }
>>      if (1 + 0i > 0 + ireal.nan) { ... }

Yes, but that still doesn't work, there's no > for complex numbers.
Is  2 - 3i > 3 - 2i ?
March 02, 2006
Don Clugston wrote:
> Thomas Kuehne wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Don Clugston schrieb am 2006-02-28:
>>
>> [snip]
>>
>>> OK, there's another bug in there, comparing an int with an imaginary real should also not be legal.
>>>
>>>      if (1 > -2i) { assert(0); }
>>>      if (1 > ireal.nan) { assert(0); }
>>>
>>> Reals and ireals cannot be compared. Ever.
>>
>> Sure you can. Floats and imaginary floats can both be implicitly promoted
>> to complex floats.
> 
> That only gives you == and !=.
> 
> <snip>
>> Thus
>>
>>>      if (1 > -2i) { assert(0); }
>>>      if (1 > ireal.nan) { assert(0); }
>>
>> are interpreted as
>>
>>>      if (1 + 0i > 0 - 2i) { ... }
>>>      if (1 + 0i > 0 + ireal.nan) { ... }
> 
> Yes, but that still doesn't work, there's no > for complex numbers.
> Is  2 - 3i > 3 - 2i ?

One could speak of their magnitudes, I suppose.

creal i = 2 - 3i;
creal j = 3 - 2i;

real i_m = sqrt(i * complexConjugate(i));
real j_m = sqrt(j * complexConjugate(j));

but then I guess you are just comparing reals.
« First   ‹ Prev
1 2