I've been writing a tad of C lately. I haven't had too much experience throwing everything into headers, writing their implementations, etc - but I thought I knew enough. At least, until today :P
Long story short - I'm getting an error of 'conflicting types for ValueArray' - but it points me to the same line for the previous declaration.
It repeats that for a handful of declarations in that same file, and then declarations in another file as well.
P.S. The error is not underlined in CLion as well.
In file included from chunk.h:2,
from vm.h:1,
from compiler.h:1,
from vm.c:5:
value.h:7:3: error: conflicting types for ‘ValueArray’
7 | } ValueArray;
| ^~~~~~~~~~
In file included from chunk.h:2,
from vm.h:1,
from vm.c:4:
value.h:7:3: note: previous declaration of ‘ValueArray’ was here
7 | } ValueArray;
| ^~~~~~~~~~
Here is value.h:
typedef double Value;
typedef struct {
int capacity;
int count;
Value* values;
} ValueArray;
void initValueArray(ValueArray* array);
void writeValueArray(ValueArray* array, Value value);
void freeValueArray(ValueArray* array);
I've looked through my code and haven't found any redeclarations of ValueArray. I did some research - it seems like it could depend on when ValueArray is declared. To me though, it seems completely fine.
For reference, I'm following Bob Nystrom's guide Crafting Interpreters, with a bit of my own twists.
Thanks a million in advance!
The error is
In file included from chunk.h:2,
from vm.h:1,
from compiler.h:1,
from vm.c:5:
value.h:7:3: error: conflicting types for ‘ValueArray’
7 | } ValueArray;
but we see this next:
In file included from chunk.h:2,
from vm.h:1,
from vm.c:4:
Notice the include path is different.
It looks like you're compiling vm.c
. vm.c
includes compiler.h
, which eventually causes value.h
to be included.
You then include vm.h
, which also causes value.h
to be included.
You need to use include guards to prevent multiple inclusion of the file:
value.h
:
#ifndef MY_VALUE_H_INCLUDED
#define MY_VALUE_H_INCLUDED
(include file contents here)
#endif
You need to pick an identifier (MY_VALUE_H_INCLUDED
in this example) that will be unique. Note that starting the identifier with two underscores (__
) or an underscore and a capital letter (_V
) would be using values reserved for the implementation.
You may have circular references, in which case you need to use forward declarations.