On Thu, 30 Mar 2023 at 15:44, Jonathan Wakely wrote: > > On Thu, 30 Mar 2023 at 00:40, Jonathan Wakely via Libstdc++ > <libstd...@gcc.gnu.org> wrote: > > > > Tested powerpc64le-linux. Pushed to trunk. > > > > -- >8 -- > > > > Change ip::basic_endpoint to work in constant expressions, but only for > > C++20 and later (due to the use of a union, which cannot change active > > member in constexpr evaluation until C++20). > > > > During constant evaluation we cannot inspect the common initial sequence > > of basic_endpoint's union members to check whether sin_family == AF_INET > > or AF_INET6. This means we need to store an additional boolean member > > that remembers whether we have a v4 or v6 address. The address type can > > change behind our backs if a user copies an address to the data() > > pointer and then calls resize(n), so we need to inspect the sa_family_t > > member in the union after a resize and update the boolean. POSIX only > > guarantees that the sa_family_t member of each protocol-specific address > > structure is at the same offset and of the same type, not that there is > > a common initial sequence. The check in resize is done using memcmp, so > > that we avoid accessing an inactive member of the union if the > > sockaddr_in and sockaddr_in6 structures do not have a common initial > > sequence that includes the sa_family_t member. > > If we had > https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2641r2.html > then we wouldn't need the extra boolean. During constant evaluation we > could use the new magic function to check which union member is > active, and during runtime we could inspect the sa_family_t member > (still using memcmp, because POSIX doesn't guarantee a common initial > sequence, even though I think everybody does give it one in practice).
In fact, thinking about P2641 some more, I might revert this change. Instead of adding an extra bool member to support constexpr, I think I'll just remove the 'constexpr' keywords from basic_endpoint for now, and implement it in terms of just inspecting the sa_family_t member of the union members. And then later, once we have something like P2641, we can re-add the constexpr keywords and use is_within_lifetime during constant evaluation. That way we don't add a bool then need to take it away again, changing the ABI each time.