为什么这个 reinterpret_cast 在 Visual Studio 中失败了?

Why this reinterpret_cast fails in Visual Studio?

我有一些代码(见下文),奇怪的是,当我通过 gcc 运行 代码时它编译得很好,但是当我在 Visual Studio 2017 年打开同一个文件时,我得到一个编译器错误为:

Error   C2440   'reinterpret_cast': cannot convert from '::size_t' to 'Alias'

这是一个最小的示例,如果您愿意,可以尝试一下。只需点击 "new project" 和 select 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

Unlike static_cast, but like const_cast, the reinterpret_cast expression does not compile to any CPU instructions. It is purely a compiler directive which instructs the compiler to treat the sequence of bits (object representation) of expression as if it had the type new_type.

因此,至少在我看来,如果我尝试在以完全相同的方式占用内存的两种类型之间进行 reinterpret_cast,那么 reinterpret_cast 才是真正需要的。毕竟我是,顾名思义,"reinterpreting"同位模式到另一种类型。

我知道 reinterpret_cast 主要针对指针类型之间的转换,但我不明白为什么我应该被禁止在这种情况下使用它。在某种 "use the right tool for the right job" 意义上,允许程序员将 reinterpret_cast 用于其预期目的,而不是强迫他们在不必要时使用 static_cast 不是更有意义吗(不是更何况在这个过程中不必要地消耗了几个时钟周期)?

在别名类型之间允许 reinterpret_cast 是否存在某种危险,会导致 Visual Studio 不允许这样做? Reinterpret_cast 如果使用不当肯定会很危险,但我不明白为什么如果使用得当它会失败(当然除非我在 "proper" use 的定义中遗漏了一些东西在这种情况下).

[C++14: 5.2.10/2]: The reinterpret_cast operator shall not cast away constness (5.2.11). An expression of integral, enumeration, pointer, or pointer-to-member type can be explicitly converted to its own type; such a cast yields the value of its operand.

因为std::size_t是整型,而Aliasstd::size_t,我想说这是一个有趣的Visual Studio 错误。