public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "dangelog at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug libstdc++/113060] std::variant converting constructor/assignment is non-conforming after P2280?
Date: Mon, 18 Dec 2023 14:32:51 +0000	[thread overview]
Message-ID: <bug-113060-4-6fd4XvLZVv@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-113060-4@http.gcc.gnu.org/bugzilla/>

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

--- Comment #2 from Giuseppe D'Angelo <dangelog at gmail dot com> ---
(In reply to Jonathan Wakely from comment #1)
> (In reply to Giuseppe D'Angelo from comment #0)
> > GCC 14 implements P2280 (see #106650). 
> 
> N.B. if you say "Bug 106650" or "PR 106650" or "bug #106650" or pretty much
> anything except just #106650 then bugzilla makes it a clickable link :)

D'oh! 


> > it seems that variant<float> should indeed accept construction from IC.
> 
> I'm not convinced that this change to the semantics of std::variant was an
> intended side effect of https://wg21.link/P2280 -- I think I'd prefer if the
> committee confirmed it.

Ok, I'll raise the question to LEWG. Or maybe EWG?


> The standard doesn't say that it _should_ work in a constant expression, it
> seems like you're assuming that because it's now possible to implement it so
> that it works, that it's required to work.
> 
> My reading of [variant.ctor] p14 is that "some invented variable x" is not a
> constant expression, so using std::declval as a stand-in for "some invented
> variable" is fine.


But it does say how you get that x, you get it from the statement:

  Tj x[] = {std​::​forward<T>(t)};

Nowhere in there's a call to declval. My reasoning is simply that if you spell
FUN out for Ti = float, something like this (although the standard doesn't
really specify the signature of FUN, which is not ideal):

  template <typename T>
  auto FUN_float(T &&t) {
      float x[] = {std​::​forward<T>(t)};
  }

then FUN_float(IC{}) is well-formed after P2280.

Note that in general

  IC c;       // not const!!!
  float f{c}; // OK

is well-formed, and this is even before P2280. What seems to have changed with
P2280 is that references do not disqualify expressions from being constant, and
thus we can now detect this case a requires-expression that uses references.


> If we made this change, then some cases that compile today would become
> ill-formed, e.g. see PR 113007. Under your reading, conversion from the
> constant 42 would be valid for both int64_t and double, and so the
> initialization would be ill-formed. But it would be well-formed when using a
> non-constant int equal to 42.

Are you sure it would? FUN_double(42) should be still ill-formed (!), due to
narrowing. 

My reasoning, in the context of P0870 (is_convertible_without_narrowing), is
that int->double requires a lvalue-to-rvalue conversion, and then this kicks in
https://eel.is/c++draft/expr.const#5.9 , disqualifying `t` from being treated
as a constant expression. So then the list-initialization of `x` triggers
narrowing.

This is different from IC->double, where there's no lvalue-to-rvalue conversion
(!), it's described here
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0870r5.html#ch5.9

Testcase: https://gcc.godbolt.org/z/rfvnfvYzs


> Apart from the fact it would be a breaking change, the difference in
> behaviour between runtime and compile time would be surprising. It would
> also mean that std::is_constructible would be misleading: it would say you
> can construct variant<long, double> from 42, but when you try to do that it
> would fail to compile.

Sure, I'm really struggling at squaring the P2280 rules with detecting
narrowing conversions, but I'm not sure if this would actually break. (And I'm
not sure if something _else_ would break instead.)

  parent reply	other threads:[~2023-12-18 14:32 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-18  9:32 [Bug libstdc++/113060] New: " dangelog at gmail dot com
2023-12-18 11:18 ` [Bug libstdc++/113060] " redi at gcc dot gnu.org
2023-12-18 14:32 ` dangelog at gmail dot com [this message]
2024-02-16 14:43 ` redi at gcc dot gnu.org
2024-02-19  8:07 ` de34 at live dot cn
2024-02-19  9:07 ` de34 at live dot cn
2024-02-19  9:11 ` de34 at live dot cn
2024-02-19 23:47 ` dangelog at gmail dot com
2024-02-20  1:47 ` de34 at live dot cn
2024-02-20 10:09 ` dangelog at gmail dot com

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-113060-4-6fd4XvLZVv@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: link
Be 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).