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