[coding practises] do you declare your superclass "throws"??

L

Lew

Andreas said:
No, not even these are, since if the currently commented out line
(or block or method) happens to contain the one and only call to
yet another private method, then I'd enter a chain of methods to
comment out each separately, and re-activate them when re-activating
that one initial line/block/method.

Otoh, if rather than commenting stuff out I prepend it with "if (false)",
then the code is still dead, and the compiler doesn't even write a
warning.

But "if (false)"ing is still no substitute, since it still requires
the thusly deaktivated part to still be compileable.

Also, I just tried: unused private methods do *not even* raise
a warning in javac (this seems to be an eclipse-feature). I consider
unused private methods to be the principially same thing as unused
default-blocks in exhaustive switches and catches for unthrown
exceptions. Actually, if/while-statement-bodies, whose condition
can be determined as always-false could also be determined as
dead code, but only if the consequence were not worse than a warning,
since that's probably the most-used workaround for the annoying
feature under discussion.

I'd find it reasonable that all of them threw warnings.

But then again, maybe we're indeed barking up the wrong tree, and
what we really want is a compiler that, based on some options,
deviates from JLS to not overly annoy for code still under active
development.

I can agree to both Lew and JLS in that code that is shipped should
not contain any such dead blocks.
 
L

Lew

Lew wrote - actually, he didn't, he pressed SEND first.

Sorry about the accidental SEND before replying. Please disregard that.


If it did, it would violate the JLS.

But not necessarily compiled. Anyway, the whole point of that section is to
lock down one type of incorrect code. You guys are arguing that Java should
be more tolerant of that variety of incorrect code. Java is saying, "Tough
noogies." I'm agreeing with Java. Having a compiler call bad code an error
is not the worst flaw in the Java language.

Good point. It should. Java should be more strict, not more lax.

There is a difference in the language spec between how conditions are handled
in if statements and how they're handled in while statements.

The Java designers went through a great deal of trouble to define if (false)
to allow conditional non-compilation without it being an error.

JLS
if (false) { x=3; }
does not result in a compile-time error.
An optimizing compiler may realize that the statement
x=3; will never be executed and may choose to omit the code for that
statement from the generated class file, but the statement x=3; is
not regarded as "unreachable" in the technical sense specified here.

I'm not entirely sure I read your message correctly, but it seemed to take
issue with that feature.
 
A

Andreas Leitgeb

Lew said:
I'm not entirely sure I read your message correctly, but it seemed to take
issue with that feature.

There are certain samples which I consider "the same in principle",
but JLS has defined different behaviour for:

on one hand:
never-called private methods.
if (false) { ... } and while(false) {...}
and also if (true) {} else { ... },
for (;false; ...) { ... }.
extraneous exceptions in throws-clause of a
private method. (ok, not exactly "code",
but additional items in the methods
"Exceptions"-attribute)
probably another couple of such things

on the other hand:
un-reachable catch-blocks
un-reachable switch-default-blocks.
probably another couple of such things

While first hand is defined by JLS to be entirely "ok",
the other hand is defined by JLS to be entirely not ok.

While the former do allow dead-code to exist in currently-legal
java-code, thusly thwarting the proclaimed goal of avoiding dead
code, the latter is a nuissance during development phase justified
in the name of avoiding dead code.

In principle they are all the same, namely dead code,
and all of these would be defined to yield (just) warnings
in my fictive ideal JLS. :)

Position clear now? Dare to contradict me??? ;-)
 
L

Lew

Andreas said:
There are certain samples which I consider "the same in principle",
but JLS has defined different behaviour for:

on one hand:
never-called private methods.
if (false) { ... } and while(false) {...}
and also if (true) {} else { ... },
for (;false; ...) { ... }.
extraneous exceptions in throws-clause of a
private method. (ok, not exactly "code",
but additional items in the methods
"Exceptions"-attribute)
probably another couple of such things

on the other hand:
un-reachable catch-blocks
un-reachable switch-default-blocks.
probably another couple of such things

While first hand is defined by JLS to be entirely "ok",
the other hand is defined by JLS to be entirely not ok.
Position clear now? Dare to contradict me??? ;-)

Actually, the JLS defines different behavior for the if() and while() conditions.
 
A

Andreas Leitgeb

Lew said:
Actually, the JLS defines different behavior for the if() and while() conditions.

Indeed, "while (false) ..." is illegal ...
Well then consider it moved to the "other hand", and
my point is (imho) still valid.

PS: "while (i==1.5) { ... } *is* legal for an "int i" :)
But, admittedly, that's not the point under discussion ;-)
 
L

Lew

Andreas said:
PS: "while (i==1.5) { ... } *is* legal for an "int i" :)
But, admittedly, that's not the point under discussion ;-)

It's an interesting point, nonetheless.

This cannot be proven at compile time to fail, at least not without
considerable semantic analysis beyond what compilers really should do.

It requires that the compiler understand that the double-promoted value of an
int can never have a fractional part, an assumption that would fail for long
btw, and that the other operand does have a fractional part - it could do
that, but that's a lot of work for compile-time. As you've noted, Java's
rules about unreachable code didn't try to lock down all the scenarios - in
particular they don't lock down anything that requires run-time analysis of
the operations. Even more particularly, they don't lock down expressions
where you don't know all the values at compile time. Even though the promoted
value of 'i' can be predicted not to equal 1.5, it cannot be predicted what it
will equal.

So 'while ( i == 1.5 )' for an int i passes the compile-time check for
reachability. The rules don't account for any run-time actions, like binary
promotion, even ones where one "could know" what the result will not be.
 
J

Joshua Cranmer

Lew said:
It's an interesting point, nonetheless.

This cannot be proven at compile time to fail, at least not without
considerable semantic analysis beyond what compilers really should do.

What about optimizing compilers utilizing constant value propagation and
dead code elimination? If the set of values of i can be known at
compile-time (e.g., the previous statement is "int i=5;"), then it
stands to reason that a compiler should figure out that 5 != 1.5 and
remove the while block.
 
L

Lew

Joshua said:
What about optimizing compilers utilizing constant value propagation and
dead code elimination? If the set of values of i can be known at
compile-time (e.g., the previous statement is "int i=5;"), then it
stands to reason that a compiler should figure out that 5 != 1.5 and
remove the while block.

That is a run-time consideration and doesn't bear on the issue of what is
"unreachable" code according to the language specification.

You're speaking of the Hotspot compiler, the bytecode-to-machine code
compiler. This discussion focused on javac, the Java-source-text-to-bytecode
compiler.
 
B

Ben Phillips

Andreas said:
No, not even these are, since if the currently commented out line
(or block or method) happens to contain the one and only call to
yet another private method, then I'd enter a chain of methods to
comment out each separately, and re-activate them when re-activating
that one initial line/block/method.

These methods could be made a single contiguous block within the source
file. Then it's only one block to comment out.
Otoh, if rather than commenting stuff out I prepend it with "if (false)",
then the code is still dead, and the compiler doesn't even write a
warning.

Interesting. I wasn't sure if this would work as a workaround, since the
code is still provably dead by static analysis.
But "if (false)"ing is still no substitute, since it still requires
the thusly deaktivated part to still be compileable.

If you're not editing that part, and didn't remove some declaration
needed for it to be compilable, this should not be a problem. The
situation under discussion had been where editing in one area makes code
elsewhere that you'd rather not touch yet become unreachable, after all.
Also, I just tried: unused private methods do *not even* raise
a warning in javac

Yes, I noticed. It's an example of inconsistency in applying principles
from the JLS. I'd suggest it become a warning, and as a compromise the
unused default/catch block errors also become warnings. :)
I'd find it reasonable that all of them threw warnings.
But then again, maybe we're indeed barking up the wrong tree, and
what we really want is a compiler that, based on some options,
deviates from JLS to not overly annoy for code still under active
development.

Isn't that overloading the purpose of the warning/error distinction?
Warnings meaning "this may work, but it looks dodgy and at minimum needs
polish" for the most part, and errors typically meaning "this cannot
work, at all".
I can agree to both Lew and JLS in that code that is shipped should
not contain any such dead blocks.

Ditto. Of course I firmly believe that code that is shipped should not
generate any compiler warnings, and not merely because of gratuitous use
of the @SuppressWarning annotation everywhere either, though sometimes
it's justifiable especially when dealing with generics-induced messes.

Is this supposed to be the end of your post? If not, my newsserver seems
to have truncated their copy of your post. I can't find any way to
"refresh" it in Thunderbird as I would a web page in Firefox, so I can't
see if their master copy is truncated or only the copy they sent me (or,
if the latter, actually get the rest of it, it seems! Not without
resubscribing and clobbering all of my read/unread info for
comp.lang.java.programmer anyway).
 
A

Andreas Leitgeb

Ben Phillips said:
These methods could be made a single contiguous block within the source
file. Then it's only one block to comment out.

They could be, but probably they aren't ;-)
Commenting out a whole group of consecutive methods will most
likely also include one or two methods still needed elsewhere...
Yes, I noticed. It's an example of inconsistency in applying principles
from the JLS. I'd suggest it become a warning, and as a compromise the
unused default/catch block errors also become warnings. :)

As it seems, the "founding fathers" of java did intend for "if(false)"
to also solve the temporarily-no-throws problem, in that the body of
a if(false) may contain the only throw-source for a checked exception,
and then the according catch is no longer stale in javac's sense, even
though no bytecode is emitted for that if's body.

Even more interestingly, some experiment of mine shows, that even
for the catch-clause, in this case no bytecode is generated! Thus

class Y extends Exception {}
public class X {
public static void main(String[] args) {
try {
if (false) { foo(); }
} catch (Y e) {
e.printStackTrace(System.out);
}
}
static private boolean foo() throws Y { return false; }
}

The bytecode generated for main() is no more than:
0: goto 3
3: return
(so, either the if or the try is not entirely traceless :)
Warnings meaning "this may work, but it looks dodgy and at minimum needs
polish" for the most part, and errors typically meaning "this cannot
work, at all".

That's exactly how I see it.
Is this supposed to be the end of your post?
Sorry for the confusion I caused. During writing that post, I was
distracted a couple of times, and when seeing the next distraction
approaching, I sent it off, having forgotten that the last line
was yet unanswered.

The error->warning for unreachable code is 100% desirable in my
eyes. Issueing new warnings for unused private methods and
if(false) actually less so, since that would effectively be an
incompatible change, afterall.
 
W

Wayne

Lew said:
Andreas Leitgeb wrote:
...
It requires that the compiler understand that the double-promoted value
of an int can never have a fractional part, an assumption that would
fail for long btw, ...

This has been an interesting thread, but I'm not sure I understand
the above (off-off-topic :). When can a long promoted to double
contain a fraction? Do you have any examples?

-Wayne
 
L

Lew

Wayne said:
This has been an interesting thread, but I'm not sure I understand
the above (off-off-topic :). When can a long promoted to double
contain a fraction? Do you have any examples?

Any long with more than 53 significant bits.

A double cannot capture all integral values because long has a higher
resolution. So when you promote a long to a double you could end up with an
approximation to the original value.

You are right, that number will not have a fractional part; I misspoke. What
I meant was that the value will be off by a fractional part of the magnitude,
which of course is still an integral amount of error.

What I should have pointed out is that a double-to-long comparison could fail
even if both values are integral, if the values exceed 53 bits of precision.
This still supports the primary original point that the compiler is not really
free to define "unreachable" in terms of run-time analysis, not in the
restricted sense defined by the JLS.

Thanks for spotting the mistake.
 
L

Lew

Andreas said:
The error->warning for unreachable code is 100% desirable in my
eyes. Issueing new warnings for unused private methods and
if(false) actually less so, since that would effectively be an
incompatible change, afterall.

Particularly incompatible would be the 'if (false)' change, since the founders
went through so much trouble to make it work the way that it does.
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,150
Latest member
MakersCBDReviews
Top