Das Hinzufügen von zwei 32-Bit-Ganzzahlen kann zu einem Ganzzahlüberlauf führen:
uint64_t u64_z = u32_x + u32_y;
Dieser Überlauf kann vermieden werden, wenn eine der 32-Bit-Ganzzahlen zuerst umgewandelt oder zu einer 64-Bit-Ganzzahl hinzugefügt wird.
uint64_t u64_z = u32_x + u64_a + u32_y;
Wenn der Compiler jedoch beschließt, den Zusatz neu zu ordnen:
uint64_t u64_z = u32_x + u32_y + u64_a;
Der ganzzahlige Überlauf kann immer noch auftreten.
Dürfen Compiler eine solche Neuordnung durchführen oder können wir darauf vertrauen, dass sie die Ergebnisinkonsistenz bemerken und die Ausdrucksreihenfolge unverändert lassen?
((uint32_t)-1 + (uint32_t)1) + (uint64_t)0
Ergebnisse in 0
, während (uint32_t)-1 + ((uint32_t)1 + (uint64_t)0)
Ergebnisse in 0x100000000
, und diese beiden Werte nicht gleich sind. Es ist also wichtig, ob der Compiler diese Transformation anwenden kann oder nicht. Aber ja, der Standard verwendet das Wort "Überlauf" nur für vorzeichenbehaftete Ganzzahlen, nicht für vorzeichenlose.
uint32_t
Werte sind - die nicht überlaufen, sondern umbrechen. Dies sind keine unterschiedlichen Verhaltensweisen.