Problem with GCC 3.3 and pasting in macros

Discussion in 'C Programming' started by Boris Boehlen, Jun 25, 2003.

  1. Hello,

    One of our C files declares the following macro

    #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;

    which used as follows:

    LRCALL_USELOCAL(DeleteGraphPool, (PDir, Pool, get_pool_mark( PDir, Pool), Status), (PDir, Pool, Status) );

    When I compile this code with GCC 3.3 I get the following error message:

    rgras.c:290:111: pasting "LG__DeleteGraphPool" and "(" does not give a valid preprocessing token

    Looking around in the web I found no applicable solution for this problem.
    For example, it has been suggested to remove the ## which is not possible
    in my case. As far as I can see the problem seems to be that we are
    passing a couple of parameters, enclosed in (...) to the macro. The code
    compiles with GCC 2.95.

    Any ideas? Please respond by mail because I'm reading this news group on
    an irregular basis.

    Regards,

    Boris Boehlen


    --
    Dipl.-Inform. Boris Boehlen -aachen.de
    RWTH Aachen (Technical University of Aachen)
    Department of Computer Science III phone: +49 (2 41) 80 21 312
    Ahornstrasse 55, 52074 Aachen fax: +49 (2 41) 80 22 218
     
    Boris Boehlen, Jun 25, 2003
    #1
    1. Advertising

  2. Boris Boehlen <-aachen.de> scribbled the following:
    > Hello,


    > One of our C files declares the following macro


    > #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;


    > which used as follows:


    > LRCALL_USELOCAL(DeleteGraphPool, (PDir, Pool, get_pool_mark( PDir, Pool), Status), (PDir, Pool, Status) );


    > When I compile this code with GCC 3.3 I get the following error message:


    > rgras.c:290:111: pasting "LG__DeleteGraphPool" and "(" does not give a valid preprocessing token


    This is because there is no such token as "LG__DeleteGraphPool(". The
    "(" is a token all by itself.
    For example, if you have the statement:

    LG__DeleteGraphPool(PDir, Pool, Status);

    then it should be tokenised as:

    LG__DeleteGraphPool
    (
    PDir
    ,
    Pool
    ,
    Status
    )
    ;

    As you can see, everything that can possibly have a meaning all by
    itself in the C syntax is its own token.
    Your macro isn't doing this. It's trying to tokenise this as:

    LG__DeleteGraphPool(
    PDir
    ,
    Pool
    ,
    Status
    )
    ;

    or something similar (it might even be trying to tokenise the last
    parameter as "Status)"). This breaks the C syntax rules, which are
    defined in terms of tokens, not in terms of characters.

    > Looking around in the web I found no applicable solution for this problem.
    > For example, it has been suggested to remove the ## which is not possible
    > in my case. As far as I can see the problem seems to be that we are
    > passing a couple of parameters, enclosed in (...) to the macro. The code
    > compiles with GCC 2.95.


    The only way to make it tokenise the statement correctly is to remove
    the second ## (but keep the first ##). Like it or not, it's really the
    only way to make C see the "LG__DeleteGraph(" as a function name and the
    start of a parameter list.
    If the code compiles cleanly with both ## in place in GCC 2.95, then
    GCC 2.95 is broken, although I think now Dan Pop will chime in and
    accuse me of not engaging my brain.
    I don't think you even *can* pass variable arguments to a macro in
    standard C. If you can in GCC, then it's a GCC feature, not a C feature.

    > Any ideas? Please respond by mail because I'm reading this news group on
    > an irregular basis.


    Why is your time worth more than ours? It's not like you paid for our
    services or anything. No, buddy, post here, read here.

    PS. Please try to keep your line lengths below 76 characters.

    --
    /-- Joona Palaste () ---------------------------\
    | Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
    | http://www.helsinki.fi/~palaste W++ B OP+ |
    \----------------------------------------- Finland rules! ------------/
    "Bad things only happen to scoundrels."
    - Moominmamma
     
    Joona I Palaste, Jun 25, 2003
    #2
    1. Advertising

  3. Boris Boehlen wrote:

    > #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;
    > LRCALL_USELOCAL(DeleteGraphPool, (PDir, Pool, get_pool_mark( PDir, Pool), Status), (PDir, Pool, Status) );
    >
    > When I compile this code with GCC 3.3 I get the following error message:
    >
    > rgras.c:290:111: pasting "LG__DeleteGraphPool" and "(" does not give a valid preprocessing token


    gcc3.3 is right.

    > For example, it has been suggested to remove the ## which is not possible
    > in my case.


    Too bad. That's the only correct solution for this macro call.
    ANSI 3.8.3.3 (The ## operator) says: 'If the result [from the ##
    operator] is not a valid preprocessing token, the behavior is
    undefined.'

    Another way might be to have two macros, one with and one without the
    second ##, and take care to use the appropriate one.

    > As far as I can see the problem seems to be that we are
    > passing a couple of parameters, enclosed in (...) to the macro.


    Yes.

    > The code compiles with GCC 2.95.


    gcc 2 is sloppier about error checking than gcc 3.

    --
    Hallvard
     
    Hallvard B Furuseth, Jun 25, 2003
    #3
  4. Boris Boehlen

    Dan Pop Guest

    In <-aachen.de> Boris Boehlen <-aachen.de> writes:

    >One of our C files declares the following macro
    >
    > #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;
    >
    >which used as follows:
    >
    > LRCALL_USELOCAL(DeleteGraphPool, (PDir, Pool, get_pool_mark( PDir, Pool), Status), (PDir, Pool, Status) );
    >
    >When I compile this code with GCC 3.3 I get the following error message:
    >
    > rgras.c:290:111: pasting "LG__DeleteGraphPool" and "(" does not give a valid preprocessing token
    >
    >Looking around in the web I found no applicable solution for this problem.


    The gcc error message is crystal clear: the result of the ## operator must
    be a preprocessing token, which is not the case in your example.

    >For example, it has been suggested to remove the ## which is not possible
    >in my case. As far as I can see the problem seems to be that we are
    >passing a couple of parameters, enclosed in (...) to the macro. The code
    >compiles with GCC 2.95.


    You're invoking undefined behaviour, so a compiler is allowed to do
    anything it wants with your code:

    If the result is not a valid preprocessing token, the behavior is
    undefined.

    >Any ideas?


    #define LRCALL_USELOCAL(op,s1,s2) RG__##op s2;

    BTW, are you *really* sure you want the semicolon at the end? Your
    sample invocation of the macro certainly makes it redundant and it
    could be downright harmful in other contexts.

    >Please respond by mail because I'm reading this news group on
    >an irregular basis.


    You post here, you read here. This way, if my advice is complete
    bullshit, someone else will have a chance to correct it.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jun 25, 2003
    #4
  5. Hello,

    >> #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;

    Based on the response of Joona Palaste I changed this line to

    #define LRCALL_USELOCAL(op,s1,s2) RG__##op s2;

    and nothing changed.

    > As you can see, everything that can possibly have a meaning all by
    > itself in the C syntax is its own token.
    > Your macro isn't doing this. It's trying to tokenise this as:

    What are the reasons that it tries to tokenize it in that way?

    > The only way to make it tokenise the statement correctly is to remove
    > the second ## (but keep the first ##). Like it or not, it's really the
    > only way to make C see the "LG__DeleteGraph(" as a function name and the
    > start of a parameter list.

    As said above, I did exactly this and nothing changed. Why?

    Kind Regards,

    Boris Boehlen

    --
    Dipl.-Inform. Boris Boehlen -aachen.de
    RWTH Aachen (Technical University of Aachen)
    Department of Computer Science III phone: +49 (2 41) 80 21 312
    Ahornstrasse 55, 52074 Aachen fax: +49 (2 41) 80 22 218
     
    Boris Boehlen, Jun 25, 2003
    #5
  6. Boris Boehlen wrote:

    >>> #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;

    > Based on the response of Joona Palaste I changed this line to
    >
    > #define LRCALL_USELOCAL(op,s1,s2) RG__##op s2;
    >
    > and nothing changed.


    I tried it with gcc3.3 and it worked fine. I think you must be
    #including the wrong version of the .h file which defines that macro
    or something.

    >> As you can see, everything that can possibly have a meaning all by
    >> itself in the C syntax is its own token.
    >> Your macro isn't doing this. It's trying to tokenise this as:

    > What are the reasons that it tries to tokenize it in that way?


    ## takes two tokens and combines them into one token.
    So the result is expected _be_ a valid token.

    --
    Hallvard
     
    Hallvard B Furuseth, Jun 25, 2003
    #6
  7. Boris Boehlen <-aachen.de> scribbled the following:
    > Hello,


    >>> #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;

    > Based on the response of Joona Palaste I changed this line to


    > #define LRCALL_USELOCAL(op,s1,s2) RG__##op s2;


    > and nothing changed.


    >> As you can see, everything that can possibly have a meaning all by
    >> itself in the C syntax is its own token.
    >> Your macro isn't doing this. It's trying to tokenise this as:

    > What are the reasons that it tries to tokenize it in that way?


    >> The only way to make it tokenise the statement correctly is to remove
    >> the second ## (but keep the first ##). Like it or not, it's really the
    >> only way to make C see the "LG__DeleteGraph(" as a function name and the
    >> start of a parameter list.

    > As said above, I did exactly this and nothing changed. Why?


    Perhaps the fault lies elsewhere. I tested your problem with the
    following minimalistic resemblance of your code:

    #define LRCALL_USELOCAL(op,s1,s2) LG__##op s2

    void LG__DeleteGraphPool(int PDir, int Pool, int Status) {
    return;
    }

    int get_pool_mark(int PDir, int Pool) {
    return 0;
    }

    int main(void) {
    int PDir=0, Pool=0, Status=0;
    LRCALL_USELOCAL(DeleteGraphPool, (PDir, Pool, get_pool_mark( PDir,
    Pool), Status), (PDir, Pool, Status));
    return 0;
    }

    and got no warnings other than for unused parameters. When I put the
    second ## back in, I got the original warning "LG__DeleteGraph( is not
    a valid preprocessing token" which I expected, and which I must say,
    makes perfect sense.
    BTW I have only tested with GCC 2.96. I don't have GCC 3.3 available
    for testing.

    --
    /-- Joona Palaste () ---------------------------\
    | Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
    | http://www.helsinki.fi/~palaste W++ B OP+ |
    \----------------------------------------- Finland rules! ------------/
    "Insanity is to be shared."
    - Tailgunner
     
    Joona I Palaste, Jun 25, 2003
    #7
  8. BTW,

    Boris Boehlen wrote:

    > #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;
    > LRCALL_USELOCAL(DeleteGraphPool,
    > (PDir, Pool, get_pool_mark( PDir, Pool), Status), (PDir, Pool, Status) );


    since you put ';' after the LRCALL_USELOCAL call, you should probably
    not have ';' in the macro.

    --
    Hallvard
     
    Hallvard B Furuseth, Jun 25, 2003
    #8
  9. Boris Boehlen

    Micah Cowan Guest

    Joona I Palaste <> writes:

    > Boris Boehlen <-aachen.de> scribbled the following:
    > > Hello,

    >
    > > One of our C files declares the following macro

    >
    > > #define LRCALL_USELOCAL(op,s1,s2) RG__##op##s2;

    >
    > > which used as follows:

    >
    > > LRCALL_USELOCAL(DeleteGraphPool, (PDir, Pool, get_pool_mark( PDir, Pool), Status), (PDir, Pool, Status) );

    >
    > > When I compile this code with GCC 3.3 I get the following error message:

    >
    > > rgras.c:290:111: pasting "LG__DeleteGraphPool" and "(" does not give a valid preprocessing token


    <snip>

    > If the code compiles cleanly with both ## in place in GCC 2.95, then
    > GCC 2.95 is broken, although I think now Dan Pop will chime in and
    > accuse me of not engaging my brain.


    It certainly wouldn't compile cleanly with warnings on (unsure and too
    lazy to verify without warnings), and certainly in strict
    conformance mode.

    > I don't think you even *can* pass variable arguments to a macro in
    > standard C. If you can in GCC, then it's a GCC feature, not a C
    > feature.


    There are no varargs in the code above. There are precisely three,
    protected by parens.

    -Micah
     
    Micah Cowan, Jun 26, 2003
    #9
  10. Hello,

    First I'd like to thank all of you for your help.

    > Perhaps the fault lies elsewhere. I tested your problem with the
    > following minimalistic resemblance of your code:


    > [ ... Code snippet ]


    I compiled your example with the gcc 3.3 from Debain and it compiles
    without any problem. Thus, the problem seems to be somewhere else.

    I'll try to find out where the problem is and try to produce a minial
    example which reproduces the error if I can't track it down.

    Again, thanks for your help.

    Boris

    --
    Dipl.-Inform. Boris Boehlen -aachen.de
    RWTH Aachen (Technical University of Aachen)
    Department of Computer Science III phone: +49 (2 41) 80 21 312
    Ahornstrasse 55, 52074 Aachen fax: +49 (2 41) 80 22 218
     
    Boris Boehlen, Jun 26, 2003
    #10
  11. Boris Boehlen

    Dan Pop Guest

    In <bdcgn9$6jh$> Joona I Palaste <> writes:

    >If the code compiles cleanly with both ## in place in GCC 2.95, then
    >GCC 2.95 is broken, although I think now Dan Pop will chime in and
    >accuse me of not engaging my brain.


    Your guess is right! Undefined behaviour requires no diagnostic and we
    have a case of undefined behaviour here. Both versions of gcc are doing
    the right thing.

    >I don't think you even *can* pass variable arguments to a macro in
    >standard C. If you can in GCC, then it's a GCC feature, not a C feature.


    Please engage your brain *now* and explain us where are the variable
    arguments in OP's examples. AFAICT, the macro was defined with three
    parameters and invoked with three arguments, a perfect match.

    BTW, C99 supports macros with a variable argument list.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jun 26, 2003
    #11
    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. Replies:
    80
    Views:
    2,536
    Stephen J. Bevan
    Nov 7, 2003
  2. Replies:
    1
    Views:
    497
    Marco Antoniotti
    Oct 7, 2003
  3. Replies:
    5
    Views:
    516
  4. Ben Bacarisse

    Re: String literals in macros that use token pasting

    Ben Bacarisse, Aug 3, 2009, in forum: C Programming
    Replies:
    2
    Views:
    1,326
    Anand Hariharan
    Aug 4, 2009
  5. girishk.k4
    Replies:
    0
    Views:
    1,146
    girishk.k4
    Mar 23, 2013
Loading...

Share This Page