4
  1. I have a struct called Node whose first member is Node* p_next
  2. I have a pointer to the first node called p_head
  3. I want to cast &p_head which is of type Node** to a Node*, and store it in p_node_before_head. This is so I can treat *p_node_before_head as if it were a node where the value of p_node_before_head->p_next is the value of p_head
#include <iostream>

struct Node{
    Node* p_next;
    int item;   
};

int main(){
    Node head = {nullptr, 5};
    Node* p_head = &head;
    
    //By pretending that "p_head" is a node whose first element is a pointer to the head,
    //we create a new pointer that points to this "node before the head"
    Node* p_node_before_head = reinterpret_cast<Node*>(&p_head);
    
    Node* p_head2 = p_node_before_head->p_next;
    std::cout << p_head2->item << std::endl;
}

Is this reinterpret cast undefined behaviour? I am bit confused on how to determine whether casting a pointer of one type to a pointer of another type follows pointer-interconvertibility.

2
  • 2
    Casting between pointer types is usually/always legal. It's using the pointer after the cast that is the problem. In this case is &p_head a Node** the same type as Node*? No it's not so dereferencing p_node_before_head is UB and breaks strict-aliasing rules. See Type aliasing for more details. Commented Oct 27, 2024 at 17:46
  • Whenever you have to reach for reinterpret_cast (or C-style casts) you should take that as an indication that you are probably doing something wrong. In most cases, all reinterpret_cast allows you to do is later cast back to the original type and then use that. Commented Oct 27, 2024 at 17:50

1 Answer 1

5

No that's undefined behavior. You can never pretend that an object of some type exists at some address where you never explicitly (or implicitly) created an object of such a type.

At the address &p_head there is a Node* object, but no Node object. Therefore the result of the reinterpret_cast can't point to any Node object and consequently the member access p_node_before_head->p_next has undefined behavior.

Pointer-interconvertibility doesn't even matter, because to begin with there is no Node object at the address in question. So there surely can't exist any Node object that is pointer-interconvertible with the Node* object either.

In fact it is fundamentally impossible for a Node object to exist at the address in question, because the width of the storage at that address is too small for a Node object.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.