Do we have a Strict Aliasing rule violation in this code? I thought that int -> char and int -> std::byte are OK, but what about int8_t?
int main() {
int arr[8] = {1, 1, 1, 1, 1, 1, 1, 1}; // Little endian: 10000000 | 10000000 ....
int8_t *ptr = (int8_t*)arr; // Do we have a violation of the Strict Aliasing rule in this cast?
ptr += 3; // 100[0]0000 ....
cout << (int)*ptr << endl; // outputs 0
return 1;
}
This is perfectly fine and equivalent to a
reinterpret_cast. The cast in itself is never a strict aliasing violation; the access of the pointed-to object is. See What is the strict aliasing rule? for more details.This is undefined behavior ([basic.lval] p11) because you are accessing an
intthrough a glvalue of typeint8_t. There are only exceptions forchar,unsigned char, andstd::byte, andint8_tis most likely an alias forsigned char.This is undefined behavior:
- [expr.add] p6
What you're doing is effectively the same, just with
int8_tinstead ofunsigned int.The cast itself is always fine, but only
std::byteorcharhave special properties that would also makep += 3valid(1).int8_tis most likely an alias forsigned char, which has significantly less magical powers compared tounsigned charandstd::byte. See the appendix on this answer for a summary of magical powers.(1) The standard wording is defective and does not support that; see Is adding to a "char *" pointer UB, when it doesn't actually point to a char array?.