Linked lists are a particuarly poor example though. It is just as easy to make them without null pointers as with null pointers:
struct list_node {
list_node *next;
};
struct list {
list_node sentinel;
};
IE. A circular linked list. In C++ speak, begin() is sentinel.next, end() is sentinel. In an empty list, sentinel.next points to &sentinel.
It might seem more clumsy, but it isn't really any more work. When you actually do need the equivalent of a null pointer you can use an option type to specify that you either want nothing or a valid pointer.
struct list_node { list_node *next; };
struct list { list_node sentinel; };
IE. A circular linked list. In C++ speak, begin() is sentinel.next, end() is sentinel. In an empty list, sentinel.next points to &sentinel.
It might seem more clumsy, but it isn't really any more work. When you actually do need the equivalent of a null pointer you can use an option type to specify that you either want nothing or a valid pointer.