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...

Reply via email to