This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

preprocessor bug?

#define SYSYEM LINUX



#if SYSTEM == LINUX
#define HDR "linux.h"
#elif SYSTEM == WINDOWS
#define HDR "windows.h"
#elif SYSTEM == C51
#define HDR "c51.h"
#else
#define HDR "default.h"
#endif
#include HDR


I would expect this to work, but I just keep getting "warning C322: unknown identifier" errors. whats wrong?

  • the #define SYSYEM LINUX is just a typo in the posting

    #define SYSTEM LINUX

  • I don't know, it looks ok to me. Which lines are actually giving the warnings?

    I don't see your reason for defining HDR, why not just replace tose lines with #include lines? Maybe the preprocessor doesn't like #defining strings.

    Stefan

  • How are you defining LINUX, WINDOWS, etc?

  • Preprocessor macros always resolve to something, possible through multiple steps, even when "something" is really nothing. There's no such thing as a preprocessor "literal constant" where the preprocessor stops substituting.

    #define SYSTEM LINUX

    means "replace all occurrences of SYSTEM with LINUX. Then go back and replace all occurrences of LINUX with whatever LINUX is #defined to be. If LINUX isn't #defined, replace it with nothing."

    So, if there's no definition for LINUX,

    #if SYSTEM == LINUX

    turns into

    #if LINUX ==

    which then turns into

    #if ==

    after macro substitution, which isn't very useful.

    Wait, I know what you'r about to do:

    #define SYSTEM "Linux"
    #if SYSTEM == "Linux"

    But the preprocessor cannot compare string constants. Not even the stringizing operator can save you. Don't even try it :)

    You'll have to have a standard header with something like:

    #define LINUX 1
    #define WINDOWS 2
    #define RTX51_TINY 3
    #define UCOS 4

    and then you'll be able to write:

    #include <osdefs.h>

    #define SYSTEM LINUX

    #if SYSTEM == LINUX

    to get the effect that you want.

    (The "#define SYSTEM LINUX" most likely belongs in your build environment, not in the source code. It doesn't help portability if you have to edit this one line of text. Pass the definition for SYSTEM in on the compiler command line instead, and then you don't have to touch the code at all.)

  • #if SYSTEM == LINUX

    turns into

    #if LINUX ==

    which then turns into

    #if ==


    Close, but no cigar... Names found in #if expressions that don't have any
    definition are replaced by literal zeros, not by nothing at all. I.e. the above resolves to

    #if 0L == 0L

    which finally evaluates to true.

    I.e.: in a preprocessor statement, everthing finally is expanded to a number.

    Note that this does not happen in ordinary C source lines. LINUX mentioned elsewhere will not turn into a zero.

  • Hm. Yes, I think Hans is right. When I ran into this same problem a while back, the symptom was that the compiler always took the first #if branch, rather than give me a compiler error. Thanks for the correction.

    I don't like cigars anyway :)