std::optional assignment operator in a constexpr context
Asked Answered
C

1

9

I am scratching my head on std::optional which, according to the docs, shouldn't have a constexpr assignment operator.

However, when I try this snippet in gcc-8.1, it compiles and works just fine:

constexpr std::optional<int> foo() {
    std::optional<int> bar = 3;
    bar = 1337;
    return bar;
}

constexpr auto z = foo();

Is there something I am missing?

Chlorous answered 19/8, 2018 at 19:9 Comment(5)
Does constexpr auto z = foo() compile also?Armin
@Evgeny Yes, it does, it worked in a more complex context...Chlorous
@Evgeny Yes, live: godbolt.org/z/Y11f6kDetermine
See P0602. It‘s not applied to the standard yet, but when it's applied, it will make the assignment constexpr. (And it's expected to apply retroactively to C++17.)Gereld
@Gereld Ah, that explains a lot! Please, post it as an answer, I will accept it as that's the correct one.Chlorous
C
5

It seems like this is a bug in gcc. I just tried in clang-6.0 and the compilation fails with the expected error. Also, the standard doesn't mention any constexpr overload for the assignment operator, thus I'll report this bug to gcc bugtracker.

Link to the bug report


Edit:

It turned out that this is not a bug in gcc, but a mistake in the standard:

I don't understand how the code snippet can work in a constexpr context when the current c++17 standard doesn't specify any constexpr assignment operator.

That's true, but the standard is broken.

All implementations define the assignment operator as defaulted, and so the compiler makes it constexpr.

In fact the P0602R3 proposal is relevant, because it would require implementations to define the operator as defaulted (in order to be trivial) and so the compiler is always going to make it constexpr for std::optional.

I've raised this with the standards committee.

You can read more about it in the bug report.

Chlorous answered 19/8, 2018 at 19:31 Comment(8)
no, it doesn't fail with clang-6.0 either: wandbox.org/permlink/o7gn4bGMdazVGqUBDoig
neither does VS2017Doig
@AndriyTylychko That's even weirder because here it fails: gcc.godbolt.org/z/2u3u3MChlorous
I checked <optional> in VS and yes operator= is not constexpr, so my guess is that it's not involved at all. Can it be that it's optimised out?Doig
@AndriyTylychko I'm not sure, I've tried compiling with -std=c++17 -Wall -Wextra -pedantic -O0 -g -fno-elide-constructors and the compilation was still successful.Chlorous
interesting. and we have another mystery - why wandbox and godbolt show different results both claiming to use clang-6.0. unfortunately I don't have clang locally to check who's rightDoig
@AndriyTylychko I am wondering about the same... I just tried compiling it with clang-6.0.1 on my laptop (Linux laptop 4.17.11-arch1 x86_64) and it compiles, too. This is really bugging me.Chlorous
I posted the bug report, we will see what the developers will say about it.Chlorous

© 2022 - 2024 — McMap. All rights reserved.