Problem with GCC 3.3 and pasting in macros

B

Boris Boehlen

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
 
J

Joona I Palaste

Boris Boehlen said:
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 ([email protected]) ---------------------------\
| 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
 
H

Hallvard B Furuseth

Boris said:
#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.
 
D

Dan Pop

In said:
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
 
B

Boris Boehlen

Hello,
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
 
H

Hallvard B Furuseth

Boris said:
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.
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.
 
J

Joona I Palaste

Boris Boehlen said:
Hello,
Based on the response of Joona Palaste I changed this line to
#define LRCALL_USELOCAL(op,s1,s2) RG__##op s2;
and nothing changed.
What are the reasons that it tries to tokenize it in that way?
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 ([email protected]) ---------------------------\
| 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
 
H

Hallvard B Furuseth

BTW,

Boris said:
#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.
 
M

Micah Cowan

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
 
B

Boris Boehlen

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
 
D

Dan Pop

In said:
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
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top