限定符丢失转换C ++

时间:2015-08-07 16:14:00

标签: c++ c++11 language-lawyer c++14

以下代码无法在删除注释标记时在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转换为对象指针类型“指向cv 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 )的结果实际上可以使用中间步骤计算,因此注释后的代码应该在未注释的情况下进行编译。

我的推理错误在哪里(如果有的话)?

1 个答案:

答案 0 :(得分:2)

N3690 5.2.11 / 8:

  

以下规则定义了称为 cast away constness 的过程。在这些规则中,TnXn代表类型。对于两种指针类型:

     

X1T1 cv 1,1 * ... cv 1, N *其中T1不是指针类型

     

X2T2 cv 2,1 * ... cv 2, M *其中T2不是指针类型

     

K 是min( N M

     

X1转换为X2会抛弃constness,如果对于非指针类型T,则不存在隐式转换(第4条):

     

T cv 1,( N - K +1) {{1} } cv 1,( N - K +2) * ... cv 1, N *

     

     

* cv 2,( M - K +1) {{1} } cv 2,( M - K +2) T ... cv 2, M *

在您的示例中,**,因此 N 为2,X1const int** cv 1,1 T1 cv 1,2 为空。 intconst,因此 M 为3,X2const int*** cv 2,1 T2 cv 2,2 cv 2,3 是空。 K 是2.是否存在来自

的隐式转换

int cv 1,1 const cv 1,2 { {1}} = T

* cv 2,2 * cv 2,3 { {1}} = T const**

没有;所以你的演员会抛弃常数。

当然我们有5.2.10 / 2:

  

T运算符不得抛弃constness(5.2.11)。