C-Programmierer kann sich Verhalten des Java-Compilers nicht erklären



  • Wieso zum Teufel nochmal bekomme ich bei diesem Java-Code KEINE Fehlermeldung

    int a = 6;
    a *= true ? 3.45 : 1;
    

    Der Java-Compiler gibt noch nicht einmal eine Warnung aus und liefert als Ergebnis 20! Ich dachte der Java-Compiler wandelt float nicht automatisch in einen int und gibt sogar eine Fehlermeldung aus.

    Beobachtung:

    a = true ? 3.45 : 1; funktioniert dagegen nicht!

    Bitte erklärt/beweist eure Aussage mit Bezug auf die Java-Dokumentation.

    Danke



  • Das ist tatsächlich ein seltsames Verhalten. Scheint aber kein Bug im Compiler zu sein, weil das sowohl der javac frisst als auch der Eclipse-Compiler. Auffällig ist, dass es bei ner Zuweisung nicht mehr klappt.
    Du kannst diesen Code übrigens reduzieren auf

    int a = 6;
    		a *= 3.45;
    

    Und es wird immer noch kompiliert.

    Davon abgesehen, dass so ein Statement recht komisch und wohl eher selten anzutreffen ist, stört mich das jetzt auch ein bisschen. In C# ist das jedenfalls illegal.



  • Eine Erklärung muss es doch geben, oder?
    Außerdem glaube ich nicht, dass das Compilerabhängig ist!



  • Es hätte ja ein Bug im Compiler sein können. Eine Erklärung gibt es sicher, irgendwo versteckt in
    The Java language specification

    Ich kanns mir jetzt aber auch nicht spontan erklären und gut find ich es schon gleich gar nicht.

    btw. wunderts mich, was das damit zu tun hast, dass du ein C-Programmierer bist. Da ist ja so ein implizite Umwandlung erst recht legal.



  • Optimizer schrieb:

    Da ist ja so ein implizite Umwandlung erst recht legal.

    Genau! Und da denkt man sich als C-Programmierer: Hey, andere Sprache sind in dieser Hinsicht bestimmt viel strenger. Und was sehe ich da... sowas ist auch in Java "vorhanden"?!

    Ich muss sagen, dass ich von euch etwas enttäuscht bin , denn ich bin der Meinung, dass es bei einer Sprache vor allem auf die Einzelheiten/Kleinigkeiten ankommt. Natürlich kann ich ein Java Programm adhoc verstehen (aber eben diese Kleinigkeiten nicht...). 😞



  • IMHO macht der Java Compiler impliziet einen int cast. Bei diesem cast werden einfach die Nachkommastellen abgeschnitten. 6*3.45=20.7 und (int) 20.7 = 20.



  • Das ist ja nicht die Frage. Die Frage ist, warum der Compiler implizit einen cast macht, bei dem Informationen verlorengehen. Bei

    x = x * 2.3; darf er es nicht und bei x *= 2.3 anscheinend schon.



  • Ich denke das liegt an der Kurzform des Ausdrucks x*=3.45.

    Das bedeutet für den Compiler überprüfe, ob ein cast nötig ist und führe diesen durch. Wenn der Benutzer dies nicht möchte kann er ja ausführlich schreiben x = x* 3.45.



  • Magoon schrieb:

    Ich denke das liegt an der Kurzform des Ausdrucks x*=3.45.

    Das bedeutet für den Compiler überprüfe, ob ein cast nötig ist und führe diesen durch. Wenn der Benutzer dies nicht möchte kann er ja ausführlich schreiben x = x* 3.45.

    Wie Optimizer schon sagt, wo steht diese Regel, das der Compiler das Ergebnis hier implizit umwandeln soll?

    Von einem int in einen größeren Typ wird automatisch umgewandelt, aber ich habe nirgends gelesen, dass es Situationen gibt, wo es andersherum auch funzt!



  • 15.26.2 Compound Assignment Operators

    All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the left-hand operand is of type String.

    A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once. Note that the implied cast to type T may be either an identity conversion (§5.1.1) or a narrowing primitive conversion (§5.1.3). For example, the following code is correct:

    Q> The Java Language Specification



  • Damit ist es wohl geklärt, auch wenn es mir nicht gefällt.


Anmelden zum Antworten