Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can one volatile constexpr variable initialize another one in C++?

C++ standard allows constexpr volatile variables per defect report 1688, which was resolved in September 2013:

The combination is intentionally permitted and could be used in some circumstances to force constant initialization.

It looks though that the intention was to allow only constinit volatile, which was not available before C++20.

Still the current compilers diverge in treatment of constexpr volatile in certain circumstances. For example, this program initializes one such variable by the other one:

int main() {
    constexpr volatile int i = 0;
    constexpr volatile int j = i;
    return j;
}

It is accepted in GCC and MSVC, but Clang complains:

error: constexpr variable 'j' must be initialized by a constant expression
    constexpr volatile int j = i;
                           ^   ~
note: read of volatile-qualified type 'const volatile int' is not allowed in a constant expression
    constexpr volatile int j = i;

Online demo: https://gcc.godbolt.org/z/43ee65Peq

Which compiler is right here and why?

like image 337
Fedor Avatar asked Sep 08 '25 13:09

Fedor


1 Answers

Clang is correct. The initialization of j from i requires that an lvalue-to-rvalue conversion be performed on i, but according to [expr.const]/5.9, an lvalue-to-rvalue conversion on a volatile glvalue is never permitted inside a constant expression. Since i is a constexpr variable, it must be initialized by a constant expression.

I have no idea why GCC and MSVC choose not to enforce this rule, other than that all C++ compilers are perpetually short-staffed and can't implement everything they're expected to.

like image 82
Brian Bi Avatar answered Sep 10 '25 01:09

Brian Bi