On 11/18/2017 6:25 PM, Timon Gehr wrote:
I.e., baseClass should have type Nullable!ClassDeclaration. This does not in any
form imply that ClassDeclaration itself needs to have a null value.
Converting back and forth between the two types doesn't sound appealing.
What should the default initializer for a type do?
There should be none for non-nullable types.
I suspect you'd wind up needing to create an "empty" object just to satisfy that
requirement. Such as for arrays of objects, or objects with a cyclic graph.
Interestingly, `int` isn't nullable, and we routinely use rather ugly hacks to
fake it being nullable, like reserving a bit pattern like 0, -1 or 0xDEADBEEF
and calling it INVALID_VALUE, or carrying around some other separate flag that
says if it is valid or not. These are often rich sources of bugs.
As you can guess, I happen to like null, because there are no hidden bugs from
pretending it is a valid value - you get an immediate program halt - rather than
subtly corrupted results.
Yes, my own code has produced seg faults from erroneously assuming a value was
not null. But it wouldn't have been better with non-nullable types, since the
logic error would have been hidden and may have been much, much harder to
recognize and track down. I wish there was a null for int types. At least we
sort of have one for char types, 0xFF. And there's that lovely NaN for floating
point! Too bad it's woefully underused.
I found this out when testing my DFA (data flow analysis) algorithms.
void test(int i) {
int* p = null;
if (i) p = &i;
...
if (i) *p = 3;
...
}
Note that the code is correct, but DFA says the *p could be a null
dereference. (Replace (i) with any complex condition that there's no way the
DFA can prove always produces the same result the second time.)
Yes, there is a way. Put in an assertion. Of course, at that point you are
giving up, but this is not the common case.
An assertion can work, but doesn't it seem odd to require adding a runtime check
in order to get the code to compile?
(This is subtly different from the current use of assert(0) to flag unreachable
code.)
Also, you can often just write the
code in a way that the DFA will understand. We are doing this all the time in
statically-typed programming languages.
I didn't invent this case. I found it in real code; it happens often enough. The
cases are usually much more complex, I just posted the simplest reduction. I was
not in a position to tell the customer to restructure his code, though :-)