This syntax regarding null checking baffles me
kdevel
kdevel at vogtner.de
Sun Jan 10 14:40:04 UTC 2021
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;
}
}
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; // null ref
if (c) writeln (1);
else writeln (0);
bar (c);
foo (c);
auto x = cast (bool) c; // crash as expected
}
```
$ ./null
0
2
4
Segmentation fault
BTW: Correctly using variables of class or in case below of AA
type
takes some getting used to. A few day ago I ran into a bug with a
helper
function "merge" in a context like this:
```ini.d
import std.stdio;
void merge(T) (T a, T b)
{
foreach (k, v; b) {
if (k in a)
throw new Exception ("key <" ~ k ~ "> already set");
a[k] = v;
}
}
void main ()
{
string[string] data;
data = ["a": "A"]; // <---- comment me out! (*)
auto other_data = ["x": "X"];
data.merge (other_data);
writeln (data);
}
```
As expected one gets:
$ dmd ini.d && ./ini
["a":"A", "x":"X"]
Now it happened that in the course of development there was a code
path in which data was not initialized (*). Guess what the output
was!
$ dmd ini.d && ./ini
[]
A void merge(T) (ref T a, T b) is required to cover the
uninitialzed
case. That was a rather surprising experience.
More information about the Digitalmars-d
mailing list