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
    ----- 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
    ----- 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. Advertisements

  2. 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.
    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.
    V
     
    Victor Bazarov, Jul 16, 2012
    #2
    1. Advertisements

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

    W Karas Guest

    .
    Victor, Victor, where's the love?
     
    W Karas, Jul 25, 2012
    #4
  5. In the air, I'm guessing...
     
    Victor Bazarov, Jul 25, 2012
    #5
  6. Alex Vinokur

    W Karas Guest

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

    James Kanze Guest

    Only when you use extensions.
    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 Kanze, Jul 29, 2012
    #7
  8. Alex Vinokur

    James Kanze Guest

    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.
    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 Kanze, Jul 29, 2012
    #8
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.