1

As a simple beginner project, I am trying to build a linked list. I have created a structure typedef for the node. My issue is that I want another typedef as a pointer to a list node, for some reason, this is not working and I am very confused. I have read other answers on here and none of them have worked.

main.c

#include <stdio.h>
#include "linkedList.h"


int main(int argc, char **argv){
    return 0;
}

linkedList.h

#ifndef linkedList
#define linkedList

typedef struct listStrNode {
    char *string;
    struct listStrNode *next;
} listStringNode;

typedef listStringNode *linkedList;

#endif

error

In file included from main.c:3:
linkedList.h:9:35: error: expected identifier or ‘(’ before ‘;’ token
    9 | typedef listStringNode *linkedList;
      |

compiled with:

gcc main.c

any ideas?

  • 4
    I would recommend to a beginner to forget ever having heard of `typedef`. It is strictly a convenience feature, but it is sometimes confusing, and some people consider most uses of it to be poor style. *Especially* do not hide pointer nature behind a `typedef`, unless you are intentionally trying to be obscure. – John Bollinger Jul 18 '21 at 01:10
  • 1
    I would refine @JohnBollinger's comment to the effect that using a typedef to alias a pointer to a type is rude. Using typedefs to save on typing, such as the `listStringNode` type, is fine. Creating aliases for types, is rarely ever required, but a type def that saves you from typing `struct Something` instead of `TSomething` is good form, if the struct definition is intended for reuse, if not, don't bother. I know you'll find lots of examples in the world, where the gods of kernel programming have liberally applied type aliases for pointers to type in the past, but it's generally frowned on. – jwdonahue Jul 18 '21 at 02:30
  • To be clear, my position is that using a typedef to save typing, as in to omit `struct` or `union` keywords, is *not* fine. I consider it a poor style choice. I acknowledge, however, that this is a controversial position. – John Bollinger Jul 18 '21 at 13:01
  • 2
    But I want to be sure that a more essential point is not overlooked: code style considerations notwithstanding, a beginning C programmer would be better off staying well clear of `typedef`. Having learned that it exists, they should file that information away in the back of their minds for further consideration at some later date when they are comfortable with (the rest of) the language. – John Bollinger Jul 18 '21 at 13:04
  • I am used to programming in java so I am somewhat trying to handle the linkedList typedef as an abstraction to the data structure – Gabe Koleszar Jul 18 '21 at 21:01

2 Answers2

5
#define linkedList

That will replace all instances of linkedList with an empty string. Which effectively means typedef listStringNode *linkedList; becomes typedef listStringNode *; and hence the error. To fix, rename either the #define or the type name. A common convention is to use a representation of the filename as the include guard: e.g. #define LINKEDLIST_H

kaylum
  • 13,833
  • 2
  • 22
  • 31
  • [Note: leading underscores.](https://stackoverflow.com/a/1449301/2505965) – Oka Jul 18 '21 at 01:25
  • No, the `linkedList` will not be replaced with empty string. Try this - `printf ("%s", linkedList)` to verify your statement. The replacement is empty and not empty string. – H.S. Jul 18 '21 at 06:00
  • thanks so much, I only did the include guard thinking it was a good practice and didn't really understand it. Goes to show I should understand features before I use them. – Gabe Koleszar Jul 18 '21 at 20:58
0

In your code (linkedList.h file), you have this macro definition

#define linkedList

which, after preprocessing stage, will result in empty replacement of macro linkedList.

gcc compiler has an option -E which give output in the form of preprocessed source code (basically it stop after the preprocessing stage). When compiling your code with -E option, gives following output:

# gcc -E main.c


..... //showing only relevant part
.....

typedef struct listStrNode {
    char *string;
    struct listStrNode *next;
} listStringNode;

typedef listStringNode *;
                       ^^^
                        |
                   [ check this ]
           [ the empty replacement of macro 'linkedList' ]

.....
.....

Hence you are getting the error: expected identifier error.

To solve this problem, just change the name of #include guard in the linkedList.h header file.

H.S.
  • 11,654
  • 2
  • 15
  • 32