Take the following code
#include <iostream>
void func() {
int i = 2147483640;
while (i < i + 1)
{
std::cerr << i << '\n';
++i;
}
return;
}
int main() {
func();
}
This code is clearly wrong, as the while loop can only terminate if the signed int i
overflowed, which is UB, and hence the compiler may for instance optimize this into an infinite loop (which Clang does on -O3
), or do other sorts of funky things. My question now is: from my reading of the C++ standard, types that are equivalent up to signedness may alias (i.e. pointers int*
and unsigned*
may alias). In order to do some funky signed "wrapping", does the following have undefined behavior or not?
#include <iostream>
static int safe_inc(int a)
{
++reinterpret_cast<unsigned&>(a);
return a;
}
void func() {
int i = 2147483640;
while (i < safe_inc(i))
{
std::cerr << i << '\n';
++i;
}
return;
}
int main() {
func();
}
I have tried the above code with both Clang 8 and GCC 9 on -O3
with -Wall -Wextra -Wpedantic -O3 -fsanitize=address,undefined
arguments and get no errors or warnings and the loop terminates after wrapping to INT_MIN
.
cppreference.com tells me that
Type aliasing
Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:
- AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.
which from my reading means that for purposes of type aliasing, signedness is not considered, and the code using reinterpret_cast
has well-defined semantics (albeit being somewhat cheesy anyhow).
Your code is perfectly legal, cpp reference is a very good source. You can find the same information in the standard [basic.lval]/11
If a program attempts to access the stored value of an object through a glvalue whose type is not similar ([conv.qual]) to one of the following types the behavior is undefined:
the dynamic type of the object,
a type that is the signed or unsigned type corresponding to the dynamic type of the object,[...]