Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reinterpret_cast behavior when dereferencing a void pointer

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 to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. The result refers to the same object as the source glvalue, but with the specified type. [ Note: That is, for lvalues, a reference cast reinterpret_cast<T&>(x) has the same effect as the conversion *reinterpret_cast<T*>(&x) with the built-in & and * operators (and similarly for reinterpret_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?

like image 210
Praetorian Avatar asked Mar 12 '26 22:03

Praetorian


1 Answers

An expression of type void is allowed as a mostly just syntactical device in a return statement, and also you can cast an expression to void, but that's all: there are no glvalues of type void, an expression of type void does not refer to memory. Thus the quoted passage from the standard, starting with a glvalue, does not apply. Thus, clang is wrong.

like image 90
Cheers and hth. - Alf Avatar answered Mar 14 '26 10:03

Cheers and hth. - Alf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!