G++ paste operator - expands as desired but compile fails

Discussion in 'C++' started by Chris, Aug 15, 2007.

  1. Chris

    Chris Guest

    Hello all,

    Using g++ 3.3.1 on Linux ("Linux From Scratch") I have a data
    structure SCSIParams_t that I wish to print out, field-by-field.
    Rather than code a long line of the form

    std::cout << "fieldname = " << basepointer->fieldname <<
    std::endl;

    for every field, I'd like to do it with a short macro, e.g.

    EMITSCSI(SCSIDriverType);

    I've coded a macro definition

    #define EMITSCSI(fieldname) \
    std::cout << # field << " = " << basepointer->##fieldname <<
    std::endl

    and coded, as a test, a single line identical to the "short macro,
    e.g..." example shown above.

    That line generates the compile error,

    pasting "->" and "fieldname" does not give a valid
    preprocessing token

    However, using the -E switch on the compile line, I find that the
    macro does, in fact, expand to a line identical to the "long line..."
    shown above. In fact, if I cut-and-paste the expansion text from the
    preprocessor output into my source file, and comment out the line that
    uses the macro, my code compiles cleanly. That is to say, "expanding
    the macro" MANUALLY, i.e. "by hand," leads to successful compilation,
    but letting the preprocessor do it leads to failiure-to-compile.

    Can someone suggest a way around this? I also have g++ 3.4.3
    available, although that's not what we use for standard development.

    Thanks,

    Chris

    PS - the e-mail address appearing on this message is no longer valid,
    so don't e-mail. My new address is similar but different:
    . I'll create a new Google Groups login soon...
    Chris, Aug 15, 2007
    #1
    1. Advertising

  2. Chris

    Ondra Holub Guest

    On 15 Srp, 19:35, Chris <> wrote:
    > Hello all,
    >
    > Using g++ 3.3.1 on Linux ("Linux From Scratch") I have a data
    > structure SCSIParams_t that I wish to print out, field-by-field.
    > Rather than code a long line of the form
    >
    > std::cout << "fieldname = " << basepointer->fieldname <<
    > std::endl;
    >
    > for every field, I'd like to do it with a short macro, e.g.
    >
    > EMITSCSI(SCSIDriverType);
    >
    > I've coded a macro definition
    >
    > #define EMITSCSI(fieldname) \
    > std::cout << # field << " = " << basepointer->##fieldname <<
    > std::endl
    >
    > and coded, as a test, a single line identical to the "short macro,
    > e.g..." example shown above.
    >
    > That line generates the compile error,
    >
    > pasting "->" and "fieldname" does not give a valid
    > preprocessing token
    >
    > However, using the -E switch on the compile line, I find that the
    > macro does, in fact, expand to a line identical to the "long line..."
    > shown above. In fact, if I cut-and-paste the expansion text from the
    > preprocessor output into my source file, and comment out the line that
    > uses the macro, my code compiles cleanly. That is to say, "expanding
    > the macro" MANUALLY, i.e. "by hand," leads to successful compilation,
    > but letting the preprocessor do it leads to failiure-to-compile.
    >
    > Can someone suggest a way around this? I also have g++ 3.4.3
    > available, although that's not what we use for standard development.
    >
    > Thanks,
    >
    > Chris
    >
    > PS - the e-mail address appearing on this message is no longer valid,
    > so don't e-mail. My new address is similar but different:
    > . I'll create a new Google Groups login soon...


    1. Delete extra white-space between # and field
    2. Delete ## - it is not necessary. -> and member name are different
    preprocessor tokens, so you do not need to concat them with ##
    #define EMITSCSI(fieldname) \
    std::cout << #field << " = " << basepointer->fieldname <<
    std::endl
    Ondra Holub, Aug 15, 2007
    #2
    1. Advertising

  3. Chris

    red floyd Guest

    On Aug 15, 10:35 am, Chris <> wrote:
    > Hello all,
    >
    > Using g++ 3.3.1 on Linux ("Linux From Scratch") I have a data
    > structure SCSIParams_t that I wish to print out, field-by-field.
    > Rather than code a long line of the form
    >
    > std::cout << "fieldname = " << basepointer->fieldname <<
    > std::endl;
    >
    > for every field, I'd like to do it with a short macro, e.g.
    >
    > EMITSCSI(SCSIDriverType);
    >
    > I've coded a macro definition
    >
    > #define EMITSCSI(fieldname) \
    > std::cout << # field << " = " << basepointer->##fieldname <<
    > std::endl


    Don't bother with ## here. It's only needed when you want to combine
    two preprocessor tokens into one.

    I.e. you want to create a new identifier. Since -> and fieldname are
    two separate tokens anyways, just go with

    std::cout << #fieldname " = " << basepointer->fieldname <<
    std::endl;

    Note that I corrected your typo, and that I elided the (unneeded) <<
    between #field and " = ". Since they're both string literals, the
    compiler will concatenate them.

    You might want to look into overloading operator<< for SCSIParams_t,
    i.e.

    std::eek:stream& operator<<(std::eek:stream&, const SCSIParams_t&);


    >
    > and coded, as a test, a single line identical to the "short macro,
    > e.g..." example shown above.
    >
    > That line generates the compile error,
    >
    > pasting "->" and "fieldname" does not give a valid
    > preprocessing token
    >
    red floyd, Aug 15, 2007
    #3
  4. Chris

    David Harmon Guest

    On Wed, 15 Aug 2007 10:35:30 -0700 in comp.lang.c++, Chris
    <> wrote,
    >
    > #define EMITSCSI(fieldname) \
    > std::cout << # field << " = " << basepointer->##fieldname <<
    >std::endl
    >
    >and coded, as a test, a single line identical to the "short macro,
    >e.g..." example shown above.
    >
    > That line generates the compile error,
    >
    > pasting "->" and "fieldname" does not give a valid
    >preprocessing token


    Read the message. It contains the explanation of what the problem is.
    In fact, pasting "->" can never begin a larger preprocessing token.
    The pasting is extraneous, you want simply instead
    << basepointer -> fieldname

    By the way, you are committing endl abuse. Use << '\n'
    David Harmon, Aug 15, 2007
    #4
  5. Chris

    Chris Guest

    Thanks to all who replied. To paraphrase and respond a little,

    > > #define EMITSCSI(fieldname) \
    > > std::cout << # field << " = " << basepointer->##fieldname <<
    > >std::endl

    >
    > [...]
    >
    > > pasting "->" and "fieldname" does not give a valid
    > >preprocessing token

    >
    > Read the message. It contains the explanation of what the problem is.


    With all due respect, if I understood what the error message was
    talking about, I would have fixed the problem instead of posting. :)

    > In fact, pasting "->" can never begin a larger preprocessing token.


    I don't understand what you mean by that. I expected the preprocessor
    to paste together whatever I told it to paste together, and pass the
    result along to the compiler. You're saying that's not the way it
    works?

    > The pasting is extraneous, you want simply instead
    > << basepointer -> fieldname


    I'm amazed that it's as simple as that. Clearly the scope-and-
    behavior of tokens within a macro definition is a completely "other
    animal" than in ordinary code. This is why I've programmed for 18+
    years WITHOUT USING macros. Can never get 'em to do what I want, and
    spend an inordinate amount of time fighting with the compiler over the
    matter.

    > By the way, you are committing endl abuse. Use << '\n'


    Another shock. Every C++ book I've ever read instructs the reader to
    use 'endl' (or, worse, 'std::endl') to generate end-of-line. Did this
    change? When?

    Chris
    Chris, Aug 20, 2007
    #5
    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. ck
    Replies:
    5
    Views:
    4,780
    Steve Pugh
    Jun 8, 2004
  2. MarionEll
    Replies:
    0
    Views:
    338
    MarionEll
    Nov 2, 2004
  3. chuck amadi
    Replies:
    1
    Views:
    479
    Larry Bates
    Jun 23, 2004
  4. techy techno
    Replies:
    0
    Views:
    92
    techy techno
    Feb 4, 2004
  5. M.L.
    Replies:
    9
    Views:
    287
Loading...

Share This Page