Search code examples
c++visual-studioaliasreinterpret-cast

Why this reinterpret_cast fails in Visual Studio?


I have some code(see below), and curiously it compiles fine when I run the code through gcc, but when I open up the same file in Visual Studio 2017, I get a compiler error to the tune of:

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

Here's a minimal example that you can try if you want. Just hit "new project", and select the C++ windows console application, insert this code, and try to compile in the default x86-debug mode:

#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;
}

Oddly enough if you change the return statement to this slightly more convoluted variant, it indeed compiles, so it seems like Visual Studio decided to allow reinterpret_cast only for pointer types:

return *(reinterpret_cast<Alias*>(&n));

This strikes me as a strange decision by Visual Studio, because, according to 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.

So it would seem, at least to me, that if I attempt to reinterpret_cast between two types that occupy memory in the exact same way, then reinterpret_cast is really what is called for. After all, I am, as the name suggests, "reinterpreting" the same bit pattern to another type.

I realize that reinterpret_cast is mainly targeted toward converting between pointer types, but I don't see why I should be barred from using it in situations like this. In a sort of "use the right tool for the right job" sense, wouldn't it make more sense to allow programmers to use reinterpret_cast for its intended purpose, rather than forcing them to use static_cast when that's not necessary (not to mention needlessly burning a few clock cycles in the process)?

Is there some sort of danger in allowing reinterpret_cast between aliased types that would cause Visual Studio to disallow this? Reinterpret_cast can definitely be dangerous when used incorrectly, but I can't see why it would have to fail if used properly (unless of course I'm missing something in the definition of "proper" use in this case).


Solution

  • [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.

    Since std::size_t is an integral type, and Alias is std::size_t, I'd say that this is an amusing Visual Studio bug.