Search code examples
csingly-linked-list

how to fix "invalid use of undefined type" of struct type in C?


Sorry first for my bad English. I'm begginer in C, trying to make a Singly Linked List. This is my setup of the List:

#include <stdio.h>
#include <stdlib.h>
typedef int Element;
struct
{
    Element Data;
    struct Node *Next;
} Node;

typedef struct Node *Position;
typedef Position List;

This is how I initialize this Struct (i dont know if this function is wrong):

void resetList(List *L)
{
    *L = (struct Node *)malloc(sizeof(Node));
};

My problem is, wherever I used the (->), I will got this error

error: invalid use of undefined type ...

the compiler mark the error at any (->) in my code. For example:

int isEmpty(List L)
{
    return (L->Next == 0);
};

will get the error at (->).

I know my code is so dump. Please help me. Thanks.


Solution

  • My problem is, wherever I used the (->), I will got this error

    Your struct needs to be defined as a type and at the same time a self-referencing type, able to point at a variable which is of the same type as itself. In can be done like this:

    typedef struct Node
    {
      Element Data;
      struct Node *Next;
    } Node;
    

    Where the first Node is a struct tag, which is a name allowed to co-exist with the type name Node later defined at the } Node;.


    Hiding pointers behind a typdef like typedef struct Node *Position; is horrible practice, because it achieves nothing except making the code much harder to read for everyone including yourself. There's no need for a typedef at all here, just declare a variable Node* Position.

    Similarly, drop the typedef Position List;, creating new types just for the heck of it only creates clutter.


    This is how I initialize this Struct (i dont know if this function is wrong):

    The reason why you aren't sure, is because of all the obscure typedefs. Consider rewriting the function as:

    void resetList (Node** list)
    {
      *list = malloc(sizeof(Node));
    };
    

    The reason why it has to be a pointer-to-pointer is explained here: Dynamic memory access only works inside function

    As for what this function does, resetList is a very weird name for a function allocating a single node. I would expect it to delete the previous list if present and then maybe allocate a new node.