2

I keep getting a compiler issue when trying to use a struct I defined in a header file.

I have two files: main.c:

     #include <stdio.h>
     #include <stdlib.h>
     #include "node.h"

     int main(){
         struct NODE node;
         node.data = 5;
         printf("%d\n", node.data);
         return 0;
     }

as well as node.h:

#ifndef NODE
#define NODE
    struct NODE{
        int data;
        struct NODE *next;
    };

#endif

I was writing a small program to practice some modular programming in C, but I've been getting the following compiler error:

node.h:5:21: error: expected ‘{’ before ‘*’ token
         struct NODE *next;
                     ^

I got the main.c to compile and do what I would like it to do when I define the struct directly in the file main.c, but for some reason it won't work if I place the definition in a header file and then try to include it in main.c. It's very frustrating, and I'm sure it's a minor thing, but could someone please tell me why this isn't working? From what I've been reading, I should be able to do this, no?

Thanks a lot!

6
  • 3
    Change your include guard to something like NODE_H_. Commented Apr 28, 2019 at 19:55
  • @StoryTeller why should changing the name in the include guard help this code compile? Commented Apr 28, 2019 at 19:56
  • 3
    Because #define NODE means "replace any occurrence of the tokenNODE by nothing". For a header file header.h, normal conventions for the header guard include HEADER_H or HEADER_H_INCLUDED — and you'll see system headers using leading underscores, but they're required to do that and you're required NOT to do that. Commented Apr 28, 2019 at 19:57
  • 2
    Because your struct has the same name as the your include guard #define, so the preprocessor is expanding it into an empty string. Commented Apr 28, 2019 at 19:57
  • 2
    Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of C11 §7.1.3 Reserved identifiers says: — All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. See also What does double underscore (__const) mean in C? Commented Apr 28, 2019 at 20:01

2 Answers 2

6

The preprocessor is expanding NODE to nothing because you've defined it with a macro. Change your header file to look like this:

#ifndef NODE_H
#define NODE_H
    struct NODE{
        int data;
        struct NODE *next;
    };

#endif
Sign up to request clarification or add additional context in comments.

Comments

3

You defined a macro NODE as nothing. From that point on, every NODE in your source code is replaced with nothing. So your header file is actually:

struct{
    int data;
    struct *next;
};

That should answer your question why changing the include guard from NODE to NODE_H fixes it.

1 Comment

OOOOOOOOOH I see now. It was a name collision! works now, thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.