C++ needs undefined behavior, but maybe less
think-cell.com
think-cell.com
> If it is implementation-defined, it is no longer considered an error by the C++ standard
I do't understand why implementation defined can't be "throws exception/abort on overflow for debug build and something more efficient for release builds". Why do they need a new category for that?
my understanding is that the proposal of "erroneous behavior" limits the scope of the consequences of triggering the behavior (like implementation-defined behavior), while still clearly marking it as erroneous and something to be diagnosed (like undefined behavior).
Regarding the diverse compiler point you made, that argument can be used to torpedo most ideas in this space. For example sanitizers started in clang, and now gcc and msvc have similar options, if something is a good idea, chances are the others will copy it. And relying on erroneously defined behavior (EB) to be a hard error, means relying on behavior that can differ across implementations and platforms which is problematic in itself. Plus, even relying on a hard error implies that EB has to be an error which is problematic for the reasons outlined above, or means it can't be used in the places you'd like to use it like signed integer overflow.
With signed integer overflow being the UB, sanitizers are able to catch them regardless of the level of optimization you apply to your code. "Debug" or "release".
And what you propose, and what I think Rust does, is in no way better because "something more efficient" is ambiguous at its best. I wonder what would that be considering that is a condition that you certainly _want_ to catch. I think the reason why Rust did it this way (by panicking on the overflows in non-optimized builds) is because it does not have support for sanitizers (yet).
Another option is to use a library like SafeInt [1] or Boost Safe Numerics [2] which offer drop-in replacement types like safe<int>. If you want to use raw unchecked integer types in release builds, you could do that using a typedef like my_int, in combination with a #if.
[0] https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html , the -ftrapv flag
[1] https://github.com/dcleblanc/SafeInt
[2] https://www.boost.org/doc/libs/release/libs/safe_numerics/do...
The example is wrong because compiler is allowed to do optimization in such context not due to the undefined behavior. The "within-thread as-if-serial" guarantees are still preserved and optimization still can be done even if undefined behavior is removed from the example.