precompiler: pasting and underscore

B

Bill Pursell

This question must be FAQ, but I can't find it: I'm baffled
by the following:

[tmp]$ cat a.c
#define foo(x) foo##x_
#define bar(x) bar##x##_

foo()
foo(1)
bar()
bar(1)

[tmp]$ gcc -E a.c | tail -5

foox_
foox_
bar_
bar1_

Can anyone point me to a reference explaining how
'_' is treated by the precompiler?
 
A

Arthur J. O'Dwyer

This question must be FAQ, but I can't find it: I'm baffled
by the following:

[tmp]$ cat a.c
#define foo(x) foo##x_

This says: foo(x) is replaced by foox_ (i.e., "foo" concatenated with
"x_"). The argument "x" is ignored.
#define bar(x) bar##x##_

This says: bar(x) is replaced by "bar" concatenated with x concatenated
with "_".
Can anyone point me to a reference explaining how
'_' is treated by the precompiler?

The same way as any other letter. (And it's normally called the
"preprocessor", not the "precompiler", FYI.)

HTH,
-Arthur
 
B

Ben Pfaff

Bill Pursell said:
This question must be FAQ, but I can't find it: I'm baffled
by the following:

[tmp]$ cat a.c
#define foo(x) foo##x_
#define bar(x) bar##x##_

foo()
foo(1)
bar()
bar(1)

[tmp]$ gcc -E a.c | tail -5

foox_
foox_
bar_
bar1_

Can you explain further what part of this is baffling? I don't
see anything surprising here.

Are you surprised that "x" and "x_" are different identifiers, so
that the "x" in "x_" doesn't get macro expanded? In other words,
the definition of foo(x) doesn't actually use its argument "x" at
all.
 
C

Christopher Benson-Manica

Bill Pursell said:
#define foo(x) foo##x_

The argument x to this macro is never used; the foo and x_ tokens are
pasted to yield foox_. Thus,
foo()
foo(1)

expands to
foox_
foox_

, just as

#define foo(x) foo##xb

always expands to fooxb. Nothing mysterious here.
#define bar(x) bar##x##_

Here the argument x is used, pasting bar, x, and underscore to yield a
new token, which is apparently what you feel the first example should
do as well. An underscore in a macro is just an ordinary character.
 
E

Eric Sosman

Ben Pfaff wrote On 07/28/06 13:40,:
This question must be FAQ, but I can't find it: I'm baffled
by the following:

[tmp]$ cat a.c
#define foo(x) foo##x_
#define bar(x) bar##x##_

foo()
foo(1)
bar()
bar(1)

[tmp]$ gcc -E a.c | tail -5

foox_
foox_
bar_
bar1_


Can you explain further what part of this is baffling? I don't
see anything surprising here.

Are you surprised that "x" and "x_" are different identifiers, so
that the "x" in "x_" doesn't get macro expanded? In other words,
the definition of foo(x) doesn't actually use its argument "x" at
all.

On a related note, can someone explain why the first
invocation of each macro doesn't cause the compiler to
complain about the empty argument list? They look like
clear violations of 6.10.3/4, which requires the number
of arguments in the invocation to match the number of
parameters in the definition (for a non-variadic macro).

Based on the expansion shown, gcc appears to treat
bar() not as an invocation with an empty argument list,
but as an invocation with one argument that happens to
be empty. Is gcc's interpretation correct? C&V, anyone?

Help, please: I'm feeling unusually stupid today ...
 
B

Bill Pursell

Ben said:
Bill Pursell said:
This question must be FAQ, but I can't find it: I'm baffled
by the following:

[tmp]$ cat a.c
#define foo(x) foo##x_
#define bar(x) bar##x##_

foo()
foo(1)
bar()
bar(1)

[tmp]$ gcc -E a.c | tail -5

foox_
foox_
bar_
bar1_

Can you explain further what part of this is baffling? I don't
see anything surprising here.

Are you surprised that "x" and "x_" are different identifiers, so
that the "x" in "x_" doesn't get macro expanded? In other words,
the definition of foo(x) doesn't actually use its argument "x" at
all.

I think I was confused by the fact that foo() and bar() don't
cause errors, and I was mistakenly believing that there
is something magical about the '_' that causes that. I've
seen many obfuscated code signature blocks that use '_' as
the parameter, and somehow it has been stuck in my
head that underscore is treated specially. I was incorrectly
parsing the 'x_' as two tokens, but the example which
was given that replaces '_' with 'b' makes it clear why
I am incorrect.

Thanks to all for the responses, and I look forward to seeing
some answers to Eric Sosman's followup question about
why the macro invocations with no arguments are working
in gcc.
 
B

Ben Pfaff

Eric Sosman said:
Ben Pfaff wrote On 07/28/06 13:40,:

On a related note, can someone explain why the first
invocation of each macro doesn't cause the compiler to
complain about the empty argument list? They look like
clear violations of 6.10.3/4, which requires the number
of arguments in the invocation to match the number of
parameters in the definition (for a non-variadic macro).

Based on the expansion shown, gcc appears to treat
bar() not as an invocation with an empty argument list,
but as an invocation with one argument that happens to
be empty. Is gcc's interpretation correct? C&V, anyone?

Example 3 in 6.10.3.5 suggests that gcc's interpretation is
correct:

5 EXAMPLE 3 To illustrate the rules for redefinition and
reexamination, the sequence
#define q(x) x
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
results in
int i[] = { 1, 23, 4, 5, };

(I dropped most of the lines out of that example to emphasize the
part that is interesting for answering this question.)
 
C

Christopher Benson-Manica

Eric Sosman said:
On a related note, can someone explain why the first
invocation of each macro doesn't cause the compiler to
complain about the empty argument list? They look like
clear violations of 6.10.3/4, which requires the number
of arguments in the invocation to match the number of
parameters in the definition (for a non-variadic macro).

I was surprised to find that gcc silently accepts the code even when
passed -Wall, -ansi, and -pedantic.
 
K

Kevin Bagust

Eric said:
Ben Pfaff wrote On 07/28/06 13:40,:
This question must be FAQ, but I can't find it: I'm baffled
by the following:

[tmp]$ cat a.c
#define foo(x) foo##x_
#define bar(x) bar##x##_

foo()
foo(1)
bar()
bar(1)

[tmp]$ gcc -E a.c | tail -5

foox_
foox_
bar_
bar1_

On a related note, can someone explain why the first
invocation of each macro doesn't cause the compiler to
complain about the empty argument list? They look like
clear violations of 6.10.3/4, which requires the number
of arguments in the invocation to match the number of
parameters in the definition (for a non-variadic macro).

Based on the expansion shown, gcc appears to treat
bar() not as an invocation with an empty argument list,
but as an invocation with one argument that happens to
be empty. Is gcc's interpretation correct? C&V, anyone?

Help, please: I'm feeling unusually stupid today ...

Its the heat. I am sure this has been discussed previously on either clc
or csc. It is not explicitly stated, but C99 section 6.10.3#4 stats:

If the identifier-list in the macro definition does not end with
ellipsis, the number of arguments (including those arguments consisting
of no preprocessor tokens) in an invocation of a function ...

Which suggest that that a valid argument is an empty argument, which
means that bar() has either 0 or 1 arguments depending on how it is
declared.

Kevin Bagust.
 

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

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,125
Latest member
VinayKumar Nevatia_
Top