Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / February 2006

Tip: Looking for answers? Try searching our database.

Possible contradiction between JLS and Sun's Java compiler

Thread view: 
Oliver Wong - 09 Feb 2006 20:22 GMT
From the JLS 3rd edition:

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.26

<quote>
a=b=c means a=(b=c), which assigns the value of c to b and then assigns the
value of b to a.
</quote>

   I'm inferring that if "a" and "c" are double precision floating points,
and "b" is a single precision floating point, then the assignment from "c"
to "b" may result in some rounding, and the assignment to "a" will give "a"
the rounded value in "b", and not the original value from "c".

   However, a friend of mine said when they disassembled the code produced
by javac essentially says "read c; duplicate; write b; write a;" which seems
to contradict what the JLS claims.

   I'm at work right now, and I don't have easy access to a class file
disassembler, so I was wondering if someone could verify whether JavaC and
the JLS really do contradict each other for me.

   - Oliver
Monique Y. Mudama - 09 Feb 2006 20:37 GMT
> From the JLS 3rd edition:
>
[quoted text clipped - 17 lines]
> disassembler, so I was wondering if someone could verify whether JavaC and
> the JLS really do contradict each other for me.

You seem to be talking about the Sun jre specifically ...

It doesn't seem like a violation of the spec to make something behave
with better precision than is promised in the spec.

Signature

monique

Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html

Oliver Wong - 09 Feb 2006 21:06 GMT
>> From the JLS 3rd edition:
>>
[quoted text clipped - 26 lines]
>
> You seem to be talking about the Sun jre specifically ...

   I think this is a "compile-time" issue, in that assuming the JLS is
correct, the implementation of Javac is emitting an incorrect sequence of
bytecode (if my friend's claim is actually true). So, I am indeed speaking
of Sun's specific implementation (e.g. perhaps other compilers, like the
Sable Java Compiler, emits the correct bytecode), but it'd be more of a JDK
issue than a JRE one, if anything.

> It doesn't seem like a violation of the spec to make something behave
> with better precision than is promised in the spec.

   Software might intentionally be using the fact that "a" should contain
the rounded value, and would behave incorrectly if they got the
higher-precision value.

   It seems strange to me that Sun would overlook this, since they spend a
large amount of time in the JLS, for example, explaining the concept of
"FP-Strict" modes:

<quote>
Within an FP-strict expression, all intermediate values must be elements of
the float value set or the double value set, implying that the results of
all FP-strict expressions must be those predicted by IEEE 754 arithmetic on
operands represented using single and double formats. Within an expression
that is not FP-strict, some leeway is granted for an implementation to use
an extended exponent range to represent intermediate results; the net
effect, roughly speaking, is that a calculation might produce "the correct
answer" in situations where exclusive use of the float value set or double
value set might result in overflow or underflow.
</quote>

   - Oliver
Monique Y. Mudama - 09 Feb 2006 23:42 GMT
>> It doesn't seem like a violation of the spec to make something
>> behave with better precision than is promised in the spec.
>
>     Software might intentionally be using the fact that "a" should
>     contain the rounded value, and would behave incorrectly if they
>     got the higher-precision value.

I'm sorry; somehow I completely glossed over the mixing of double and
float in your description.  That obviously makes a difference.

Signature

monique

Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html

Eric Sosman - 09 Feb 2006 20:58 GMT
Oliver Wong wrote On 02/09/06 15:22,:
> From the JLS 3rd edition:
>
[quoted text clipped - 17 lines]
> disassembler, so I was wondering if someone could verify whether JavaC and
> the JLS really do contradict each other for me.

   Using javac 1.4.2_04-b05, this source

public class Assign {
   public static void main(String[] unused) {
    double d1 = Math.PI;
    float f;
    double d2;
    d2 = f = (float)d1;
       System.out.println(d2 == d1);
   }
}

... compiles to this bytecode (as shown by javap):

public class Assign extends java.lang.Object{
public Assign();
 Code:
  0:    aload_0
  1:    invokespecial    #1; //Method java/lang/Object."<init>":()V
  4:    return

public static void main(java.lang.String[]);
 Code:
  0:    ldc2_w    #2; //double 3.141592653589793d
  3:    dstore_1
  4:    dload_1
  5:    d2f
  6:    dup
  7:    fstore_3
  8:    f2d
  9:    dstore    4
  11:    getstatic    #4; //Field java/lang/System.out:Ljava/io/PrintStream;
  14:    dload    4
  16:    dload_1
  17:    dcmpl
  18:    ifne    25
  21:    iconst_1
  22:    goto    26
  25:    iconst_0
  26:    invokevirtual    #5; //Method java/io/PrintStream.println:(Z)V
  29:    return

}

... and produces this output when executed:

false

... so your friend is mistaken, at least for this version.

Signature

Eric.Sosman@sun.com

Chris Uppal - 09 Feb 2006 21:05 GMT
> <quote>
> a=b=c means a=(b=c), which assigns the value of c to b and then assigns
> the value of b to a.
> </quote>

[...]
>     However, a friend of mine said when they disassembled the code
> produced by javac essentially says "read c; duplicate; write b; write a;"
> which seems to contradict what the JLS claims.

The following code will not compile under JDK1.4.2 or 1.5.0.
==========
class Abc
{
static void
method()
{
 double a;
 float b;
 double c = 27.3;

 a = b = c;
}
}

==========

The compiler won't accept it without a cast of c to float.  With the cast it
(1.4 and 1.5) produce the bytecode you'd expect (with converstions from double
to float and back again).  Note, btw, that b takes up 1 stack slot while a and
c take up 2 each -- which makes it hard to see how the compiler could "get
away" with generating incorect code.

FWIW, the actual disassembly is:
   ldc2_w 27.3
   dstore_3
   dload_3
   d2f
   dup
   fstore_2
   f2d
   dstore_0
   return

Perhaps your friend has a more complicated example ?

   -- chris
Oliver Wong - 09 Feb 2006 21:12 GMT
> Perhaps your friend has a more complicated example ?

   Yeah, I guess I should just quote the message he wrote:

<quote>
I think that the bytecode produced by javac just doesn't follow the
given clausule in the language spec, as the value assigned to a is the
value directly read from c.

I have no idea whether this means anything (e.g. with volatile variables
and multiple writer threads to b in practise. Having e.g. two threads
such that
thread 1)
 while(true) {
    a = b = 1;

    if(a == 2) {
        System.out.println("foobar");
    }
 }

and then there's another thread 2)
 while(true) {
    b = 2;
 }

Under my understanding, using JLS semantics (the variables are
volatile..), this 'foobar' would be "sometime" written. Using javac
semantics, it is never written.
</quote>

   - Oliver
Eric Sosman - 09 Feb 2006 22:09 GMT
Oliver Wong wrote On 02/09/06 16:12,:

>>Perhaps your friend has a more complicated example ?
>
[quoted text clipped - 26 lines]
> semantics, it is never written.
> </quote>

   Okay, this is a little different from the example
in the posting that started the thread.  I think your
friend is misunderstanding the JLS.  Your friend can be
forgiven, because the quoted bit of JLS ("assigns the
value of c to b and then assigns the value of b to a")
is imprecise.  Presumably, the JLS authors were trying
to make the document more understandable, so they put
in little snippets of less formal language to get their
points across.

   However, the quoted piece comes from a short paragraph
describing the right-to-left associativity of assignment,
not the values assigned.  A little further along in the
section we find

    "... the result of the assignment expression is
    the value of the variable after the assignment has
    occurred."

Even this is a little fuzzy, but I do not believe this can
be construed as requiring an actual read of `b' after assigning
to it (how long after the assignment should the read occur?),
but as a shorthand way to say that the result is the value
assigned to the `b'.

   Your friend seems to think `a = b = 1;' is equivalent
to `b = 1; a = b;', with the possiblity that `b' might be
modified between the two assignments.  Instead, I think
he should read it as `a = (b = 1);', emphasizing that `a'
is set to the result of the assignment expression `b = 1',
and that this is `1' converted to the type of `b'.  So the
compiler is justified in producing the same bytecode as
for `b = 1; a = 1;', because the value of `b = 1' is 1.

Signature

Eric.Sosman@sun.com

Oliver Wong - 09 Feb 2006 22:47 GMT
>    Okay, this is a little different from the example
> in the posting that started the thread.

   Yes, I had previously (erroneously) assumed that the two examples
illustrated the same issue, but that the one with floats and doubles was
easier to understand, which was why I went for that one first.

> I think your
> friend is misunderstanding the JLS.  Your friend can be
[quoted text clipped - 28 lines]
> compiler is justified in producing the same bytecode as
> for `b = 1; a = 1;', because the value of `b = 1' is 1.

   I had to re-read your explanation and the appropriate sections of the
JLS 3 or 4 times, but I think I got it now, and what you say makes sense.
Thanks.

   - Oliver
Roedy Green - 10 Feb 2006 04:16 GMT
>a=b=c means a=(b=c)

that sort of code is begging for trouble. It confuses maintenance
programmers and attracts implementation bugs since it is not obvious
how it should behave. Only lawyers can decide.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.