You can do this easily in the global scope:
// nil = &nilObj, which means nil->next == nil.
//
// This way, there's no checking for both 'nil' and 'NULL'!
//
// As a consequence of this last point, you can make passing 'NULL'
// to most list functions invalid: it just means the user didn't
// use mklist() on every list they needed to manually work with.
static struct node nilObj = { 0, "null", "null", &nilObj };
node nil = &nilObj;
void mklist(node *n)
{
*n = nil;
}
As Stephen Docy mentioned, using typedef T *Tname;
is generally a bad idea as it hides the fact that you're using a pointer, which can be confusing when you use Tname *n
as (*n)->foo
(I'd expect to use it as n->foo
honestly). Some APIs do this, but they do it in a way that expresses that the variable is a pointer to an object rather than an object: instead of Node
, something like NodeRef
or NodePtr
is used, signifying in the name that it's a pointer to a node, not a node. Apple's Core Foundation API uses names like this (e.g. CFStringRef
). I highly suggest adopting a convention similar to this henceforth. The above code I posted might then look something like this:
static struct node nilObj = { 0, "null", "null", &nilObj };
nodeRef nil = &nilObj;
void mklist(nodeRef *n)
{
*n = nil;
}