"Lekker niet"? kom op, we kunnen dit toch wel als volwassenen bediscussieren?
Ik zie niet in waarom ik de code zou moeten compileren als mijn stelling is dat het niet zo relevant is welke instructies eruit komen rollen? Jouw punt dat de loads in een andere volgorde kunnen worden gedaan is nutteloos, want je kunt niets met die informatie.
kom maar op met de quote die zegt dat de Java specificatie garandeert dat statements op volgorde worden uitgevoerd. Die ga je ook niet vinden.
Vandaar dat ik het aanhaal

. Het is zodat het lijkt alsof ze van boven naar beneden worden uitgevoerd, vanuit het oogpunt van de uitvoerende thread. Maar in een topic als deze zeg je gewoon dat statements van boven naar beneden worden uitgevoerd. Uiteraard is de stelling voor statements wel wat gevaarlijker, ivm observeerbaar gedrag van een ándere thread.
Nouja, assignments zijn geen expressie
Oh, sinds wanneer niet? Is
(a = 3) + 5 geen geldige expressie in Java volgens jou?
maar increments zijn inderdaad wel interessante. Die moeten inderdaad daadwerkelijk van links naar rechts om de illusie te behouden
Nou ja, volgens jouw eigen redenatie hoeft dat helemaal niet.
Java:
1
2
| int a = 1;
int b = ++a * ++a; |
Kan ook worden gecompileerd worden als:
Om maar weer aan te geven, het is eigenlijk niet zo belangrijk welke code eruit komt rollen, zolang het eindresultaat maar matcht met de gestelde regels: evaluatievolgorde is van links naar rechts. Wat dus niet impliceert dat er ook maar iets daadwerkelijk wordt geëvalueerd.
Exceptions maken echter niet uit (zolang het maar blijft lijken dat de evaluatie van links naar rechts is).
Als a een lege int array is, geeft dit dan:
A. een IndexOutOfBoundsException
B. een ArithmeticException
C. kun je niet weten, want evaluatievolgorde is ongedefinieerd.
Je "zolang het maar blijft lijken dat de evaluatie van links naar rechts is" is natuurlijk de kern van de discussie. Bottom line is dat
3 / a.length niet mag worden geëvalueerd voor
a[0], aangezien
a[0] mogelijk side effects heeft (Het kan zowel een NullPointerException als een ArrayIndexOutOfBoundsException gooien).
Je stelling dat het alleen om functies gaat, wordt nu wel heel beperkt en kun je bijna beter omdraaien: het is alleen niet gedefinieerd voor simpele identifiers en operators die nooit kunnen throwen, want alleen dan valt er niets te observeren.
Eigenlijk kan je concluderen: wil je een programma schrijven, dan mag je aannemen dat de volgorde van links naar rechts is (en statements van boven naar beneden). Als je wilt weten wat er daadwerkelijk gebeurd, kom je er achter dat die aanname eigenlijk niet klopt
Maar dat is op zoveel niveaus. De IL kan niet overeenkomen met de code, de gejitte asm kan niet overeenkomen met de IL, en de uitvoering van de asm door de CPU kan vervolgens ook weer eens niet overeenkomen met de asm zelf (door out of order execution of out of order memory access). En bij al die dingen geldt dat het niet uitmaakt omdat je het gedrag toch niet kan observeren*
* Niet helemaal waar natuurlijk, zie Spectre en Meltdown
[
Voor 10% gewijzigd door
.oisyn op 13-12-2018 12:18
]