On Wed, 2024-04-10 at 12:03 +0200, stefan@xxxxxxxxx wrote: > Yes, there is an overflow when the value gets assigned to x > > u32 x = *a * *b; > > And after that line of code, x is a valid unsigned int, no matter what > value was assigned. And the compiler must not throw away that > unsignedness. If *a * *b does not overflow, x is a valid unsigned int. But if *a * *b overflows, x is not valid, at all. Its type does not matter. > Also an add can overflow: > > u64 faa(int a, int b) { > u32 x = a + b; > u64 r = x; > > And in this case the optimizer doesn't discard the variable x Only an overflow on *arithmetic operation* is undefined behavior. An overflow on *conversion* is not. In fact an "overflow on conversion" is even not referred as "overflow" in the standard. So in this case if a and b are both -1, x *must* be 0xfffffffdU, r *must* be 0xfffffffdULL, and there's no undefined behavior. So it will be incorrect (i.e. violating the standard, not "different from what a person thinks") to use a signed extension here, and the compiler does not do that. But for u16 a, b; u32 x = (int)a * (int)b; (int)a and (int)b must be non-negative, and since an overflow on multiplication is UB, (int)a * (int)b must be non-negative too. So it's valid (i.e. allowed by the standard, not "doing exactly what a person thinks") to use a signed extension (though maybe it's not optimal, and we may have a missed-optimization here). -- Xi Ruoyao <xry111@xxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University