Sun, 07 Nov 2010 01:54:24 -0500, Nick Sabalausky wrote: > "Nick Sabalausky" <a...@a.a> wrote in message > news:ib5ht0$2uf...@digitalmars.com... >> "Walter Bright" <newshou...@digitalmars.com> wrote in message >> news:ib5bue$2ld...@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.