null [re: spec#]
Roman Ivanov
isroman.DEL at ETE.km.ru
Sun Nov 7 07:53:42 PST 2010
On 11/7/2010 10:51 AM, Roman Ivanov wrote:
> On 11/7/2010 1:02 AM, Walter Bright wrote:
>> Jonathan M Davis wrote:
>>> Going C# or Java's route forces the programmer to initialize variables
>>> even in cases where they know that it's not necessary (which is
>>> annoying but may or may not be worth it),
>>
>> Correct. It's not that doing flow analysis is hard, it's that it's
>> impossible to do it correctly. So you wind up with wishy-washy messages
>> that p "might not" be initialized, which is what the Java compiler does
>> for this:
>>
>> class A
>> {
>> public void foo()
>> {
>> Object p;
>> if (m)
>> p = new Object();
>> if (m)
>> p.toString(); // <-- p might not have been initialized
>> }
>> boolean m;
>> }
>>
>> It even errors out if you write it as:
>>
>> class A
>> {
>> public void foo()
>> {
>> Object p;
>> if (m)
>> p = new Object();
>> if (p != null) // <-- p might not have been initialized
>> p.toString();
>> }
>> boolean m;
>> }
>>
>> Note that the error message is on the null check!
>
> I know what your mean, but the example is flawed:
>
> public void foo()
> {
> if (m) {
> Object p = new Object();
> p.toString();
> }
> }
>
> ...
>
> Thing is, I don't think you really _need_ flow analysis to implement
> nonnulity. The simplest way is to disallow creation of unitialized
> nonnull variables. I think it would work, but without some clever syntax
> such rule would be painful to follow for the programmers. Things like
> these would be prohibited, for example
>
> Duck d;
> if (b)
> d = new Duck();
> else
> d = new DuckSubclass();
>
> Seems like a big loss, but it really isn't.
>
> Duck d = b ? new Duck() : new DuckSubclass();
>
> But ternary ops are not generic, unless you chain them which is
> super-ugly. Is there nothing that can fix this? Delegates probably can:
>
> enum Dri { one, two, three};
> Dri s = Dri.two;
>
> int x = {
> if (s == Dri.one)
> return 1;
> else if (s == Dri.two)
> return 2;
> else
> return 3;
> }();
>
> This works. I'm not sure how efficient it is, but that would solve the
> issue with initialization without any path analysis. If there was a
> clearer, more efficient syntax for this, it would work even better.
>
> int x = do {
> if (s == Dri.one)
> return 1;
> else if (s == Dri.two)
> return 2;
> else
> return 3;
> };
OF course, the code above assumes that Duck is unnulable. I didn't want
to make my own syntax for it, because it would obfuscate the example.
More information about the Digitalmars-d
mailing list