use*_*702 26 c++ gcc clang language-lawyer c++11
以下代码段在Clang 3.5中正常工作,但在GCC 4.9.2中没有:
int main()
{
constexpr volatile int i = 5;
}
Run Code Online (Sandbox Code Playgroud)
有错误:
错误:这里不能使用'volatile'和'constexpr'
如果我检查Clang生成的程序集,它会5
按预期显示:
movl $5, -4(%rsp)
Run Code Online (Sandbox Code Playgroud)
在GCC中,constexpr int i = 5
被优化掉了,但volatile int i = 5
也在5
装配中显示出来.volatile const int i = 5
在两个编译器中编译.对于同时具有易失性和常量的东西而言,这不是一个外国概念.
哪个编译器的标准是正确的?
Sha*_*our 24
是的,这是有效的,有缺陷报告1688:为此提交的挥发性constexpr变量,说:
目前的措辞中似乎没有语言表明constexpr不能应用于volatile限定类型的变量.另外,5.19 [expr.const]第2段中的措辞提到"用constexpr定义的非易失性对象"可能导致人们推断该组合是允许的,但这样的变量不能出现在常量表达式中.意图是什么?
它被拒绝为非缺陷(NAD),回应和理由是:
有意允许组合,并且可以在某些情况下使用该组合来强制不断初始化.
正如DR指出的那样,这样的变量本身不能用于常量表达式:
constexpr volatile int i = 5;
constexpr int y = i ; // Not valid since i is volatile
Run Code Online (Sandbox Code Playgroud)
Section [expr.const]/2包括使条件表达式不是核心常量表达式的所有情况,包括:
除非适用,否则左值到右值的转换(4.1)
并且所有例外都需要:
[...]指的是非挥发性物品[...]
Cas*_*sey 17
引用N4140 [dcl.constexpr]/9:
constexpr
对象声明中使用的说明符将对象声明为const
.这样的对象应具有文字类型并应初始化.
文字类型在[basic.types]/10中定义:
类型是文字类型,如果它是:
(10.1) -
void
; 要么(10.2) - 标量类型; 要么
(10.3) - 参考类型; 要么
(10.4) - 一个文字类型的数组; 要么
(10.5) - 具有以下所有属性的类类型(第9节):
(10.5.1) - 它有一个简单的析构函数,
(10.5.2) - 它是一个聚合类型(8.5.1)或者至少有一个
constexpr
构造函数或构造函数模板不是复制或移动构造函数,并且(10.5.3) - 它的所有非静态数据成员和基类都是非易失性文字类型.
标量类型在第9段中:
算术类型(3.9.1),枚举类型,指针类型,指向成员类型的指针(3.9.2)
std::nullptr_t
和这些类型的cv限定版本(3.9.3)统称为标量类型.
int
是算术,因此volatile int
是标量类型,因此是文字类型.constexpr volatile int i = 5;
因此是一个结构良好的宣言.
有趣的是,求值的表达式i
不能是核心常量表达式,因为它将左值到右值的转换应用于volatile类型的glvalue([expr.const]/2).因此,求值的表达式i
既不是整型常量表达式也不是常量表达式.我不确定该constexpr
声明中的内容是否有任何影响,除了i
隐式地const
,并且(向@TC点头)要求其初始化器是一个常量表达式.
我已将此报告为GCC错误65327,我们将看到GCC人员所说的话.
2015-03-16更新:已针对GCC 5修复了错误.
归档时间: |
|
查看次数: |
1531 次 |
最近记录: |