January 10, 2021 Re: This syntax regarding null checking baffles me | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Sunday, 10 January 2021 at 14:40:04 UTC, kdevel wrote:
> On Sunday, 10 January 2021 at 10:42:48 UTC, Jonathan M Davis wrote:
>
> [...]
>
>> IIRC, if the class overrides opCast for bool, then
>>
>> if(c)
>>
>> will cast the object to bool and use the result for the if condition,
>
> Well, no:
>
> ```null.d
> import std.stdio: writeln;
> class C {
> bool opCast ()
> {
> return true;
> }
> }
Your opCast has the wrong signature. It should be:
bool opCast(T : bool)()
|
January 10, 2021 Re: This syntax regarding null checking baffles me | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Sunday, 10 January 2021 at 16:44:29 UTC, Paul Backus wrote: [...] > Your opCast has the wrong signature. "Wrong" in what respect? > It should be: > > bool opCast(T : bool)() "My" opCast works as expected: ```null2.d import std.stdio: writeln; class C { int i; bool opCast () { __PRETTY_FUNCTION__.writeln; return true; } } void bar (C c) { if (c) writeln (3); else writeln (2); } void foo (ref C c) { if (c) writeln (5); else writeln (4); } void main () { C c = new C; writeln (c); if (c) writeln (1); else writeln (0); bar (c); foo (c); cast (bool) c; // print bool null2.C.opCast() c = null; cast (bool) c; // Segmentation fault } ``` $ dmd null2 && ./null2 null2.C 1 3 5 bool null2.C.opCast() Segmentation fault |
January 10, 2021 Re: This syntax regarding null checking baffles me | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 10 January 2021 at 10:42:48 UTC, Jonathan M Davis wrote: > IIRC, if the class overrides opCast for bool, then > > if(c) > > will cast the object to bool and use the result for the if condition, whereas > > if(c !is null) > > always checks whether the reference is null. You're misremembering. Or maybe it was changed since you last checked. A rewrite from `if (c)` to `if (c.opCast!bool)` "only happens, however, for instances of structs. Class references are converted to bool by checking to see if the class reference is null or not." https://dlang.org/spec/operatoroverloading.html#boolean_operators |
January 10, 2021 Re: This syntax regarding null checking baffles me | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Sunday, 10 January 2021 at 17:28:42 UTC, kdevel wrote: > On Sunday, 10 January 2021 at 16:44:29 UTC, Paul Backus wrote: > > [...] > >> Your opCast has the wrong signature. > > "Wrong" in what respect? > It does not match the signature required by the language spec: https://dlang.org/spec/operatoroverloading.html#cast |
January 10, 2021 Re: This syntax regarding null checking baffles me | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Sunday, 10 January 2021 at 19:21:47 UTC, Paul Backus wrote:
> On Sunday, 10 January 2021 at 17:28:42 UTC, kdevel wrote:
>> On Sunday, 10 January 2021 at 16:44:29 UTC, Paul Backus wrote:
>>
>> [...]
>>
>>> Your opCast has the wrong signature.
>>
>> "Wrong" in what respect?
>>
>
> It does not match the signature required by the language spec:
>
> https://dlang.org/spec/operatoroverloading.html#cast
Sure, but it is called anyway:
```null3.d
import std.stdio: writeln;
class C {
int i;
bool opCast ()
{
__PRETTY_FUNCTION__.writeln;
return false;
}
}
void main ()
{
C c = new C;
cast (bool) c; // print bool null3.C.opCast()
c = null;
cast (bool) c; // Segmentation fault
}
```
$ dmd null3 && ./null3
bool null3.C.opCast()
Segmentation fault
As ag0aep6g pointed out
if (c)
does not invoke the opCast member. Neither one of the signatures
bool opCast ()
T opCast (T: bool) ().
This "conversion to bool" [1] of the class variable seems to be not
programmatically accessible.
[1] "Class references are converted to bool by checking to see if the class reference is null or not." from § 20.2.1
|
January 11, 2021 Re: This syntax regarding null checking baffles me | ||||
---|---|---|---|---|
| ||||
Posted in reply to 12345swordy | On Thursday, 7 January 2021 at 04:57:55 UTC, 12345swordy wrote:
> if (c !is null) Why?????
>
> Would it be simpler to type
>
> if (c is not null)
>
> on a related note. Why are not we allowed to do this?
>
> if (c != null)
>
> when other languages such as c#/java allow for it?
>
> -Alex
One thing you could do is to make an "extension method", exploit ufcs and do like c.isNull instead.
Maybe those already exists somewhere.
For reference, in C# we have null-conditional and null-coalescing operators. Also, strings for example have string.IsNullOrEmpty and IsNullOrWhiteSpace, those are handy.
|
January 11, 2021 Re: This syntax regarding null checking baffles me | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On 1/10/21 4:52 PM, kdevel wrote: > On Sunday, 10 January 2021 at 19:21:47 UTC, Paul Backus wrote: >> On Sunday, 10 January 2021 at 17:28:42 UTC, kdevel wrote: >>> On Sunday, 10 January 2021 at 16:44:29 UTC, Paul Backus wrote: >>> >>> [...] >>> >>>> Your opCast has the wrong signature. >>> >>> "Wrong" in what respect? >>> >> >> It does not match the signature required by the language spec: >> >> https://dlang.org/spec/operatoroverloading.html#cast > > Sure, but it is called anyway: > > ```null3.d > import std.stdio: writeln; > class C { > int i; > bool opCast () > { > __PRETTY_FUNCTION__.writeln; > return false; > } > } > > void main () > { > C c = new C; > cast (bool) c; // print bool null3.C.opCast() > c = null; > cast (bool) c; // Segmentation fault > } > ``` > > $ dmd null3 && ./null3 > bool null3.C.opCast() > Segmentation fault > > As ag0aep6g pointed out > > if (c) > > does not invoke the opCast member. Neither one of the signatures > > bool opCast () > T opCast (T: bool) (). > > This "conversion to bool" [1] of the class variable seems to be not > programmatically accessible. > > [1] "Class references are converted to bool by checking to see if the class reference is null or not." from § 20.2.1 That's a relic from D1: https://digitalmars.com/d/1.0/operatoroverloading.html#Unary IMO, that functionality should not be used, but I doubt we will ever remove it. (I tested, and using this form works for if(s) for a struct) Note also that assert(c) will check the invariant of the object if it's not null. D has a few hidden behaviors for truthiness. -Steve |
Copyright © 1999-2021 by the D Language Foundation