为什么不能安全地转换指向数字类型的指针?

时间:2017-09-09 19:20:36

标签: c++ c++11 pointers casting

考虑这段代码

T* pa = new T(13);
int address = reinterpret_cast<int>(pa);

其中T可以是任何内置类型。

1)我无法理解重新解释这里的错误是什么?

2)这种铸造会导致不确定的行为的情况是什么?

3)pa是否总是包含内存地址的正确十进制表示?

3 个答案:

答案 0 :(得分:5)

  

我无法理解重新诠释这里的错误是什么?

由于标准不要求int和指针具有相同的大小,因此您可能会通过强制转换丢失信息。

  

这种铸造会导致不确定行为的情况是什么?

如果是这样的话:

1 << (sizeof(T*) * CHAR_BIT) > INT_MAX

然后地址的值可能不会填入int,这会调用未定义的行为。

  

pa是否始终包含内存地址的正确十进制表示形式?

如果你使用std::[u]intptr_t,那么是的,因为这些类型可以保证能够保存指针的值。

答案 1 :(得分:2)

T*int的大小取决于您的编译器和架构。

如果sizeof(T*) > sizeof(int)您将丢弃信息。虽然这可能适用于一个编译器,但架构在另一个编译器上可能不正确。

您可以使用std::intptr_tstd::uintptr_t代替int。这两个保证足够大,可以保存指针的值。

答案 2 :(得分:1)

正如其他答案所指出的,整数的大小和指针的大小不必相同。例如,在许多64位Intel机器上,指针是64位,整数只有32。

但是,还有其他原因可以防止这种情况发生。例如,某些较旧的处理器体系结构具有包含trap representations的整数表示,如果使用这些表示将导致未定义的行为。这意味着原则上指针可以适合整数的大小,但是转换为整数的指针可能会导致陷阱表示导致进一步的数值计算失败。