Most of the conversations around undefined behavior (UB) talk about how there are some platforms that can do this, or some compilers do that.
What if you are only interested in one platform and only one compiler (same version) and you know you will be using them for years?
Nothing is changing but the code, and the UB is not implementation-defined.
Once the UB has manifested for that architecture and that compiler and you have tested, can't you assume that from then on whatever the compiler did with the UB the first time, it will do that every time?
Note: I know undefined behavior is very, very bad, but when I pointed out UB in code written by somebody in this situation, they asked this, and I didn't have anything better to say than, if you ever have to upgrade or port, all the UB will be very expensive to fix.
It seems there are different categories of Behavior:
Defined
- This is behavior documented to work by the standardsSupported
- This is behavior documented to be supported a.k.a implementation definedExtensions
- This is a documented addition, support for low level bit operations likepopcount
, branch hints, fall into this categoryConstant
- While not documented, these are behaviors that will likely be consistent on a given platform things like endianness,sizeof
int
while not portable are likely to not changeReasonable
- generally safe and usually legacy, casting from unsigned to signed, using the low bit of a pointer as temp spaceDangerous
- reading uninitialized or unallocated memory, returning a temp variable, usingmemcopy
on a non pod class
It would seem that Constant
might be invariant within a patch version on one platform. The line between Reasonable
and Dangerous
seems to be moving more and more behavior towards Dangerous
as compilers become more aggressive in their optimizations