null [re: spec#]

retard re at tard.com.invalid
Sun Nov 7 06:08:29 PST 2010


Sun, 07 Nov 2010 01:54:24 -0500, Nick Sabalausky wrote:

> "Nick Sabalausky" <a at a.a> wrote in message
> news:ib5ht0$2uff$1 at digitalmars.com...
>> "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).
>>
>>
> Additionally, the root problem with default values is that they make
> deliberately-default-inited declarations and accidentally-uninited
> declarations completely indistinguishable by both the compiler and the
> programmer.
> 
> (And no, "accidentally-uninited" does *not* imply "undefined value". If
> something's supposed be inited to X and it gets inited to Y, that's
> still *wrong* - *even* if it's reproducibly-wrong.)

When I started with D, some of the main reasons for choosing D were:

 - you can return int from a void function without compilation errors
 - you can use 'void main()' instead of 'int main()' and a silly return 
value 0
 - counter variables are default initialized to 0

I thought it would save so much typing.


More information about the Digitalmars-d mailing list