Citat:
Ursprungligen postat av
Nightling
result += ++val1 * val2 + (double)((val2 * val3 + val4) % val3 /val1);
Trots att operationerna +, *, &, ^ och | inte är helt
kommutativa och
associativa i C, p.g.a. signade tal, möjligheten för over-/underflow, tappad precision i flyttal, och sidoeffekter, får kompilatorn ändå utnyttja att de är det matematiskt och byta ordning på operanderna och/eller flytta parenteserna. T.ex. kan `(a + b) + c` beräknas som `(c + a) + b`. Det gäller bara när man använder
samma operator flera gånger i rad - inte kombinerat som med
distributivitet, och en subtraktion är alltid en subtraktion, inte en addition av det negativa talet.
Om a, b och/eller c är funktionsansrop (eller volatila minnesplatser) kan de anropas (accessas) i vilken ordning som helst. Om b var ett negativt tal som skulle förhindra overflow inför additionen med c, kan man ha skitit i det blå skåpet. Om a, b och c är extrema flyttal, kan evalutionsordningen vara skillnaden mellan liv och död.
Dela upp beräkningen i två statements.
EDIT: Då du konverterar en av additionens två operander, tror jag att kompilatorn
inte får byta ordning på dem. Där drog man tydligen gränsen... Och eftersom du inte modifierar någon variabel mer än en gång mellan sequence points, tror jag att resultatet faktiskt är definierat.