Ary Borenszweig wrote:
Walter Bright escribió:
Ary Borenszweig wrote:
Walter Bright escribió:
Ary Borenszweig wrote:
It's not like that. They don't require you to initialize a variable
in it's initializer, but just before you read it for the fist time.
That's very different.
The only way to do that 100% reliably is to instrument the running
code.
Java does it on compile time.
Java is a severely constrained language. Even so, how does it do with
this:
Foo f;
if (x < 1) f = new Foo(1);
else if (x >= 1) f = new Foo(2);
f.member();
Whenever there are branches in code and a variable still doesn't have a
value at that point:
- if all branches assign a value to that variable, from now on the
variable has a value
- if not, at then end of the branches the variable still doesn't have a
value
That rule gets the wrong answer in the above case. Consider that in
order to get where you want to go with this, the flow analysis has to
always work, not most of the time work. Otherwise you get bug reports
with phrases like "seems to", "sometimes", "somehow", "I can't figure it
out", "I can't reproduce the problem", etc.
Here's another lovely case:
Foo f;
if (x < 1) f = new Foo();
... lots of code ...
if (x < 1) f.member();
The code is quite correct and bug-free, but flow analysis will tell you
that f in f.member() is "possibly uninitialized".
? (You might ask who would write such, but sometimes the conditions
are much more complex, and/or are generated by generic code.)
If it's done only for local variables then you don't need to
instrument the running code.
How about this:
Foo f;
bar(&f);
? Or in another form:
bar(ref Foo f);
Foo f;
bar(f);
Java doesn't have ref parameters.
C# does have ref parameters and it also performs this kind of check.
It cannot do it and still support separate compilation.
I just tried it and it says a parameter can't be passed by reference if it
doesn't have a value assigned.
I'll bet that they added this constraint when they got a bug report
about that hole <g>.
So your first example should be an error.
The same should be applied for &references.
(in your first example, if you want to pass f by reference so that bar
creates an instance of f, then it should be an out parameter).
Doesn't work if the function conditionally initializes it (that is not
uncommon, consider the API case where if the function executes
correctly, the reference arg is initialized and filled in with the results).
In other words, you have to start throwing in constraints like the C#
copout or get rid of large chunks of the language like Java does.