The boolean expression for each of the first two if statements is a compile-time constant so the compiler knows the value of i and j at compile time. However, the boolean expression for the third if statement is not a compile-time constant so the compiler does not know if k will be properly initialized at run-time. Therefore, a compiler error is generated due to the uncertainty of the state of k.

so I think it has the logic as Dan points out has to do with compile time constant.But something more.Before I proceed lets look what JLS has to say about if statements

We need to understand what is a compile time constant to the if statement, it is nothing but a boolean value.Generally, we provide if with an expression that leads to a boolean value.Now this expression needs to be evaluated in order to the statement to be executed.So here ,when we say if(1==1) we are still providing an expression to be evaluated at runtime.So the variable initialization still epends upon the value of expression,and there is an ambiguity as to whether j will be intialized or not and hence the error .But when we say if (true) we are directly supplying the required input for the if statement this is the compile time constant,And bcoz it is true compiler has no problem since the statement following will be executed.Now change the code to the following:

This is also a compile time constant but a false value which menas the compiler determines at compile time that this statement will never to be executed and churns out an error.

thanks bindesh for the detailed explaination. on running the code i just got one error of k not being initialized.

howz is your compiler giving 2 errors? i am using version 1.4...which is your version?

Bindesh Vijayan
Ranch Hand

Joined: Aug 21, 2001
Posts: 34

posted Jul 21, 2002 08:29:00

0

Zarina, I am still using the older one 1.2 .In the process of downloading newer one ( 1.4 )got errors two times when half of the download was complete. Downloading needs great amount of luck Thanks Bindesh Vijayan

zarina mohammad
Ranch Hand

Joined: Jun 26, 2002
Posts: 104

posted Jul 21, 2002 08:46:00

0

If the answer is varying with version? then how do we answer in the real exam ? i mean should the answer be different for SJCP(old version) and SJCP(new version).? i am planning to write the exam of older version.but at home i am using the new version for preparation of the exam. should i switch back to old version?

Dan Chisholm
Ranch Hand

Joined: Jul 02, 2002
Posts: 1865

posted Jul 21, 2002 08:59:00

0

Bindesh, It is logical to assume that expressions are evaluated at run time because some sort of operation must that place. However, the Java compiler does indeed evaluate expressions at compile time if the operands are constants. Such an expression is called a "constant expression". As an example, a constant expression is associated with each case statement within a switch statement. The following question from my mock exam illustrates the use of constant expressions.

At run time, the value of the switch expression is compared to the value of the constant expression associated with each case statement. The value of each constant expression, however, is evaluated a compile time. To further support the fact that the constant expressions are evaluated at compile time, consider the requirement that the value of the constant expression associated with a case statement must be assignable to the type of the switch expression otherwise a compile time error is generated. The compile time error can only be generated if the constant expression is indeed evaluated at compile time. Constant Expressions are discussed in Section 15.28 of the Java Language Specification [ July 21, 2002: Message edited by: Dan Chisholm ]

Dan, I believe the guys have a point here. Yes, you are correct that constant expressions are evaluated at compile time. So, it is true that in Zarina's code the expression 1 == 1 will be evaluated at compile time; but that is not the issue here. The issue is that real compilers have optimizations that go beyond what is specified in the JLS. For instance, the JLS nowhere says that the contained statement of an if-statement whose condition expression is evaluated to true in compile-time is always executed. In plainer English this means that, for the following code snippet,

the JLS does NOT require from a compiler to be so smart as to figure out that since the compile-time value of true and 1 == 1 is true it should consider the i = 1; and j = 1; as always executed, and thus consider variables i, j as always getting assigned a value. On the contrary, the JLS allows a compiler to be dumb enough as to ignore the obviously true value of both condition expressions and say: "Well, I dunno if the contained statement will always be executed, so it may be the case that i and j never get initialized... Let's throw a compile-time error here." It seems from what the guys in this thread (Zarina et al.) mention, that: - The 1.2 compiler instance they happened to use is smart enough to take into account the blatantly true value of the condition expression and don't throw a compile-time error there. - The 1.4 compiler used was even smarter as to figure out that the expression 1 == 1 is known to be true at compile time already, so it is certain that the j = 1; statement will be executed. So, it didn't throw a compile-time error for that expression either. However, the "imaginary" compiler for the purposes of the SCJP2 exam is assumed to have no compiler optimizations. So the answer to the question should be that all three expressions (i = ..., j = ..., k = ...) would result in compile-time errors. One may want to read JLS 14.20 ("Unreachable statements") and especially the last 4 lines in page 314 wrt this issue. Please note the conspicuous absense of any reference to an "always reachable" term. Also note that this is the sole reference to conditional compilcation in the JLS. Hope this helps, Panagiotis. [ July 21, 2002: Message edited by: Panagiotis Varlagas ]

Dan Chisholm
Ranch Hand

Joined: Jul 02, 2002
Posts: 1865

posted Jul 21, 2002 12:00:00

0

Panagiotis, Your argument is an interesting one. However, I am not yet convinced that a discussion of unreachable statements is relavent here. The Java compiler is required to generate an error if unreachable code is detected. As stated immediately following the four lines that you pointed out, the rationale for the dumbing down of the compiler's ability to detect unreachable code is the desire to allow the programmer to intentionally use an "if" statement to disable code based on the state of a debug expression that may be set to the boolean constant "false". In this case the compiler is not simply given the option to fail to detect the unreachable state of the code inside of the "if" statement. In fact, the compiler is required to ignore the unreachable state of the code inside of the "if" statement. The dumbing down of the compiler is not an option offered to the developers of compilers. Instead, it is a requirement dictated to the developers of compilers. Constant expressions are defined by the JLS and their use in case labels and assignment conversions is explicitly stated in section 15.28. However, section 15.28 does not mention the use of constant expressions in relation to "if" statements. Even so, we know that the compiler does indeed make use of constant expressions in "if" statements while determining the initialization state of variables. For example, the following compiles and runs without error.

The compiler knows that a, b, c, and d are initialized because the compiler evaluated the constant expressions of the "if" statements. However, the following does not compile because the variable "e" is no longer "final" and is therefore not a compile-time constant.

The above examples demonstrate the expected behavior of the compiler. Furthermore, the above examples in no way demonstrate a violation of the Java Language Specification. In view of the fact that the above behavior does not violate the JLS and is consistent with the behavior of the compiler, then why would Sun develop an exam question that tests your willingness to reject the known behavior of Java? At this point, I am not convinced that Sun would require an answer that is not supported by the JLS and is not consistent with the behavior of the compiler. In any case where the compiler or the JVM violates the JLS or fails to support the JLS, then we should select the answer that is consistent with the JLS. However, to the best of my knowledge, the examples above do not violate the JLS or fail to support the JLS. At this point, I believe that we should select the answer that reflects the behavior demonstrated by the examples contained in this post. However, my position remains flexible and I welcome any arguments against my position.

Panagiotis Varlagas
Ranch Hand

Joined: Nov 27, 2000
Posts: 233

posted Jul 22, 2002 01:51:00

0

Dan, I guess my reference to JLS 14.20 confused things rather than clearing them up... Let's start from scratch again. Do we agree in two basic premises? (1) true, 1 == 1, "aaa" != "zzz" are all constant expressions, get evaluated at compile time, and their value is true? (2) A statement of the form

has it's condition expression evaluated at compile time, and considers <a statement> to be reachable? I guess we agree in the above two premises, so we have a common starting point. Note, that premises (1) and (2) are based strictly on what the JLS specifies. Now, I am asking you this: Does the JLS anywhere specify that <a statement> should be considered by the compiler to be always reached? The answer is no. Even, though, we all know that it always shall be reached, and even though the compiler has all the information to deduce that fact at compile time (because it has evaluated the constant expression at compile time already and its value its true), the JLS does not force the compiler to consider the <a statement> as "always reached". I.e. the JLS leaves a lot of leeway to the compiler designer to add all those smart compiler optimizations that will take the value of the condition expression into account if it is evaluated to true at compile time already, or just ignore the value altogether if the compiler designer wants (say) a quick-n-dirty compiler implementation. Neither of the two compiler implementations would violate JLS. Both would respect it, because the JLS leaves a lot of leeway in that respect. So, in the particular examples Zarina et al. have put forth it seems that the particular 1.4 compiler is smarter than the particular 1.2. compiler. But, one could have an even dumber compiler that would not even exploit the blatantly true expression in a if (true) {...} statement. Such a compiler would still satisfy JLS; it would just have no compiler optimization to take advantage of the blatantly true value of (true). So, given that, for the purposes of the SCJP exam, no compiler optimizations should be counted upon, I believe the "imaginary" compiler of the SCJP exam should be considered to have "dumb" behavior wrt exploiting condition expressions known to be true at compile time. Hence, my belief on what should be the correct answer What do you think? I am looking forward to your (Dan) and your (everybody's!) comments and arguments on this line of thought of mine. Panagiotis. [ July 22, 2002: Message edited by: Panagiotis Varlagas ]

Dan Chisholm
Ranch Hand

Joined: Jul 02, 2002
Posts: 1865

posted Jul 22, 2002 10:41:00

0

Panagiotis, I agree that your reasoning is logical, and I agree that Sun has the option to develop an exam that assumes the use of a compiler that does no optimizations beyond those explicitly stated in the JLS. I'm just not convinced that Sun actually has done that. My point in my previous post was that the Java compilers produced by Sun do indeed make use of constant expressions when checking the initialization state of variables at compile time. Although we have not found a JLS requirement to do the checks we know that they are actually done. Sun has the option to test a person's ability to differentiate between strict JLS requirements and the actual behavior of the compiler, but what would be accomplished by doing so? The number of questions in the SCJP exam is limited, and there is a lot of important material that needs to be covered. Why would Sun waste a question on testing a person's willingness to disregard the actual behavior of the compiler if the actual behavior does not violate the JLS? I understand that the JLS does not prevent the development of a less sophisticated compiler, but why would Sun care to test a person's awareness of that option? Secondly, why would anyone care to use a less sophisticated compiler? As long as the actual behavior of the compiler does not violate the JLS, any exam question that tests a person's willingness to disregard that behavior would be highly controversial. Why would Sun include such a question in the exam? At this point, I still believe that Sun would either not put such a controversial question in the exam or Sun would accept an answer that is consistent with the actual behavior of the compiler as long as the actual behavior does not violate the JLS. Of course, we are both voicing personal assumptions here. It would be interesting to hear some opinions from the bartenders or from the authors of some of the exam preparation books.

Panagiotis Varlagas
Ranch Hand

Joined: Nov 27, 2000
Posts: 233

posted Jul 23, 2002 02:14:00

0

"I agree that Sun has the option to develop an exam that assumes the use of a compiler that does no optimizations beyond those explicitly stated in the JLS. I'm just not convinced that Sun actually has done that."

I was under the impression that Sun had done that, but I am not in a position to corroborate that feeling of mine with any hard facts. I guess this is the core of the "controversy" here: When Sun asks a question in the lines of "What does this piece of code produce when compiled/run?", what compiler does Sun assume for the purposes of the exam? A compiler that "minimally" satisfies the JLS, or a typical compiler such as the one that comes with the JDK (javac) with all the optimizations (probably undocumented ones) such a compiler would carry? I would gravitate towards the first option (the "minimal" compiler) but I guess we need to find something "official" written down, or hear word from Sun Ed as to what THEY assume wrt to this compiler issue. What we (you, me, et al.) believe/think/guess may be mistaken or, even if it were correct, would not be authoritative enough for the guys preparing for the exam to depend on (IMHO).

"Why would Sun include such a question in the exam? At this point, I still believe that Sun would either not put such a controversial question in the exam or Sun would accept an answer that is consistent with the actual behavior of the compiler as long as the actual behavior does not violate the JLS."

I wholeheartedly agree with you on this one. Why would Sun include such a question in the exam? There are a zillion clear-cut questions it could choose from that would spark no controversy whatsoever.

"why would anyone care to use a less sophisticated compiler?"

A possible (hypothetical though) case that comes to mind is in a limited-resource environment such as a wireless device (PDA, cell phone, etc.). If (for whatever idiosyncratic reason) one is running javac on a limited-resource environment, one would want the process to be as lightweight as possible; so, the compiler designer may want to throw out the window any "optimizations" and be contended with the bare minimum. I agree with you that the opinion of bartenders, authors, etc. (not to mention SunEd itself) would be most appropriate here. I guess they're all getting a tan right now , while we are sitting in front of a computer discusing compilers and specifications Cheers, Panagiotis. [ July 23, 2002: Message edited by: Panagiotis Varlagas ]

When Sun asks a question in the lines of "What does this piece produce when compiled/run?", what compiler does Sun assume for the purposes of the exam? Just my $.02... The only assumed compiler is you, the SCJP-aspirant. The JLS specifies an "ideal" compiler which should be taken as the base compiler. That doesn't mean that you have to know the JLS by heart, but that whenever you are in doubt and that the Sun compiler (javac reference implementation) does not produce the expected results (because it does not fully implement the spec), you have to refer to the JLS as the highest authority.

Originally posted by Valentin Crettaz:When Sun asks a question in the lines of "What does this piece produce when compiled/run?", what compiler does Sun assume for the purposes of the exam? Just my $.02... The only assumed compiler is you, the SCJP-aspirant. The JLS specifies an "ideal" compiler which should be taken as the base compiler. That doesn't mean that you have to know the JLS by heart, but that whenever you are in doubt and that the Sun compiler (javac reference implementation) does not produce the expected results (because it does not fully implement the spec), you have to refer to the JLS as the highest authority.

and there are ambiguities in JLS also.... so compilers take advantage of these ambugities too

"Thanks to Indian media who has over the period of time swiped out intellectual taste from mass Indian population." - Chetan Parekh