MACRO QUERY-3

T

Tagore

Consider following program:

#include<stdio.h>

#define NEG(a) -a
#define PR(a) printf("%d",a);

int main(void)
{
int x=5;
PR(-NEG(x)); // This statement prints 4
printf("%d",-NEG(x)) ; // This statement also prints 4
}
________

I am confused why first statement expands to --x and second expands to
- -x.
 
K

Keith Thompson

Tagore said:
Consider following program:

#include<stdio.h>

#define NEG(a) -a
#define PR(a) printf("%d",a);

int main(void)
{
int x=5;
PR(-NEG(x)); // This statement prints 4
printf("%d",-NEG(x)) ; // This statement also prints 4
}
________

I am confused why first statement expands to --x and second expands to
- -x.

Perhaps your compiler is buggy. In both cases, the macro expansion
should yield a sequence of tokens that includes two adjacent "-"
delimiters, not a single "--" token. (gcc gets this right.)
 
P

Peter Nilsson

It is often bad form to put a semicolon in a macro like that.

You mean the statement before the null statement?
Perhaps your compiler is buggy.

In what way? The standard doesn't prescribe the behaviour
for preprocessor output since the it doesn't describe a
'preprocessor'.

The is a notional mapping from Translation Phases into the
common implementation components (preprocessor, compiler and
linker), however the practicalities of those components
means the mapping has some overlaps and bluring.
 In both cases, the macro expansion should yield a sequence
of tokens that includes two adjacent "-" delimiters, not a
single "--" token.  (gcc gets this right.)

When asked to give plain text output, some preprocessors
will output source that will reparse in an equivalent manner
to the original, hence the OP might see an expansion as
'- -x' rather than '--x'.

A good test would be to stringize the source...

#include<stdio.h>

#define STR(x) #x
#define STRSTR(x) STR(x)

#define NEG(a) -a
#define PR(a) printf("%d",a);

int main(void)
{
puts(STRSTR(PR(-NEG(x))));
puts(STRSTR(printf("%d",-NEG(x))));
return 0;
}

This should print...

printf("%d",--x);
printf("%d",--x)

....even on the implementation where the preprocessor 'output'
had '- -x'.
 
K

Keith Thompson

Peter Nilsson said:
It is often bad form to put a semicolon in a macro like that.


You mean the statement before the null statement?


In what way? The standard doesn't prescribe the behaviour
for preprocessor output since the it doesn't describe a
'preprocessor'.

His comments say that both statements print 4. Using my compiler
(which happens to be gcc), both statements print 5, which I think is
what they should print. If both statements print 4, that implies that
in the first one, macro expansion generates a "--" token, and in the
second statement it generates two "-" tokens; I believe this is
incorrect behavior. (I was unclear on how I concluded that the
compiler might be buggy; I was judging it on the program's output
rather than what the preprocessor's output looks like.)

Here's a cleaned-up version of the program:

#include <stdio.h>

#define NEG(a) -a
#define PR(a) printf("%d", a)

int main(void)
{
int x = 5;
PR(-NEG(x));
putchar(' ');
printf("%d", -NEG(x));
putchar('\n');
return 0;
}

Its output should be "5 5". If the OP's compiler is behaving as he
describes, I expect its (incorrect) output to be "4 4".
The is a notional mapping from Translation Phases into the
common implementation components (preprocessor, compiler and
linker), however the practicalities of those components
means the mapping has some overlaps and bluring.


When asked to give plain text output, some preprocessors
will output source that will reparse in an equivalent manner
to the original, hence the OP might see an expansion as
'- -x' rather than '--x'.

Good point.
A good test would be to stringize the source...

#include<stdio.h>

#define STR(x) #x
#define STRSTR(x) STR(x)

#define NEG(a) -a
#define PR(a) printf("%d",a);

int main(void)
{
puts(STRSTR(PR(-NEG(x))));
puts(STRSTR(printf("%d",-NEG(x))));
return 0;
}

This should print...

printf("%d",--x);
printf("%d",--x)

...even on the implementation where the preprocessor 'output'
had '- -x'.

Using gcc 4.3.2, I get (what I think is) the correct output for both
program -- but "gcc -E" gives me "- -x" for the first program and
"--x" for the second. That seems odd, but (a) the output of "gcc -E"
is not governed by the standard, and as long as both programs produce
correct run-time output there's no real problem, and (b) I'm not going
to take the time to track down the reason for the difference.
 

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,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top