"Small" Program Challenge.

S

Stefan Ram

javax.swing.JSnarker said:
"Void main() is not supported by the C specification." is English prose,
not a code example.

The text with in the quotes misses inner quotes. It should be written as:

»The text "void main()" is not supported by the C specification.« (1)

»The text "void main()"« is a restrictive appositive and must be used
to fulfill both the rules of English and C for the spelling of the »v«.
See also:

http://en.wikipedia.org/wiki/Apposition

. The quotation marks in »"void main()"« are used to fulfill the

http://en.wikipedia.org/wiki/Use–mention_distinction

. So, (1) fulfills the rules of English, of C, and of the use-mention
distinction.
 
J

javax.swing.JSnarker

Oh, but it is.

It is, indeed, English prose; glad you realize that now.
I have seen plenty that suggest "void main()" in a hosted
implementation. It is the first thing that I look for in evaluating
quality.

To then reject the ones that suggest it, I hope.
You keep missing

I have done nothing of the sort, or anything wrong at all, and I will
thank you to stop publicly smearing me by claiming or suggesting
otherwise in news posts.
I think it more likely that it is you who is wrong.

Then you think wrong. The spec clearly says that initialization precedes
invocation.
I await your next smokescreen post.

Then you will be waiting a very long time.
 
L

Lew

javax.swing.JSnarker said:
Gene said:
javax.swing.JSnarker wrote:

[snip]
Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

1) It is "void", not "Void", and

Yes, I know, however it was at the start of a sentence and part of
English prose rather than compilable code.
2) more importantly, "void main()" is legal C,

Not according to any of the books I've read, and there have been many.
Why not just read the JLS instead using "common sense" and
baseball gloves?

I read the JLS *as well*. The JLS clearly stated that initialization
*precedes* invocation. It does not follow it and it certainly does not
happen *during* it, as some recent posts to this thread seem to have
suggested.

It precedes invocation, but not the attempt to invoke.

You are wrong. I have seen in real code where classes were loaded and
not initialized, causing a bug in code written by the wrong idea you're promoting.

Reality wins.

The JLS clearly states when initialization MUST NOT happen after loading,
therefore if you read the JLS you will see that the two do not
happen together automatically, and you will correct your misapprehension.

You are mistaken.
 
J

javax.swing.JSnarker

It precedes invocation, but not the attempt to invoke.

That doesn't make sense. "It precedes catching the ball, but not the
attempt to catch" likewise doesn't make sense.
You are wrong.

No, I'm not.
I have seen in real code where classes were loaded and not initialized,

Not relevant here, unless you're claiming you've seen in real code where
a static method began to be invoked and the class was *still* not
initialized.
Reality wins.

And you lose.

The rest of your post is redundant with other parts of it and as such
has been ignored as asked-and-answered already.
 
J

javax.swing.JSnarker

As has been pointed out earlier in the thread, that's exactly what
happens when, with Java 7, you try to start a Java program with a
class that does not contain a valid main method.

And as has been pointed out earlier in the thread, that contravenes the
spec, which says initialization occurs *before* invocation.
 
L

Lew

No, it doesn't contravene the spec. Initialization *does* occur before
invocation, but not before the attempt to invoke. As the spec explains.
I disagree that it contravenes the spec, but regardless it is an
example of "real code where a static method began to be invoked and
the class was still not initialized." Of course, that's assuming that
we consider Java 7 to have "begun to invoke" the missing main method,
but if not, the rest of your argument falls through.

The same thing happens in Java 5 (and should have happened in 1.2 through
1.4), if you refer to the 'class' literal of a class before any action that
triggers intialization, the class will be loaded but not initialized.

As required by the JLS. Since before Java 5. Admittedly (in that Sun admitted
it) there was a bug in Sun's Java 1.4 whereby reference to the 'class' literal
did cause class initialization, but they fixed that in Java 5.

These are facts which completely undercut "JSnarker"'s claim. As does the JLS:

<http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2>
"The procedure assumes that the Class object has already been verified and
prepared, and that the Class object contains state that indicates one of four
situations:

"- This Class object is verified and prepared but not initialized.
...."

See?

There is a point at which a class has been loaded, verified and prepared, but
not initialized.

That state can exist at any of the initialization points mentioned in §
12.4.1, e.g., "immediately before the first occurrence of ... T is a class and
a static method declared by T is invoked."

Prior to that, the class may have already been loaded but not initialized,
e.g., by a reference to its 'class' literal or by an invocation of
'Class#forName()' with the 'intialize' parameter set to 'false'.

As for the process happening upon an attempt to invoke, here's language from
12.1.1:

"The initial attempt to execute the method main of class Test discovers that
the class Test is not loaded ..."

Where's your temporal sequence now, O Snarky One? As I have stated and you
have obstinately rejected repeatedly, the loading (if not yet done) and
initialization occurs upon the attempt to invoke, i.e., the attempt happens
first, conceptually.

Read the JLS and understand.
 
L

Lew

Here we go. "No true Scotsman". This plus /ad hominem/ attacks.

It is relevant because the argument was over whether initialization always
occurs together with loading, as you claimed upthread. It does not, as I have
stated all along. I never made the claim that invocation of a static method
did not cause (despite following) initialization.

And doesn't your statemtn - "a static method began to be invoked and the class
was *still* not initialized" - reveal a sequence of "begin to invoke" followed
by "initialize", just as I've been saying right along?

Do you mean to say you've been arguing against something that you actually
agree with?

All this time?

If I hadn't been responding via a Web interface I'd've remembered why I
plonked you a long time ago, snark.
As has been pointed out earlier in the thread, that's exactly what
happens when, with Java 7, you try to start a Java program with a
class that does not contain a valid main method.

As is required by the JLS, and has been since before Java 7.
 
A

Andreas Leitgeb

It all boils down to the true definition of "invocation".

Is it the moment when the instruction pointer hits the bytecode for
invokestatic and starts doing it, or is it just before it hits the
first instruction of the callee (iff existing)?

JVM7-behaviour implies the latter. I admit having difficulties myself
to actually read it unambiguously from JLS §12.4.1. Probably this
is defined elsewhere.

Anyway, between these two moments, there's plenty time for the JVM
to load the class, check availability of the method, and only if ok
then initialize the class and proceed with the callee's code,
otherwise skip initialization and just throw some exception.
And for a certain definition of "invocation", initialization
would still always precede it.
 
L

Lew

Andreas said:
It all boils down to the true definition of "invocation".

Is it the moment when the instruction pointer hits the bytecode for
invokestatic and starts doing it, or is it just before it hits the
first instruction of the callee (iff existing)?

JVM7-behaviour implies the latter. I admit having difficulties myself
to actually read it unambiguously from JLS §12.4.1. Probably this
is defined elsewhere.

Anyway, between these two moments, there's plenty time for the JVM
to load the class, check availability of the method, and only if ok
then initialize the class and proceed with the callee's code,
otherwise skip initialization and just throw some exception.
And for a certain definition of "invocation", initialization
would still always precede it.

The gap "between these two moments" is the gap between the attempt to
invoke, and the invocation proper.

JLS §12.4.1 lives in a context, one that include JLS §12.4.2,
op. cit. upthread.

Even so,
"A class or interface type T will be initialized immediately before the first
occurrence of any one of the following:
"T is a class and an instance of T is created.
"T is a class and a static method declared by T is invoked. ..."

is pretty clear. Whatever the definition of "invocation", initialization occurs
just before it. This means that the system identifies "immediately before".
That moment of "immediately before" can only be at the point of the attempt
to invoke, right before the invocation proper. I call "immediately before",
therefore, the "attempt to invoke". This distinguishes it from the invocation,
which occurs after initialization.

Note that this passage does not say that the class is loaded at that point.
That's because the class may have been loaded considerably earlier, but
not initialized.
 
J

javax.swing.JSnarker

I disagree that it contravenes the spec, but regardless it is an
example of "real code where a static method began to be invoked and
the class was still not initialized."

Which would contravene the spec, since the spec clearly says that
initialization must *precede* invocation.
Of course, that's assuming that we consider Java 7 to have "begun to
invoke" the missing main method, but if not, the rest of your argument
falls through.

Lew considers it to have "begun to invoke" the missing main method, as
is apparent when he says it attempts to invoke the missing method first.
So if Lew is correct, then the behavior is out of spec. On the other
hand, if Lew is wrong, then the argument I made for why if Lew was
correct the behavior is out of spec falls through, but was moot anyway.
 
J

javax.swing.JSnarker

No, it doesn't contravene the spec. Initialization *does* occur before
invocation, but not before the attempt to invoke. As the spec explains.

The spec explains no such thing -- fortunately, because it doesn't make
sense. You cannot separate "the attempt to invoke" from "invocation".
The two go hand in hand like the attempt to catch a ball and the
successful catch. How can they not? Until the first byte of the main
method's bytecode is executing the attempt may or may not be successful;
success is defined by the main method's bytecode being entered and
starting to execute! How *else* could one sensibly define the attempt to
invoke said bytecode? But then initialization *must* precede the attempt
to not violate the spec, because otherwise it occurs after at least the
first byte of the main method begins executing. And by then it's too
late. The main method will see stuff uninitialized that the spec
requires it never see uninitialized, and there goes your claim to have a
conformant implementation. And until that moment, the "attempt to
invoke" is not guaranteed to succeed and is therefore still an attempt
and not an invocation by your own peculiar worldview in which you regard
the two as somehow separate.
The same thing happens in Java 5 (and should have happened in 1.2
through 1.4), if you refer to the 'class' literal of a class before any
action that triggers intialization, the class will be loaded but not
initialized.

How does loading it right away in such cases accomplish anything useful?
The class literal might as well evaluate to a memory-cheap stub-object
that is transparently replaced with the real class object when, and only
when, something is done with it that goes beyond bandying it about,
printing it, using its monitor, getting its hashcode, or comparing it
for equality. And the things that would then trigger actual loading also
are the ones that trigger initialization. Such a scheme would be *much*
more in what you previously called the "spirit of lazy initialization".
These are facts which completely undercut "JSnarker"'s claim.

In a pig's eye.
As does the JLS:

Only by your twisted and, shall we say "unique", interpretation of it.
See?

There is a point at which a class has been loaded, verified and
prepared, but not initialized.

Nothing in that says that that circumstance should be anything but very
brief, and it's clear that it must exist *at least* very briefly as
loading obviously must precede initialization.
As for the process happening upon an attempt to invoke, here's language
from 12.1.1:

"The initial attempt to execute the method main of class Test discovers
that the class Test is not loaded ..."

Where's your temporal sequence now, O Snarky One? As I have stated and
you have obstinately rejected repeatedly, the loading (if not yet done)
and initialization occurs upon the attempt to invoke, i.e., the attempt
happens first, conceptually.

What it says is that an attempt is made and fails because the class is
not both loaded and initialized. It is loaded, if necessary, and
initialized, and then a fresh attempt is automatically made. THAT
attempt may then succeed, or fail for other reasons, such as the method
doesn't exist.
Read the JLS and understand.

Already did that. Still waiting for you to practice what you preach, thoguh.
 
J

javax.swing.JSnarker

Here we go. "No true Scotsman". This plus /ad hominem/ attacks.

From you people, perhaps.
It is relevant because the argument was over whether initialization
always occurs together with loading

The argument is over whether attempting to invoke the main method is
allowed to precede initialization.
And doesn't your statemtn - "a static method began to be invoked and the
class was *still* not initialized" - reveal a sequence of "begin to
invoke" followed by "initialize", just as I've been saying right along?

That statement was a rephrasing of *your* claims intended to make it
clear that they contravene the spec.
If I hadn't been responding via a Web interface I'd've remembered why I
plonked you a long time ago, snark.

Ah. These must be the promised /ad hominem/ attacks.
As is required by the JLS, and has been since before Java 7.

The JLS requires that initialization precede the invocation, and
therefore precede the exception thrown when invocation fails due to lack
of the needed method.
 
J

javax.swing.JSnarker

It all boils down to the true definition of "invocation".

Is it the moment when the instruction pointer hits the bytecode for
invokestatic and starts doing it,

Obviously, and more or less by definition of "invokestatic".
JVM7-behaviour implies the latter.

The spec implies the former, though with sufficient ambiguity as to have
confused the hell out of Leif and Lew. And the name of the opcode
"invokestatic" also implies the former, as does the behavior of JVM6,
JVM5, ...
Anyway, between these two moments, there's plenty time for the JVM
to load the class, check availability of the method, and only if ok
then initialize the class and proceed with the callee's code,
otherwise skip initialization and just throw some exception.
And for a certain definition of "invocation", initialization
would still always precede it.

A kooky definition.
 
A

Andreas Leitgeb

Lew said:
Even so,
"A class or interface type T will be initialized immediately before the first
occurrence of any one of the following:
"T is a class and an instance of T is created.
"T is a class and a static method declared by T is invoked. ..."

It's interesting, how some aspect gets through only after reading
it the umpty+1st time.

The mention is actually clearly about a "a static method declared by T",
which obviously doesn't cover calls to methods, that are *not* declared
by that class.

PS: some example for Java 6
A.java:
class A {
static { System.out.println("A static init"); }
static void foo() { System.out.println("A static foo"); }
}
B.java:
class B {
static { System.out.println("B static init"); }
public static void main(String[]args) {
System.out.println("B static main");
A.foo();
}
}
compile both (with Java 6), run B:
B static init
B static main
A static init
A static foo
Then comment out the method "foo()" from A,
recompile only A, run B:
B static init
B static main
Exception in thread "main" java.lang.NoSuchMethodError: A.foo()V
at B.main(B.java:4)
Note: no initialization of A, even with Java 6.

Anyone care to try this with other (older) versions and report results?
 
J

javax.swing.JSnarker

compile both (with Java 6), run B:
B static init
B static main
A static init
A static foo
Then comment out the method "foo()" from A,
recompile only A, run B:
B static init
B static main
Exception in thread "main" java.lang.NoSuchMethodError: A.foo()V
at B.main(B.java:4)
Note: no initialization of A, even with Java 6.

So, even Java 6 has a version of the bug. Interesting. I don't see how
the remark about "declared by T" is relevant here, since foo clearly is
declared by A in your example that reproduces the bug.
 
L

Lew

javax.swing.JSnarker said:
So, even Java 6 has a version of the bug. Interesting. I don't see how
the remark about "declared by T" is relevant here, since foo clearly is
declared by A in your example that reproduces the bug.

Of what bug do you speak?

Since no static method of 'A' was called in the second run, the condition
to initialize the class was not met.
 
J

javax.swing.JSnarker

Of what bug do you speak?

Since no static method of 'A' was called in the second run,

There was a call to A.foo(). That the call did not *succeed* doesn't
mean that it didn't *exist*. If the call didn't exist, what threw the
exception, and why?
 
D

Daniel Pitts

I'd rather see it as an extension of the bytecode validation mechanism,
that has to exist anyway:

1. Load bytecode
2. Validate bytecode
(exits if there is no 'main' method for the main class)
3. Initialize class
4. Run 'main' method.
Actually, the way I understand it is that Loading is immediately
followed by verification.

How I would expect this to work in reality.

1. Load class
2. get a reference to the static method "void main(String[])"
3. Attempt to execute that reference
3.1 Causes class initialization before execution.
3.2 actual execution occurs.
 
J

javax.swing.JSnarker

How I would expect this to work in reality.

1. Load class
2. get a reference to the static method "void main(String[])"
3. Attempt to execute that reference
3.1 Causes class initialization before execution.
3.2 actual execution occurs.

That has a problem, though, in that class initialization will happen on
every method call, resulting in multiple initializations, if it's part
of "attempt to execute the reference" rather than (as the spec says)
something the JVM does immediately *before* the first such attempt (or
other action that requires an initialized class for the action to begin).

I suppose you could change 3.1 to "see if the class is initialized, and
if not, initialize it", but even that would add to *every method call*
the overhead of a test-and-branch, and would still be dodgy at best on
spec-adherence grounds.
 

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

Similar Threads

Programming Challenge 2
Virtuous Hacking challenge 13
Tutorial challenge program help 19
small program 49
JFrame stays unusably small in applet 5
Tasks 1
[Challenge] Cookie Monster! 6
Html download challenge 25

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top