c++11 - Is this union compatible with strict-aliasing rules? -
is ok use both parts of union if know parts don't overlap? in example, ok use both buf[31] ps?
struct ptrsize { const char *data; size_t size; }; class smallstringornot { union { ptrsize ps; char buf[32]; } pb; public: bool issmallstring() const { return pb.buf[31] != 0; } smallstringornot(const char *str) { size_t len = strlen(str); if (len && len < 31) { memcpy(pb.buf, str, len); pb.buf[31] = len; } else { pb.ps.data = str; pb.ps.size = len; pb.buf[31] = 0; // ok, accessing buf right after ps? } } ptrsize asptrsize() const { if (issmallstring()) { return ptrsize{pb.buf, pb.buf[31]}; } else { return pb.ps; } } };
unfortunately code not ok: @ least not in "undefined behaviour"-zone, since in c++ legal access union
through char
member, have no guarantee modifying buf[31]
not altering ps.data
or ps.size
. in 128-bit machine surely doing it.
on more normal architectures, code should fine 100% guarantee should refer compiler documentation, since size_t
in principle bigger void*
. example, on 64-bit machine theoretically have 192-bit ps.size
member (which summed 64 bit of ps.data
pointer make ptrsize
overlap buffer.
Comments
Post a Comment