From: Jim Janney on
Alan Malloy <alan.NO.SPAM(a)malloys.org> writes:

> Jim Janney wrote:
>> Tom Anderson <twic(a)urchin.earth.li> writes:
>>
>>> On Tue, 25 May 2010, Patricia Shanahan wrote:
>>>
>>>> Rhino wrote:
>>>>> I've received some criticism recently with regards to the approach
>>>>> I use to initializing variables so I'd like to throw this issue out
>>>>> to the whole group so that I can learn more about the pros and cons
>>>>> of the approach I am using....
>>>>>
>>>>> Basically, I initialize pretty much every variable as I declare it,
>>>>> just to be sure it has some kind of value right away. That initial
>>>>> value is typically a zero for a number or a null for an
>>>>> object. Some recent criticism questioned this practice so I thought
>>>>> I'd review some of the material that helped get me in that habit in
>>>>> the first place.
>>>> ...
>>>>
>>>> I follow the extreme opposite view. I initialize a local variable at the
>>>> point of declaration if doing so makes logical sense or I know that I
>>>> know something the compiler does not know. Generally, that involves the
>>>> compiler assuming a fall-through from a call to System.exit.
>>>>
>>>> The reason for doing this is simple. I make mistakes. I have done most
>>>> of my work in environments in which pair programming is not feasible, so
>>>> I cannot depend on another programmer to catch my mistakes. To the
>>>> maximum extent possible, I want to co-opt Eclipse's continuous source
>>>> code checking as an aid to finding my mistakes as quickly as possible.
>>>>
>>>> One mistake I might make is omitting a logically necessary assignment to
>>>> a local variable. Routinely initializing at the point of declaration
>>>> would eliminate the possibility that it might be detected by the compiler.
>>>>
>>>> When I get a definite assignment error I take the time to look at my
>>>> logic. Just occasionally, simply adding an initializer to the
>>>> declaration would leave either an actual error or unnecessarily
>>>> convoluted code, and I do something else.
>>> This is exactly what i do. By initialising locals at the point of
>>> definition, you immediately throw away the compiler's ability to
>>> sanity-check your assignments to them. Don't do that.
>>
>> You've lost me here. We all make mistakes, but I don't see how this
>> is supposed to help. Perhaps someone could post a short example?
>>
>
> void printList(MyLinkedList list) {
> MyNode n = null;
> // Some other initialization code
>
> // forgot to uncomment the next line
> // n = list.first();
>
> while (n != null) {
> print(n);
> n = n.next();
> }
> }
>
> Without the initial null assignment, the compiler will let you know
> you've made a mistake. Putting it there destroys the read-before-use
> checking and causes the method to do nothing at runtime, with no error
> detection at all.

OIC, thanks.

--
Jim Janney
From: Tom Anderson on
On Wed, 26 May 2010, Gunter Herrmann wrote:

> Tom Anderson wrote:
>> On Tue, 25 May 2010, Arne Vajh?j wrote:
>
>>> But I would note that in many cases the optimal solution is to
>>> wait declaring the variable until you have a value to give it.
>>
>> Absolutely. Goes without saying!
>
> There are exceptions to this rule (pun intended)
>
> Foo foo = null;
>
> try {
> foo = new Foo();
> foo.doProcessing();
> }
> catch (FooException ex) {
> doSomething(ex);
> }
> finally {
> foo.cleanup();
> }
>
> In this case you have to initialize the variable foo.

No, because you should just write it like this:

Foo foo = new Foo();
try {
foo.doProcessing();
}
catch (FooException ex) {
doSomething(ex);
}
finally {
foo.cleanup();
}

If new Foo() can also throw an exception, then wrap that whole lot in a
try-catch or whatever.

tom

--
Please! Undo clips before opening handle.
From: Tom Anderson on
On Tue, 25 May 2010, Lew wrote:

> Arne Vajh?j wrote:
>>>>>> I strongly favor readability here. The extra overhead of something
>>>>>> getting initialized twice should be minimal or zero if the JIT
>>>>>> compiler optimizes it away.
>
> Lew wrote:
>>>>> Minimal, perhaps, but the system is not permitted to optimize away
>>>>> member initialization.
>
> Arne Vajh?j wrote:
>>>> What would prevent the JIT compiler from optimizing the setting of
>>>> an int to zero twice to only doing it once?
>
> Lew wrote:
>>> The JLS, section 12.5, "Creation of New Class Instances":
>>> "In some early implementations, the compiler incorrectly omitted the
>>> code to initialize a field if the field initializer expression was a
>>> constant expression whose value was equal to the default initialization
>>> value for its type."
>
> Arne Vajh?j wrote:
>> But isn't that talking about javac and not JIT?
>
> Not as I read it, but maybe it is.
>
> Regardless, JIT requires multiple executions (by default 10,000 IIRC)
> before it decides to optimize something. By definition, initialization
> code is run once.

Um, once per instance. If it's an instance initializer. Which is what i
thought we were talking about here. That could easily be run 10 000 times
in a single program.

> Regardless, as you pointed out and I reiterated, the performance impact is
> not enough to trump issues of readability or self-documentation. Nor is it
> required to initialize member variables to their default values.
>
> I admit it's possible that I read this wrong, but I think not.

I don't see how a statement like that is even meaningful when applied to a
JVM. You can require that a JVM behaves *as if* it does or doesn't do
something, defined in terms of some model of what the JVM is doing, but as
long as it does, it can do it however it likes. I don't see how rules to
the contrary would be useful or even possible to judge compliance to.

tom

--
uk.local groups TO BE RENAMED uk.lunatic.fringe groups
From: Eric Sosman on
On 5/26/2010 3:06 PM, Tom Anderson wrote:
> On Tue, 25 May 2010, Lew wrote:
>
>> Arne Vajh?j wrote:
>>>>>>> I strongly favor readability here. The extra overhead of something
>>>>>>> getting initialized twice should be minimal or zero if the JIT
>>>>>>> compiler optimizes it away.
>>
>> Lew wrote:
>>>>>> Minimal, perhaps, but the system is not permitted to optimize away
>>>>>> member initialization.
>>
>> Arne Vajh?j wrote:
>>>>> What would prevent the JIT compiler from optimizing the setting of
>>>>> an int to zero twice to only doing it once?
>>
>> Lew wrote:
>>>> The JLS, section 12.5, "Creation of New Class Instances":
>>>> "In some early implementations, the compiler incorrectly omitted the
>>>> code to initialize a field if the field initializer expression was a
>>>> constant expression whose value was equal to the default initialization
>>>> value for its type."
>>
>> Arne Vajh?j wrote:
>>> But isn't that talking about javac and not JIT?
>>
>> Not as I read it, but maybe it is.
>>
>> Regardless, JIT requires multiple executions (by default 10,000 IIRC)
>> before it decides to optimize something. By definition, initialization
>> code is run once.
>
> Um, once per instance. If it's an instance initializer. Which is what i
> thought we were talking about here. That could easily be run 10 000
> times in a single program.
>
>> Regardless, as you pointed out and I reiterated, the performance
>> impact is not enough to trump issues of readability or
>> self-documentation. Nor is it required to initialize member variables
>> to their default values.
>>
>> I admit it's possible that I read this wrong, but I think not.
>
> I don't see how a statement like that is even meaningful when applied to
> a JVM. You can require that a JVM behaves *as if* it does or doesn't do
> something, defined in terms of some model of what the JVM is doing, but
> as long as it does, it can do it however it likes. I don't see how rules
> to the contrary would be useful or even possible to judge compliance to.

A suppressed initialization can be observed:

class Super {
Super() {
evilCode();
}

void evilCode() { }
}

class Sub extends Super {
int value = 0; // suppressible?

Sub() {
System.out.println("value = " + value);
}

void evilCode() {
value = 42;
}

public void main(String[] unused) {
new Sub();
}
}

Yes, this is evil code that merits severe chastisement of its author,
but despite its sins it is perfectly legal Java -- and the required
output is "value = 0". If the initialization were suppressed, the
output would be "value = 42" -- and that would (was?) wrong.

--
Eric Sosman
esosman(a)ieee-dot-org.invalid
From: Tom Anderson on
On Wed, 26 May 2010, Tom Anderson wrote:

> On Wed, 26 May 2010, Gunter Herrmann wrote:
>
>> Tom Anderson wrote:
>>> On Tue, 25 May 2010, Arne Vajh?j wrote:
>>
>>>> But I would note that in many cases the optimal solution is to
>>>> wait declaring the variable until you have a value to give it.
>>>
>>> Absolutely. Goes without saying!
>>
>> There are exceptions to this rule (pun intended)
>>
>> Foo foo = null;
>>
>> try {
>> foo = new Foo();
>> foo.doProcessing();
>> }
>> catch (FooException ex) {
>> doSomething(ex);
>> }
>> finally {
>> foo.cleanup();
>> }
>>
>> In this case you have to initialize the variable foo.
>
> No, because you should just write it like this:
>
> Foo foo = new Foo();
> try {
> foo.doProcessing();
> }
> catch (FooException ex) {
> doSomething(ex);
> }
> finally {
> foo.cleanup();
> }
>
> If new Foo() can also throw an exception, then wrap that whole lot in a
> try-catch or whatever.

If the handling for FooExceptions from the constructor and the processing
is the same:

try {
Foo foo = new Foo();
try {
foo.doProcessing();
}
finally {
foo.cleanup();
}
}
catch (FooException ex) [
doSomething(ex);
}

tom

--
unconstrained by any considerations of humanity or decency