C++ Logo


Advanced search

Re: Why is this code accepted by all compilers?

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Fri, 12 Nov 2021 16:07:01 +0100
On 12/11/2021 15.52, Jason McKesson via Std-Discussion wrote:
> On Fri, Nov 12, 2021 at 3:26 AM Jens Maurer via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
>> On 12/11/2021 04.04, Hani Deek via Std-Discussion wrote:
>>> The following code is accepted by GCC, Clang and MSVC. I thought it was ill-formed because the variable V0 is not usable in constant expressions. Is this just a bug in all of those compilers? Or is there an explanation in the C++ rules?
>>> struct S{ constexpr operator int() const{ return 0; } };
>>> void foo(S V0) { constexpr int V1 = V0; }
>>> int main()
>>> {
>>> S V0{};
>>> foo(V0);
>>> }
>> There is no lvalue-to-rvalue conversion on any part of V0.
>> Do you feel any other provision in [expr.const] p5 should
>> apply, making this not a constant expression?
> I got a bit lost in the details, but my confusion comes from the use
> of the name `V0`. C++20 says:
>> An object or reference is usable in constant expressions if it is:
>> * a variable that is usable in constant expressions, or ...
> And:
>> A constant-initialized potentially-constant variable is usable in constant expressions ...
> This means that the only variables that are "usable in constant
> expressions" are those which are constant-initialized and potentially
> constant. Neither is true of `V0`.

Right, but "usable in constant expressions" is just a technical
helper tool for determining whether some expression is a valid
constant expression. You should not read any English meaning
into that phrase; it's just a macro for formally defining
"constant expression".

> Are you suggesting that the use of the name `V0` does not trigger one
> of the conditions in [expr.const]/5 because it never triggers
> lvalue-to-rvalue conversion? If this is true, can you explain why it
> does not?

[expr.const] p5 defines whether some expression is a constant
expression or not. There are many situations (lots of bullets)
that make an expression not a constant expression, and you need
to check all of them.

A few of the bullets are concerned with lvalue-to-rvalue conversions,
but those bullets can be disregarded right away because your example
does not perform any lvalue-to-rvalue conversion at all.

I'm not seeing any of the other bullets match your example,
so you've successfully built a constant expression. Hooray.


Received on 2021-11-12 09:07:07