public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "andysem at mail dot ru" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/98978] New: Consider packing _M_Engaged in the tail padding of T in optional<> Date: Fri, 05 Feb 2021 17:14:39 +0000 [thread overview] Message-ID: <bug-98978-4@http.gcc.gnu.org/bugzilla/> (raw) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98978 Bug ID: 98978 Summary: Consider packing _M_Engaged in the tail padding of T in optional<> Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: andysem at mail dot ru Target Milestone: --- Using std::optional with some types may considerably increase object sizes since it adds alignof(T) bytes worth of overhead. Sometimes it is possible to avoid this overhead if the flag indicating presence of the stored value (_M_Engaged in libstdc++ sources) is placed in the tail padding of the T object. This can be done if std::optional constructs an object of a type that derives from T, which has an additional bool data member that is initialized to true upon construction. The below code roughly illustrates the idea: template< typename T > struct _Optional_payload_base { struct _PresentT : T { const bool _M_Engaged = true; // Forwarding ctors and other members }; static constexpr size_t engaged_offset = offsetof(_PresentT, _M_Engaged); struct _AbsentT { unsigned char _M_Offset[engaged_offset]; const bool _M_Engaged = false; }; union _Storage { _AbsentT _M_Empty; _PresentT _M_Value; _Storage() : _M_Empty() {} // Forwarding ctors and other members }; _Storage _M_payload bool is_engaged() const noexcept { return *reinterpret_cast< const bool* >(reinterpret_cast< const unsigned char* >(&_M_payload) + engaged_offset); } }; The above relies on some implementation details, such as: - offsetof works for the type T. It does for many types in gcc, beyond what is required by the C++ standard. Maybe there is a way to avoid offsetof, I just didn't immediately see it. - The location of _M_Engaged in both _PresentT and _AbsentT is the same. This is a property of the target ABI, and AFAICS it should be true at least on x86 psABI and I think Microsoft ABI. The above will only work for non-final class types, for other types, and where the above requirements don't hold true, the current code with a separate _M_Engaged flag would work.
next reply other threads:[~2021-02-05 17:14 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-02-05 17:14 andysem at mail dot ru [this message] 2021-02-05 17:58 ` [Bug libstdc++/98978] " redi at gcc dot gnu.org 2021-02-05 18:00 ` redi at gcc dot gnu.org 2021-02-05 20:44 ` andysem at mail dot ru 2021-02-06 17:26 ` redi at gcc dot gnu.org 2021-08-31 16:24 ` redi at gcc dot gnu.org 2022-09-07 12:30 ` redi at gcc dot gnu.org 2022-09-18 12:27 ` andysem at mail dot ru
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-98978-4@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).