I have this piece of C++ code:
int main() {
int* ptr = nullptr;
int& ref = reinterpret_cast<int&>(ptr);
return ref;
}
While compiling with -Wall -Wextra -pedantic
on both compilers, neither Clang nor GCC diagnose the cast, and only GCC diagnoses that I dereference a null pointer.
Is the cast from ptr
to ref
undefined behaviour? Or is only the read from ref
in the return statement UB?
only GCC diagnoses that I dereference a null pointer.
That is not the warning I get when compiling your code. Instead I get
warning: casting 'int*' to 'int&' does not dereference pointer
This is a warning that there is no dereference, from a null pointer or otherwise.
Is the cast from
ptr
toref
undefined behaviour?
The cast is perfectly valid by itself. This falls under point 6 of cppreference.com's documenation. A glvalue of type int*
can be converted to a reference to another type, in this case int
. The result is that of *reinterpret_cast<int*>(&ptr)
. That is, this cast causes ref
to refer to the value of ptr
, not (as you seem to think) to what that value points to.
If it was safe to access the reference, ref
would start with the value zero (assuming the common case where a null pointer has all zero bits). If a new pointer was assigned to ptr
, then the value of ref
would also change, still assuming access was safe.
Or is only the read from
ref
in the return statement UB?
An int
is not allowed to alias a int*
, so, yes, accessing the reference in the return
statement yields undefined behavior. The same would be true if ptr
had been initialized with int* ptr = new int;
– whether or not the pointer is null has no bearing.