#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    7
    Rep Power
    0

    Newbie preprocessor compile error question (glitch?)


    Hey all,

    First off, here are my actual (compile time) errors:

    cprog.c:15:8: error: token ""I know the C language.\n"" is not valid in preprocessor expressions
    cprog.c:19:8: error: token ""I know BASIC.\n"" is not valid in preprocessor expressions

    I'm still learning the basics of C from a Learn C in 24 Hours type book (which is where this code comes from), and I think I understand what I'm trying to do, just don't understand why my code is triggering an error. I'm thinking there's something low-level happening making it not work, and I was hoping you all might be able to tell and that I'd learn something from it. Here's my actual code, as I said I don't think I did anything wrong (correct if that's not true), but something buggy seems afoot.


    #include <stdio.h>

    #define C_LANG 'C'
    #define B_LANG 'B'
    #define NO_ERROR 0

    main(void)
    {
    #if C_LANG == 'C' && B_LANG == 'B'
    #undef C_LANG
    #define C_LANG "I know the C language.\n" // Error here
    #undef B_LANG
    #define B_LANG "I know BASIC.\n" // Error here
    printf("%s%s", C_LANG, B_LANG);
    #elif C_LANG == 'C'
    #undef C_LANG
    #define C_LANG "I only know C language.\n" // See below
    printf("%s", C_LANG);
    #elif B_LANG == 'B'
    #undef B_LANG
    #define B_LANG "I only know BASIC.\n"
    printf("%s", B_LANG);
    #else
    printf("I don't know C or BASIC.\n");
    #endif

    return NO_ERROR;

    }

    Also, it seems like it's something to do with the position of the code (maybe there's an error in doing this with #if, but not #elif?) because if I change the initial #defines of C_LANG or B_LANG those codes run fine. And if I literally copy-paste the #define C_LANG from the first #elif statement over the first #define C_LANG (in the if statement), THEN it says it's not acceptable. I think it should be acceptable, not sure what's going on here. Any ideas?
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,406
    Rep Power
    1871
    If you had executable code, it would be something like
    Code:
    if ( cond1 ) {
    } else if ( cond2 ) {
    } else {
    }
    Now the important thing to remember here is that if cond1 is true, then cond2 is NOT evaluated.

    This however is not the case with the pre-processor. Each branch is compared as it is seen, which means if you mess with the conditional before hand, you get some really strange effects.
    Code:
    #if C_LANG == 'C' && B_LANG == 'B'
    #undef C_LANG
    #define C_LANG "I know the C language.\n" // Error here
    #undef B_LANG
    #define B_LANG "I know BASIC.\n" // Error here
    printf("%s%s", C_LANG, B_LANG);
    #elif C_LANG == 'C'
    What the blue like looks like is this
    #elif "I know the C language.\n" == 'C'

    Actually, your markers are incorrect. The lines which show the errors are the two #elif lines trying to compare a string with a character.

    Personally, I would suggest you pick a different #define name for the string version as opposed to the single letter version. Say for example C_LANG_STR and B_LANG_STR respectively.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper

IMN logo majestic logo threadwatch logo seochat tools logo