https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110348
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org, | |redi at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I wonder if the paper wording isn't incorrect, or at least comparing the clang++ implementation vs. the paper gives some differences. One (minor) is that they emit errors when the size () and/or data () members aren't constexpr, while the paper as voted in only requires that "- the expression M.size() is implicitly convertible to std::size_t, and - the expression M.data() is implicitly convertible to ”pointer to const char”." unless the static assertion fails. The WIP patch doesn't do that, only effectively diagnoses it during constant evaluation of those when the static assertion fails. More important, they have in the testcase something similar to what I filed in PR111122, but let's use what works also in GCC: struct T { const char *d = init (); constexpr int size () const { return 2; } constexpr const char *data () const { return d; } constexpr const char *init () const { return new char[2] { 'o', 'k' }; } constexpr ~T () { delete[] d; } }; constexpr int a = T{}.size (); // Ok, a = 2 constexpr int b = T{}.data ()[0]; // Ok, b = 'o' constexpr const char *c = T{}.data (); // Not constant expression, because it returns // address from new which is later in the dtor deleted. static_assert (false, T{}); // Valid? "- M.data(), implicitly converted to the type ”pointer to const char”, shall be a core constant expression and let D denote the converted expression, – for each i where 0 ≤ i < N , D[i] shall be an integral constant expression, and" Now, I believe T{}.data () is not a core constant expression exactly because it returns address of later deleted heap object, but sure, both T{}.data ()[0] and T{}.data ()[1] are integral constant expressions. I don't know how std::format if constexpr (is it?) or string_view etc. work, do they need M.data () not be actual constant expression and only M.data ()[0] through M.data ()[M.size () - 1] constant expressions? In the patch I can surely try to constant expr evaluate M.data () quietly and if it isn't constant expression, just use a slower way which will ask for each character individually. More important question is what is the intention for the standard...