Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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).

like image 771
Scorch Avatar asked Mar 02 '18 00:03

Scorch


People also ask

What does Reinterpret_cast mean?

reinterpret_cast is a type of casting operator used in C++. It is used to convert a pointer of some data type into a pointer of another data type, even if the data types before and after conversion are different. It does not check if the pointer type and data pointed by the pointer is same or not.

Is Reinterpret_cast safe?

The reinterpret_cast operator can be used for conversions such as char* to int* , or One_class* to Unrelated_class* , which are inherently unsafe. The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type.


1 Answers

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

like image 133
Lightness Races in Orbit Avatar answered Sep 21 '22 09:09

Lightness Races in Orbit