为什么这是一个错误:static_cast <unsigned *>(&amp; i)

时间:2016-05-12 12:34:56

标签: c++ casting

按照经验法则首先选择static_castdynamic_cast,我写了以下程序:

int main(void)
{
    int i = 0;
    unsigned *j = static_cast<unsigned*>(&i);
    return 0;
}

但是,它甚至没有编译:

$ g++ --std=c++11 test5.cpp 
test5.cpp: In function ‘int main()’:
test5.cpp:4:44: error: invalid static_cast from type ‘int*’ to type ‘unsigned int*’
     unsigned *j = static_cast<unsigned*>(&i);
                                            ^

为什么这是错的?这种情况的正确演员是什么?

2 个答案:

答案 0 :(得分:7)

您可static_castintunsigned执行适当的转化。但你拥有的是一个指针;此指针指向要解释为int的内存区域。取消引用指针会产生int的值。 static_cast will not convert between pointers to unrelated types

int i = 0;
int* ip = &i;
int j = *ip; // treat the region pointed to as an int

要在取消引用下将内存视为unsigned,您需要重新解释内存;这是reinterpret_cast的作用。

int i = 0;
int* ip = &i;
unsigned j = *reinterpret_cast<unsigned*>(ip); // treat the region pointed to as unsigned
但是,你不应该这样做。 reinterpret_cast完全按照它所说的做法:将内存重新解释为不同的类型。如果位模式与该类型的预期不匹配,则结果将与static_cast<unsigned>执行的转换不同。例如,在没有使用2的补码表示有符号整数的系统中就是这种情况。

正确的方法是取消引用int*然后static_cast<unsigned>的结果:

int i = 0;
int* ip = &i;
unsigned j = static_cast<unsigned>(*ip); // treat the region pointed to as int
                                         // then convert the int to unsigned

总结一下:static_cast将执行整数转换,但不会将内存区域重新解释为不同的类型。这是reinterpret_cast的用途。

答案 1 :(得分:2)

你必须使用:

unsigned *j = static_cast<unsigned*>(static_cast<void*>(&i));

这是您在第5点阅读here的内容,或只是使用:reinterpret_cast

int i = 0;
unsigned *j = reinterpret_cast<unsigned*>(&i);

经常使用cast-s程序员而不是如下所示使用联合:

union {
  int n;
  unsigned char bt[4];
} data;
data.n = i;
data.bt[3] = 0xff;

正如在评论中所说,使用union进行强制转换是未定义的行为 - 即使大多数编译器都支持它:您可以在此处阅读更多内容:Is using an union in place of a cast well defined?Is using an union in place of a cast well defined?