【发布时间】:2018-08-10 04:15:34
【问题描述】:
我有一些代码(见下文),奇怪的是当我通过 gcc 运行代码时它编译得很好,但是当我在 Visual Studio 2017 中打开相同的文件时,我得到一个编译器错误:
Error C2440 'reinterpret_cast': cannot convert from '::size_t' to 'Alias'
这是一个最小的示例,您可以根据需要尝试。只需点击“新建项目”,然后选择 C++ windows 控制台应用程序,插入此代码,然后尝试在默认的 x86 调试模式下编译:
#include "stdafx.h"
#include <cstddef>
typedef std::size_t Alias;
Alias makeAlias(std::size_t n)
{
return reinterpret_cast<Alias>(n);
}
int main()
{
std::size_t x = 1;
Alias t = makeAlias(x);
return 0;
}
奇怪的是,如果您将 return 语句更改为这个稍微复杂一些的变体,它确实可以编译,所以看起来 Visual Studio 决定只允许 reinterpret_cast 用于指针类型:
return *(reinterpret_cast<Alias*>(&n));
这让我觉得 Visual Studio 做出了一个奇怪的决定,因为根据cpp reference:
与 static_cast 不同,但与 const_cast 类似,reinterpret_cast 表达式不会编译为任何 CPU 指令。它纯粹是一个编译器指令,指示编译器将表达式的位序列(对象表示)视为具有 new_type 类型。
因此,至少在我看来,如果我尝试在以完全相同的方式占用内存的两种类型之间进行reinterpret_cast,那么 reinterpret_cast 确实是需要的。毕竟,顾名思义,我是在将相同的位模式“重新解释”为另一种类型。
我意识到reinterpret_cast 主要针对指针类型之间的转换,但我不明白为什么我应该被禁止在这种情况下使用它。在某种“为正确的工作使用正确的工具”的意义上,允许程序员将reinterpret_cast 用于其预期目的不是更有意义,而不是在不需要时强迫他们使用static_cast(更不用说在这个过程中不必要地消耗几个时钟周期了)?
在别名类型之间允许reinterpret_cast 是否存在某种危险,这会导致 Visual Studio 不允许这样做? Reinterpret_cast 使用不当肯定会很危险,但我不明白为什么如果使用得当它会失败(当然,在这种情况下,我在“正确”使用的定义中遗漏了一些东西)。
【问题讨论】:
-
感谢您的建议,我已继续编辑问题
-
您遗漏了错误消息的第二半部分:“注意:转换是有效的标准转换,可以隐式执行,也可以使用 static_cast、C 样式转换或函数样式转换” .
-
FWIW 这与决策、CPU 指令或占用内存无关。这是关于错误和语义(或缺乏)
-
顺便说一句,编辑后的 MCVE 非常好 - 您可以继续删除旧版本,因为它只是妨碍了它
-
太好了,那就更好了。总的来说,这个问题和后续工作做得很好(遗憾的是,对于低代表用户来说非常罕见)。你会在这里走得很远:)
标签: c++ visual-studio alias reinterpret-cast