Background
I have created a basic linked list data structure mainly for learning purposes. One goal of the list was that it can handle different data structures. Therefore, I've tried my hand at structure composition to simulate "inheritance" in C. Here are the structures that form the basis for my linked list.
typedef struct Link {
struct Link* next;
struct Link* prev;
} Link;
typedef Link List;
In my implementation I have chosen to have a sentinel node that serves as both the head and the tail of the list (which is why Link == List).
To make the list actually handle data, a structure simply includes the Link structure as the first member:
typedef struct {
Link link;
float data;
} Node;
So the linked list looks like this.
┌───┬───┬───┐ ┌───┬───┐ ┌───┬───┬───┐
... <--->│ P │ N │ D │<--->│ P │ N │<--->│ P │ N │ D │<---> ...
└───┴───┴───┘ └───┴───┘ └───┴───┴───┘
End Node myList First Node
List myList;
Node node1 = {{}, 1.024};
....
Node nodeN = {{}, 3.14};
list_init(&myList) // myList.next = &myList; myList.prev = &myList;
list_append(&myList, &node1);
....
list_append(&myList, &nodeN);
Question
To traverse this list a Node
pointer initially points to the First Node. It then traverses along the list until it points to the sentinel again then stops.
void traverse()
{
Node* ptr;
for(ptr = myList.next; ptr != &myList; ptr = ptr->link.next)
{
printf("%f ", ptr->data);
}
}
My question is with the line ptr != &myList
. Is there a pointer alignment problem with this line?
The for loop correctly produces the warnings: (warning: assignment from incompatible pointer type
and warning: comparison of distinct pointer types lacks a cast
) which can be silenced by doing what it says and casting to Node*
. However, is this a DumbThingToDo™? I am never accessing ptr->data
when it points to &myList
as the loop terminates once ptr == &myList
.
TLDR
In C structs, a Base*
can point to a Derived
if Base
is the first member in Derived
. Can a Derived*
point to a Base
if none of Derived
specific members are accessed?
EDIT: replaced relevant function calls with their equivalent inline code.