https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110348

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #6)
> (In reply to Jonathan Wakely from comment #5)
> > I agree with your WIP patch. The requirements for data() and size() to be
> > constant expressions are in p11 (11.2) which only apply if the static
> > assertions fails.
> 
> In other words, I think the paper is clear and clang is wrong here.
> 
> Although arguably what clang does is more useful. I'm not sure why you'd
> want to use a non-constexpr size() or data() that only compiles as long as
> the static assertion passes. It means you won't find out that your
> user-generated message can't actually be printed until you run on a target
> where the assertion fails.

Sure, if the standard is changed such that size() and data() must be constexpr,
it would be nice to check it.  Without full evaluation one can't guarantee it
will
be a constant expression and there could be tons of other reasons why it isn't
constant expression (say it returns some class and conversion operator isn't
constexpr, or it throws, or has asm and many other reasons).

For the M.data () not being a constant expression, it depends on the exact
wording as well.  Either the standard could drop the requirement that it is a
core constant expression altogether, then e.g. nothing will require that
(M.data (), 0) is constant expression when M.size () is 0.  Or it could say
that (M.data (), 0) is an integer constant expression, then one can verify
that, and then quietly try if M.data () is a constant expression; if it is, it
can grab the message from it using say GCC's c_getstr if it works.  If it
isn't, it would need to evaluate it character by character.

BTW, there is a third difference between my latest patch and clang++
implementation.
They reject static_assert (false, "foo"_myd); which I have in the testcase. 
IMHO
"foo"_myd doesn't match the syntactic requirements of unevaluated-string as the
https://eel.is/c++draft/dcl.pre#10 wording says, because unevaluated-string
non-terminal is string-literal with some extra rules, while
user-defined-literal is some other non-terminal.  And as I've tried to show in
the testcase, a constexpr operator ""
can return something on which .size () / .data () can be called and can satisfy
the requirements.

Reply via email to