According to this stackoverflow answer about C++11/14 strict alias rules:
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
the dynamic type of the object,
a cv-qualified version of the dynamic type of the object,
- a type similar (as defined in 4.4) to the dynamic type of the object,
- a type that is the signed or unsigned type corresponding to the dynamic type of the object,
- a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
- an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
- a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
- a
char
orunsigned char
type.
can we access the storage of other type using
(1) char *
(2) char(&)[N]
(3) std::array<char, N> &
without depending on undefined behavior?
constexpr uint64_t lil_endian = 0x65'6e'64'69'61'6e;
// a.k.a. Clockwise-Rotated Endian which allocates like
// char[8] = { n,a,i,d,n,e,\0,\0 }
const auto& arr = // std::array<char,8> &
reinterpret_cast<const std::array<char,8> &> (lil_endian);
const auto& carr = // char(&)[8]>
reinterpret_cast<const char(&)[8]> (lil_endian);
const auto* p = // char *
reinterpret_cast<const char *>(std::addressof(lil_endian));
int main()
{
const auto str1 = std::string(arr.crbegin()+2, arr.crend() );
const auto str2 = std::string(std::crbegin(carr)+2, std::crend(carr) );
const auto sv3r = std::string_view(p, 8);
const auto str3 = std::string(sv3r.crbegin()+2, sv3r.crend() );
auto lam = [](const auto& str) {
std::cout << str << '\n'
<< str.size() << '\n' << '\n' << std::hex;
for (const auto ch : str) {
std::cout << ch << " : " << static_cast<uint32_t>(ch) << '\n';
}
std::cout << '\n' << '\n' << std::dec;
};
lam(str1);
lam(str2);
lam(str3);
}
all lambda invocations produce:
endian
6
e : 65
n : 6e
d : 64
i : 69
a : 61
n : 6e
godbolt.org/g/cdDTAM (enable -fstrict-aliasing -Wstrict-aliasing=2 )