This syntax regarding null checking baffles me

Steven Schveighoffer schveiguy at gmail.com
Mon Jan 11 13:56:33 UTC 2021


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


More information about the Digitalmars-d mailing list