reinterpret_cast - 奇怪的行为

reinterpret_cast - bizarre behaviour

本文关键字:cast reinterpret      更新时间:2023-10-16

我遇到了与reinterpret_cast有关的奇怪错误。只需查看下面的代码:

int* var;
reinterpret_cast<void const **>(&var);

VSC++2010 中的错误:错误 C2440:"reinterpret_cast":无法从"int **"转换为"const void **

"

GCC 4.1.2 中的错误:从类型"int**"reinterpret_cast为"const void**"类型会丢弃恒常性

GCC 4.6.2 中的错误:从类型"int**"reinterpret_cast为"const void**"会丢弃限定符

有没有人知道为什么编译器说我正在抛弃 const。我和我的几个同事都不知道它出了什么问题。

感谢您的帮助!

C++03 标准的第 5.2.10 节讨论了reinterpret_cast可以做什么。 它明确指出"reinterpret_cast操作者不得抛弃恒定性"。

抛弃恒常性在 C++03 标准的第 5.2.11 节中定义。 那里使用的符号有点令人困惑,但它基本上指出,如果给定限定没有隐式转换,则在两种类型之间进行转换会"抛弃恒定性"。

在您的情况下,您正在尝试将int **转换为void const**。 编译器问"我可以在T **T const**之间隐式转换吗?",答案是否定的,所以它说你正在抛弃恒常性。

这里的逻辑是,reinterpret_cast是为了处理不断变化的类型,而不是改变限定符(这就是const_cast的目的)。 因此,如果你要求它做一些你需要const_cast的事情,它会拒绝。

要添加/删除const,请使用const_cast

要处理令人困惑的转换错误,请一步一步地做一些事情:

int* var;
int** v2 = &var;
int const** v3 = const_cast<int const**>(v2);
void const** v4 = reinterpret_cast<void const**>(v3);

请注意,int const**int**是非常不同的类型,在它们之间进行转换是危险的——比void* <> int*更危险。

假设您有一个int** bob. 然后,将其传递给一个函数,该函数通过const_cast进行int const** alice

在该函数中,他们将一个指针分配给存储在只读存储器中的 int 到*alice - 完全合法。

在函数外部,您检查bob*bob是否有效,然后分配给**bob,并且您刚刚尝试写入只读内存。