Javac issues "might be uninitialized" for null test

D

David Blickstein

I find it a bit undesirable that javac would give a "might not have been
initiliazed" warning for this case:

Object o;
if (o != null) ...

If it were anything other than a test against null I'd be thankful for the
warning, but this particular hybrid case is rather obviously a "guard test"
and thus the warning is just noise. And any compiler worth its salt would
be able to recognize this particular case and suppress the message.

It's easily eliminated by initializing the reference variable in its
declaration but still...

Am I missing something? Or should I feed this back to Sun?
 
T

Tjerk Wolterink

David said:
I find it a bit undesirable that javac would give a "might not have been
initiliazed" warning for this case:

Object o;
if (o != null) ...

If it were anything other than a test against null I'd be thankful for the
warning, but this particular hybrid case is rather obviously a "guard test"
and thus the warning is just noise. And any compiler worth its salt would
be able to recognize this particular case and suppress the message.

It's easily eliminated by initializing the reference variable in its
declaration but still...

Am I missing something? Or should I feed this back to Sun?


It is just a design choice of the java programming language,
i think a good choice because you now have to explicit note
that you initialize it with nothing, Object o=null;
else the compiler should give you a warning.
 
E

Eric Sosman

David said:
I find it a bit undesirable that javac would give a "might not have been
initiliazed" warning for this case:

Object o;
if (o != null) ...

If it were anything other than a test against null I'd be thankful for the
warning, but this particular hybrid case is rather obviously a "guard test"
and thus the warning is just noise. And any compiler worth its salt would
be able to recognize this particular case and suppress the message.

It's easily eliminated by initializing the reference variable in its
declaration but still...

Am I missing something? Or should I feed this back to Sun?

It seems to me you're missing something, but I'm not
exactly sure which target your arrow isn't aimed at ...

Java does not initialize variables (as opposed to class
members, which it *does* initialize) to any kind of default
value. Some languages "initialize with garbage" and allow
you to get yourself in trouble by trying to use the garbage
as a value. Instead, Java prevents you from even trying to
observe an uninitialized variable, so the question of "What
value does it have?" cannot even arise. Yes, the memory
locations occupied by the variable `o' probably hold a bunch
of bits, but these are not a "value" because you cannot look
at them -- the situation has an almost quantum-mechanical
flavor about it.

Your `o' reference has not been initialized -- not to
`null', not to `BigInteger.ZERO', not to garbage, not to
anything at all. It has no value whatsoever, so trying to
compare the non-existent value to `null' is erroneous. Even
if Java allowed you to observe the garbage bits in `o's
memory locations, it would still be erroneous to compare them
to `null': No answer the comparison could deliver would be
reliable.

What puzzles me is why you think comparing garbage to
`null' ought to do anything sensible, and why you think the
compiler should be able to separate this case from all others
involving uninitialized variables. I don't see what it is
about "this particular case" that would allow the compiler to
suppress the message. Nor do I see what kind of code you want
the compiler to generate: Should it somehow just know what you
want the comparison to produce? Rather than asking it to
read your mind, you could just write

Object o;
if (false) ... // or if (true) ...

.... and make your intentions clear. (Maybe this is a thought
experiment that might help clarify your confusions: Why would
`if (false)' not suit your needs? That is, what do you want
the compiler to do differently?)

Granted, there are some gaps in the way Java decides that
a variable has or has not been initialized. The compiler is
unable to deduce that some execution paths are impossible so
it doesn't matter that the variable won't be initialized if
the impossible path is taken. For example

void method(Object[] array) {
int y;
switch (array.length % 3) {
case 0: y = 42; break;
case 1: y = 76; break;
case 2: y = -x; break;
}
System.out.println(y);
}

.... will elicit a complaint about `y' being uninitialized.
The compiler thinks it's possible for the `switch' to match
none of the cases, thus getting to the println() without
executing any of the assignments. You and I know better:
since array lengths cannot be negative, the `%' operation
will produce one of 0,1,2 and never -1,-2 -- but the compiler
is less clever than you and I in this respect.

Still, in the case you showed the compiler is correct:
the variable `o' has been given no value, and it is an error
to attempt to use that non-existent value. I don't know why
you'd want it otherwise.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top