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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With