cinterpreted-language

Error: Conflcting types for xxx pointing to same declaration


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!


Solution

  • 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.