By default signed overflow is undefined behaviour.
My understanding of gcc (based on https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html and What does -fwrapv do?) was that using -fwrapv made gcc treat signed overflow as being well defined behaviour.
However, comments on another question seem to say that signed overflow is still undefined behaviour even when this flag is on.
Is signed overflow well defined in gcc with -fwrapv? If not, then what is the purpose of -fwrapv?
In contrast, the C standard says that signed integer overflow leads to undefined behavior where a program can do anything, including dumping core or overrunning a buffer. The misbehavior can even precede the overflow. Such an overflow can occur during addition, subtraction, multiplication, division, and left shift.
-fsanitize=unsigned-integer-overflow : Unsigned integer overflow, where the result of an unsigned integer computation cannot be represented in its type. Unlike signed integer overflow, this is not undefined behavior, but it is often unintentional.
— the sign bit has the value −(2N − 1) (one's complement). Nowadays, all processors use two's complement representation, but signed arithmetic overflow remains undefined and compiler makers want it to remain undefined because they use this undefinedness to help with optimization.
"Signed integer overflow" means that you tried to store a value that's outside the range of values that the type can represent, and the result of that operation is undefined (in this particular case, your program halts with an error).
Given the GCC documentation says:
-fwrapv
This option instructs the compiler to assume that signed arithmetic overflow of addition, subtraction and multiplication wraps around using twos-complement representation.
I'd characterize that as an implementation-specific extension that provides clearly defined behavior for what otherwise would be undefined behavior in standard C - if and only if the underlying hardware behaves that way.
Pedantically, I'd say it's still undefined behavior by the C standard, but you're instructing the compiler to act in a specific, non-portable but predictable manner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With