Given the following code
#include <cassert>
#include <climits>
#include <cstdint>
#include <iostream>
static_assert(CHAR_BIT == 8, "A byte does not consist of 8 bits");
void func1(const int32_t& i)
{
const unsigned char* j = reinterpret_cast<const unsigned char*>(&i);
for(int k = 0; k < 4; ++k)
std::cout << static_cast<int>(j[k]) << ' ';
std::cout << '\n';
}
void func2(const int32_t& i)
{
const unsigned char (&j)[4] = reinterpret_cast<const unsigned char (&)[4]>(i);
for(int k = 0; k < 4; ++k)
std::cout << static_cast<int>(j[k]) << ' ';
std::cout << '\n';
}
int main() {
func1(-1);
func2(-1);
}
From the language rules it is clear that func1 is fine, as pointers to unsigned char can alias any other type. My question is: does this extend to C++ references to C-arrays with known length? Intuitively I would say yes. Is func2 well-defined or does it trigger undefined behavior?
I have tried compiling the above code using Clang and GCC with every possible combination of -Wextra -Wall -Wpedantic and UBSAN, and have gotten no warnings and always the same output. That obviously doesn't state that there's no UB, but I couldn't trigger any of the usual strict-aliasing type optimization bugs.