While arguing with someone over the suggestion he made in the comment thread of this answer, I came across some code that gcc4.8 and VS2013 refuse to compile but clang happily accepts it and displays the correct result.
#include <iostream>
int main()
{
int i{ 5 };
void* v = &i;
std::cout << reinterpret_cast<int&>(*v) << std::endl;
}
Live demo. Both GCC and VC fail with the error I was expecting, complaining that the code attempts to dereference a void*
within the reinterpret_cast
. So I decided to look this up in the standard. From N3797, §5.2.10/11 [expr.reinterpret.cast]
A glvalue expression of type
T1
can be cast to the type “reference toT2
” if an expression of type “pointer toT1
” can be explicitly converted to the type “pointer toT2
” using areinterpret_cast
. The result refers to the same object as the source glvalue, but with the specified type. [ Note: That is, for lvalues, a reference castreinterpret_cast<T&>(x)
has the same effect as the conversion*reinterpret_cast<T*>(&x)
with the built-in&
and*
operators (and similarly forreinterpret_cast<T&&>(x)
). —end note ] No temporary is created, no copy is made, and constructors (12.1) or conversion functions (12.3) are not called.
In this case T1
is void
and T2
is int
, and a void*
can be converted to int*
using reinterpret_cast
. So all requirements are met.
According to the note, reinterpret_cast<int&>(*v)
has the same effect as *reinterpret_cast<int*>(&(*v))
, which, by my reckoning, is the same as *reinterpret_cast<int*>(v)
.
So is this a GCC and VC bug, or are clang and I misinterpreting this somehow?