Search code examples
c++c-preprocessorheader-files

Header file works fine in one #include, causes syntax errors in another


I've got a legacy header file in my C++ project that is known to be fine. It's worked in various places in the code base without issues.

It does drag in a lot of other headers with it, which I think might be part of the issue:

/* legacy.h: */

#include "A.h"
#include "B.h"

// (Some definitions I need)


/* A.h: */

#include "C.h" // The rabbit hole continues for another few layers


/* B.h */

#include <windows.h>
#include "D.h" // Again, this also pulls in more things

I've written a new module in this project that has also worked fine for weeks:

/* module.h */

// Status codes for new module
struct Status {
    enum Enum           
    {
        ALL_GOOD = 0,
        ERROR
    };
};


/* module.cpp */

#include "module.h"

// (Code that previously didn't require the legacy header)

Today, I made a relatively small addition that required pulling in the legacy header.

All of the sudden, nothing compiles! I get hundreds of confusing syntax errors such as:

error C2143: syntax error : missing '}' before 'constant'

Weirdly, these errors will start on different lines in either module.h or module.cpp depending on the order I try to use the headers.

The worst part is, the problem doesn't seem to have anything to do with my new code in module.cpp. Heck, I even reverted back to the version that had been working for weeks. That still works, but the second I include legacy.h, everything breaks!

What's going on here? Both my module and this header are known to work just fine elsewhere, so how could they possibly cause syntax errors when brought together?


Solution

  • You appear to be a victim of a preprocessor macro somewhere in the include chain of legacy.h. I'd bet the syntax errors originate on the first use of Status::ERROR as mentioned in your header:

    /* module.h */
    
    // Status codes for new module
    struct Status {
        enum Enum           
        {
            ALL_GOOD = 0,
            ERROR // <- Syntax errors appear here
        };
    };
    

    In this case, the offender is probably

    /* B.h */
    
    #include <windows.h>
    

    I think windows.h has a macro called ERROR.

    Consider using a different naming scheme than all caps for your enum definitions, as programmers #defining a macro will often choose such names.