null [re: spec#]

Nick Sabalausky a at a.a
Sat Nov 6 23:42:23 PDT 2010


"Walter Bright" <newshound2 at digitalmars.com> wrote in message 
news:ib5bue$2ldp$1 at digitalmars.com...
> 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!

Since when should crap like that ever be written in the first place? In a 
code review, I'd slap both of those with a giant red "convoluted" stamp, 
*especially* if it's not just a trivial example like those.

Besides, I'd much rather have easily-fixable false positives like that then 
the false negatives D gets now:

Object p;
if (m)
    p = new Object();
p.toString(); // Boom!, but *only* at run-time, and *only* if m just happens 
to be true.

Plus, as I've argued before, I *wouldn't* want perfect flow analysis on 
that, I'd rather have easily-rememberable rules. If the 
initialization-safety of your code is dependent on complex logic, then 
you've written it wrong anyway.

In simple examples like yours above, the fixes are not only obvious, but 
much more clear:

Object p;
if (m)
{
    p = new Object();
    p.toString();
}

And in more complex cases, relying on complex logic to ensure things are 
inited properly is just wrong anyway, as I said above. Seriously, this whole 
"feature" amounts to nothing more than allowing the following *broken* code 
to occasionally get overlooked...

Object p;
if (m)
    p = new Object();
p.toString();

...just for the completely non-existent "convenience" of writing crap like 
this...

Object p;
if (m)
    p = new Object();
if (m)
    p.toString();

...instead of just doing it right:

Object p;
if (m)
{
    p = new Object();
    p.toString();
}

You can label C#-style init-checking "wishy-washy" all you want, but that's 
still a hell of a lot better than "wrong", which is what D does (as 
evidenced by my first example above).




More information about the Digitalmars-d mailing list