Using a undefined structure is not throwing an error

67 views Asked by At

I have a code snippet like -

typedef struct {
    int data;
    struct abc *nxt;              // Have not defined the structure of name "abc"
} mynode_t;

Here I have not defined a structure of name "abc". Still this code doesn't throw an error and compiles fine. Can anyone help understand how this piece of code is working fine?

Please note: Instead "abc", even if I give some other name like "xyz", it works

2

There are 2 answers

17
ikegami On BEST ANSWER

The C language allows pointers to structures which haven't been defined.

Without this feature, it wouldn't be possible to create constructs like the following:

struct LinkedListNode {
   struct LinkedListNode *nxt;
   void *data;
};

When the compiler encounters struct LinkedListNode *nxt; in the above, struct LinkedListNode hasn't been defined yet since we're in the process of defining it.

Note that code that dereferences nxt or otherwise needs info about the structure will require the structure to be defined.


Incomplete structure pointers are also useful for creating opaque types. For example, a library might present the following interface:

typedef struct LibData *LibHandle;

LibHandle Lib_new( void );
void Lib_delete( LibHandle );
int Lib_do_something( LibHandle, int );

To the user of this library, LibHandle is opaque, meaning it's only useful as a value to pass to the library functions. This allows the library to change the format of LibData over time without causing backwards-compatibility issues.

0
gulpr On

You are not using this structure, you are only declaring the reference (pointer) to it. It is legal, but if you try to dereference it or take sizeof of it will produce the error as this structure declaration is incomplete.

typedef struct {
    int data;
    struct abc *nxt;   //forward declaration of struct abc
} mynode_t;

void foo(void)
{
    mynode_t mn;
    mn.nxt = NULL;  //OK
}

void bar(mynode_t *mn)
{
    mn -> nxt -> something = 5; //wrong
}

void zoo(mynode_t *mn)   
{
    mn -> nxt = malloc(sizeof(*mn -> nxt));  //wrong
}

https://godbolt.org/z/PzebnbP5h

If you want nxt to reference the same struct type you need to use tag

typedef struct abc{
    int data;
    struct abc *nxt;             
} mynode_t;