【发布时间】:2015-08-07 16:13:59
【问题描述】:
删除注释标记后,以下代码在 MSVC2015 和 clang 中均无法编译,但可以按原样编译。
int main()
{
static_assert( alignof( int * ) == alignof( int * * ), "nope" );
const int * * a = nullptr;
//const int * * * b = reinterpret_cast< const int * * * >( a );
auto c = static_cast< const int * * * >( static_cast< void * >( a ) );
return 0;
}
这个问题与previously asked one 不同,因为没有整体const 限定符被抛弃。
根据标准[expr.reinterpret.cast]/7
对象指针可以显式转换为不同类型的对象指针。当对象指针类型的prvalue
v转换为对象指针类型“pointer tocv T”时,结果为static_cast<cv T*>(static_cast<cv void*>(v))。
在这种情况下,目标“指向cv T”的指针是const int * * *,这使得T = const int * * 没有cv 限定符。因此,结果应该是static_cast<T*>(static_cast<void*>(v))。
T 的对齐存在一些限制,但与静态断言中所示的此处无关。由于reinterpret_cast< const int * * * >( a ) 的结果实际上可以使用中间步骤计算,因此如果未注释,注释代码应该可以编译。
我的推理错误在哪里(如果有的话)?
【问题讨论】:
-
根据 [expr.const.cast]p8,通过 [expr.reinterpret.cast]p2 禁止这样做。
-
@dyp:我读到 [expr.const.cast]p8 “有条件地支持将函数指针转换为对象指针类型或反之亦然。”,但我认为它不应该在这里应用,因为不涉及函数指针。
-
您引用的是 [expr.reinterpret.cast]p8。我指的是 [expr.const.cast]p8 和 [expr.reinterpret.cast]p2。
-
是的,我看错了你的评论 ;-)
标签: c++ c++11 language-lawyer c++14