Fed*_*dor 27 c++ volatile language-lawyer constexpr
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;
}
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
Online demo: https://gcc.godbolt.org/z/43ee65Peq
Which compiler is right here and why?
Bri*_*ian 17
叮当是正确的。j
from的初始化i
要求对 执行左值到右值的转换i
,但根据 [expr.const]/5.9,在volatile
常量表达式内决不允许对左值到右值的转换。由于i
是一个constexpr
变量,因此必须用常量表达式对其进行初始化。
我不知道为什么 GCC 和 MSVC 选择不强制执行这条规则,除了所有 C++ 编译器永远人手不足,无法实现他们期望的一切。
小智 12
您链接的缺陷报告显示它不应该工作,所以 Clang 是正确的。
\n\n\n(...) \xe2\x80\x9ca 允许使用 constexpr\xe2\x80\x9d (...) 定义的非易失性对象,但此类变量不能出现在常量表达式中。意图是什么?
\n
但更有趣的是:为什么 Clang 关心而其他编译器不关心?
\n在我看来,发生这种情况是因为JF Bastien,一个在 Clang / LLVM 领域非常有影响力的人物,他个人不喜欢volatile
:)
长期以来,他一直建议将其从语言中删除。所以如果允许在某个地方禁止 volatility,他可能会不遗余力地做到这一点。如果没有其他原因,只是为了阻止人们编写如果他的提案最终被接受就必须重写的代码。
\n如果您想了解他的理由,他还在 CppCon 上发表了关于他的弃用提案的演讲。
\n 归档时间: |
|
查看次数: |
1520 次 |
最近记录: |