Different C-preprocessors have diffrerent behavior

Discussion in 'C Programming' started by Alex Vinokur, Jul 15, 2012.

  1. Alex Vinokur

    Alex Vinokur Guest

    Hi,

    Different C-preprocessors have diffrerent behavior on this program.

    Is there any preprocessor standard for this case?

    // ========================
    // File foo.c

    #define MACRO1(x) x
    #define MACRO2(x) x

    int main()
    {
    MACRO1(
    #if 1
    MACRO2("ABC")
    #else
    MACRO2("XYZ")
    #endif
    );
    return 0;
    }

    // ========================



    ========= Linux =========
    // Intel(R) C Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 12.0.4.191 Build 20110427
    > icc -E foo.c


    ----- Output of preprocessing -----

    # 1 "foo.c"
    int main()
    {
    "ABC";
    # 13 "foo.c"
    return 0;
    }n 0;
    }

    ========================



    ========= Windows =========
    // Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
    > cl /E foo.c


    ----- Output of preprocessing -----

    #line 1 "foo.c"

    int main()
    {
    #if 1 "ABC" #else "XYZ" #endif;
    #line 13 "foo.c"
    return 0;
    }

    ===========================
     
    Alex Vinokur, Jul 15, 2012
    #1
    1. Advertising

  2. Alex Vinokur

    Alan Curry Guest

    In article <>,
    Alex Vinokur <> wrote:
    >Hi,
    >
    >Different C-preprocessors have diffrerent behavior on this program.
    >
    >Is there any preprocessor standard for this case?


    I'm afraid not. The standard says this about expansion of function-like
    macros (macros with arguments):

    If there are sequences of preprocessing tokens within the list of arguments
    that would otherwise act as preprocessing directives, the behavior is
    undefined.

    (section 6.10.3 paragraph 11)

    gcc -pedantic would have warned you about it.

    >// ========================
    >// File foo.c
    >
    >#define MACRO1(x) x
    >#define MACRO2(x) x
    >
    >int main()
    >{
    > MACRO1(
    >#if 1
    > MACRO2("ABC")
    >#else
    > MACRO2("XYZ")
    >#endif
    > );
    > return 0;
    >}


    You'll have to make MACRO1 a function, or factor out the #if so that it
    covers the entire invocation of MACRO1, like this:

    #if 1
    MACRO1(MACRO2("ABC"));
    #else
    MACRO1(MACRO2("XYZ"));
    #endif

    Actually, the semicolon isn't within the problem area so it doesn't need to
    be repeated in both branches, but I think a bare semicolon after an #endif
    would be stylistically unfortunate:

    #if 1
    MACRO1(MACRO2("ABC"))
    #else
    MACRO1(MACRO2("XYZ"))
    #endif
    ;

    Or refactor it another way:

    #if 1
    #define arg "ABC"
    #else
    #define arg "XYZ"
    #endif
    MACRO1(MACRO2(arg));

    Or even:

    MACRO1(1?MACRO2("ABC"):MACRO2("XYZ"));

    i.e. trust the compiler to figure out that one of those branches is
    unreachable and optimize it out.

    --
    Alan Curry
     
    Alan Curry, Jul 15, 2012
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Preprocessors

    , Jul 3, 2006, in forum: HTML
    Replies:
    9
    Views:
    430
    dorayme
    Jul 5, 2006
  2. Replies:
    5
    Views:
    269
    Jon Willeke
    May 2, 2004
  3. Jamiil

    using preprocessors - help!!

    Jamiil, Dec 18, 2005, in forum: C Programming
    Replies:
    4
    Views:
    365
    Keith Thompson
    Dec 19, 2005
  4. Let_Me_Be

    Advanced Macros && Preprocessors

    Let_Me_Be, Apr 28, 2006, in forum: C Programming
    Replies:
    9
    Views:
    378
    Thad Smith
    Apr 29, 2006
  5. Alex Vinokur
    Replies:
    2
    Views:
    290
    Alex Vinokur
    Dec 19, 2012
Loading...

Share This Page