Different behavior of C/C++-preprocessor

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

  1. Alex Vinokur

    Alex Vinokur Guest

    Hi,

    Hi,

    Different C/C++-preprocessors have diffrerent behavior on this program.

    Is there any preprocessor standard for this case?

    // ========================
    // File foo.cpp

    #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
    > icpc -E foo.cpp


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

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

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



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


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

    #line 1 "foo.cpp"

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

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

  2. On 7/15/2012 12:43 AM, Alex Vinokur wrote:
    > Different C/C++-preprocessors have diffrerent behavior on this program.
    >
    > Is there any preprocessor standard for this case?


    There is but one Standard, ISO/IEC 14882:2011. It defines how the text
    of a C++ program is preprocessed. See subclause 2.2 and subclause 16.3.

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


    Here you have directives (#if, #else and #endif) appear inside a macro
    *invocation*. According to [cpp.replace/11], which says "If there are
    sequences of preprocessing tokens within the list of arguments that
    would otherwise act as preprocessing directives,155 the behavior is
    undefined", the behavior of the preprocessor is not defined by the
    Standard for your code. I think you're lucky they don't format your
    hard drive or email obscene photos to your boss on your behalf.

    > 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
    >> icpc -E foo.cpp

    >
    > ----- Output of preprocessing -----
    >
    > # 1 "foo.cpp"
    > int main()
    > {
    > "ABC";
    > # 13 "foo.cpp"
    > return 0;
    > }n 0;
    > }
    >
    > ========================
    >
    >
    >
    > ========= Windows =========
    > // Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
    >> cl /E foo.cpp

    >
    > ----- Output of preprocessing -----
    >
    > #line 1 "foo.cpp"
    >
    > int main()
    > {
    > #if 1 "ABC" #else "XYZ" #endif;
    > #line 13 "foo.cpp"
    > return 0;
    > }
    >
    > ===========================
    >


    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jul 16, 2012
    #2
    1. Advertising

  3. Victor Bazarov <> wrote:
    > I think you're lucky they don't format your
    > hard drive or email obscene photos to your boss on your behalf.


    No, they are. Because else they would be flooded with lawsuits.
     
    Juha Nieminen, Jul 17, 2012
    #3
  4. Alex Vinokur

    W Karas Guest

    On Monday, July 16, 2012 10:53:13 AM UTC-4, Victor Bazarov wrote:
    ....
    > Here you have directives (#if, #else and #endif) appear inside a macro
    > *invocation*. According to [cpp.replace/11], which says &quot;If there are
    > sequences of preprocessing tokens within the list of arguments that
    > would otherwise act as preprocessing directives,155 the behavior is
    > undefined&quot;, the behavior of the preprocessor is not defined by the
    > Standard for your code. I think you're lucky they don't format your
    > hard drive or email obscene photos to your boss on your behalf.


    Victor, Victor, where's the love?
     
    W Karas, Jul 25, 2012
    #4
  5. On 7/25/2012 12:23 AM, W Karas wrote:
    > On Monday, July 16, 2012 10:53:13 AM UTC-4, Victor Bazarov wrote:
    > ...
    >> Here you have directives (#if, #else and #endif) appear inside a macro
    >> *invocation*. According to [cpp.replace/11], which says &quot;If there are
    >> sequences of preprocessing tokens within the list of arguments that
    >> would otherwise act as preprocessing directives,155 the behavior is
    >> undefined&quot;, the behavior of the preprocessor is not defined by the
    >> Standard for your code. I think you're lucky they don't format your
    >> hard drive or email obscene photos to your boss on your behalf.

    >
    > Victor, Victor, where's the love?
    >


    In the air, I'm guessing...
     
    Victor Bazarov, Jul 25, 2012
    #5
  6. Alex Vinokur

    W Karas Guest

    On Wednesday, July 25, 2012 8:42:22 AM UTC-4, Victor Bazarov wrote:
    > On 7/25/2012 12:23 AM, W Karas wrote:
    > &gt; On Monday, July 16, 2012 10:53:13 AM UTC-4, Victor Bazarov wrote:
    > &gt; ...
    > &gt;&gt; Here you have directives (#if, #else and #endif) appear inside a macro
    > &gt;&gt; *invocation*. According to [cpp.replace/11], which says &amp;quot;If there are
    > &gt;&gt; sequences of preprocessing tokens within the list of arguments that
    > &gt;&gt; would otherwise act as preprocessing directives,155 the behavior is
    > &gt;&gt; undefined&amp;quot;, the behavior of the preprocessor is not defined by the
    > &gt;&gt; Standard for your code. I think you&amp;#39;re lucky they don&amp;#39;t format your
    > &gt;&gt; hard drive or email obscene photos to your boss on your behalf.
    > &gt;
    > &gt; Victor, Victor, where's the love?
    > &gt;
    >
    > In the air, I'm guessing...


    You seem to be holding your breath :eek:) .
     
    W Karas, Jul 26, 2012
    #6
  7. Alex Vinokur

    James Kanze Guest

    On Sunday, July 15, 2012 5:43:07 AM UTC+1, Alex Vinokur wrote:
    > Different C/C++-preprocessors have diffrerent behavior on this program.


    Only when you use extensions.

    > Is there any preprocessor standard for this case?


    I presume you're using an option to request preprocessor output
    from the compiler. The standard says nothing about this, and in
    fact, doesn't even require such an option.

    Judging from the output you post, it looks like the option you
    used with Microsoft doesn't do full preprocessing, but rather
    outputs some internal format with some preprocessing directives
    not yet expanded. It's not what I'd normally expect, but
    there's certainly nothing you can say against it from a
    standards point of view.

    --
    James
     
    James Kanze, Jul 29, 2012
    #7
  8. Alex Vinokur

    James Kanze Guest

    On Monday, July 16, 2012 3:53:13 PM UTC+1, Victor Bazarov wrote:
    > On 7/15/2012 12:43 AM, Alex Vinokur wrote:


    > > Different C/C++-preprocessors have diffrerent behavior on this program.
    > > Is there any preprocessor standard for this case?


    > There is but one Standard, ISO/IEC 14882:2011. It defines how the text
    > of a C++ program is preprocessed. See subclause 2.2 and subclause 16.3.


    It defines how the entire program is translated to an executable. He's
    apparently using some (very common) option to dump some (not necessarily
    well defined) internal state of the compiler.

    > Here you have directives (#if, #else and #endif) appear inside a macro
    > *invocation*. According to [cpp.replace/11], which says "If there are
    > sequences of preprocessing tokens within the list of arguments that
    > would otherwise act as preprocessing directives, the behavior is
    > undefined", the behavior of the preprocessor is not defined by the
    > Standard for your code. I think you're lucky they don't format your
    > hard drive or email obscene photos to your boss on your behalf.


    That's an interesting quote. I wasn't aware of this restriction. As a
    programmer, of course, I'd never write code like this. I like my code
    to be readable and maintainable. But I wasn't aware that it was
    illegal. Thanks for pointing it out to me; I've yet another argument
    against such junk.

    In practice, I expect that most compilers "do the right thing" in this
    case. I'm afraid that there are tons of legacy C code which counts on
    it. (I can recall 8 deep nesting of #if to make a single token
    conditional in some older Unix headers.)

    It would be interesting if we had a valid test of something
    which might be (or have been) defined by the standard.
    Something along the lines of:

    #include <iostream>
    #define PRINT(x) std::cout << (x) << std::endl

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


    Does this compile and generate an executable? If so, what does
    it output?

    --
    James
     
    James Kanze, Jul 29, 2012
    #8
    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. Raghu Rudra

    Different behavior locally vs remotely

    Raghu Rudra, Jul 21, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    328
    Raghu Rudra
    Jul 21, 2003
  2. Johnny Ruin
    Replies:
    5
    Views:
    502
  3. Cronus
    Replies:
    1
    Views:
    676
    Paul Mensonides
    Jul 15, 2004
  4. Mantorok Redgormor
    Replies:
    70
    Views:
    1,763
    Dan Pop
    Feb 17, 2004
  5. news.sunrise
    Replies:
    10
    Views:
    796
Loading...

Share This Page