MACRO QUERY

T

Tagore

# include<stdio.h>

#define NEG(a) -a

void main()
{
int x=1;

printf("%d",--1); //statement-1--This is compile time error.

printf("%d",-NEG(x)); //statement-2--It works and prints out 1
}

In statement-1 expectedly I am getting a compile time error as it is
trying to apply a decrement on a constant.

but in statement-2, I am not getting compiled error and gets result as
1.
I thought macro would expand as --1 and give an error.
Why is this anomaly in second statement?
 
J

John Bode

# include<stdio.h>

#define NEG(a) -a

Might be safer as

#define NEG(a) -(a)

void main()

int main(void), please.
{
      int x=1;

      printf("%d",--1);    //statement-1--This is compile time error.

      printf("%d",-NEG(x)); //statement-2--It works and prints out 1

}

In statement-1 expectedly I am getting a compile time error as it is
trying to apply a decrement on a constant.

but in statement-2, I am not getting compiled error and gets result as
1.
I thought macro would expand as --1 and give an error.
Why is this anomaly in second statement?

-NEG(x) expands to --x, not --1.
 
K

Keith Thompson

Tagore said:
# include<stdio.h>

#define NEG(a) -a

A better way to write this would be:
#define NEG(a) (-(a))
But of course you're asking about potential problems caused by the
definition without parentheses.
void main()

This should be
int main(void)
And since you're calling printf, you need
#include said:
{
int x=1;

printf("%d",--1); //statement-1--This is compile time error.

Right. "--" is a unary operator that can't be applied to a constant.
printf("%d",-NEG(x)); //statement-2--It works and prints out 1
}

In statement-1 expectedly I am getting a compile time error as it is
trying to apply a decrement on a constant.

but in statement-2, I am not getting compiled error and gets result as
1.
I thought macro would expand as --1 and give an error.
Why is this anomaly in second statement?

It's not really an anomaly. Macro expansion works on tokens. Unless
you use the "##" token-pasting operator, a macro expansion will never
combine two tokens into one. In effect, it will insert spaces where
necessary to avoid this. So, given your definition:
prinf("%d",-NEG(x));
will expand to:
printf("%d",- -x);
which is perfectly legal.

Most compilers have an option to show the output of the preprocessing
phase. "-E" is typical, at least for Unix compilers.
 
K

Keith Thompson

John Bode said:
Might be safer as

#define NEG(a) -(a)

Usually, when defining a function-like macro, each argument reference
*and* the entire definition should be enclosed in parentheses.
Otherwise, operator precedence can cause parts of the macro expansion
to be incorrectly associated with other parts of the containing
expression. In this case, given either of the above definitions,
this:
2 NEG(1)
is a valid expression, "2 -(1)" or "2 - 1". Defining it as:
#define NEG(a) (-(a))
causes it to be a syntax error, which is what you want.

[...]
      int x=1;

      printf("%d",--1);    //statement-1--This is compile time error.

      printf("%d",-NEG(x)); //statement-2--It works and prints out 1
[...]

-NEG(x) expands to --x, not --1.

No, -NEG(x) expands to - - x. Try this:
printf("%d",-NEG(1));
 
L

lawrence.jones

Han from China - Master Troll said:
I have been able to get the latest version of gcc to exhibit
inconsistent behavior in this respect, sometimes including the
space as part of function-like macro replacement and sometimes
not.

That's because the standard defines macro replacement in terms of
tokens, not source characters, and there are situations where it is
simply not possible to write an equivalent sequence of source characters
that behave the same as a macro expansion in all contexts. For example,
given:

#define NEG(x) -x

The text ``-NEG(-1)'' must expand to the tokens ``-'' ``-'' and ``1'',
but if the replacement text is stringized, it must expand to the string
"--1". GCC, like most compilers that support a text output from the
preprocessor, tries to do the best job it can, but "best" is a value
judgement that reasonable people can differ over.
 
C

CBFalconer

Obnoxious said:
John Bode wrote:
.... snip ...


Surely, if -NEG(x) expanded to --x, then he wouldn't get 1
printed, since --x equals 0.

Did you ever hear of a decrement operator?
 
C

CBFalconer

Keith said:
.... snip ...


No, -NEG(x) expands to - - x. Try this:
printf("%d",-NEG(1));

You're right, and I'm wrong. The reason is that expansion is via
tokens, and all tokens are separated by at least on blank during
the expansion.
 
H

Huibert Bol

Keith said:
John Bode said:
Might be safer as

#define NEG(a) -(a)

Usually, when defining a function-like macro, each argument reference
*and* the entire definition should be enclosed in parentheses.
Otherwise, operator precedence can cause parts of the macro expansion
to be incorrectly associated with other parts of the containing
expression. In this case, given either of the above definitions,
this:
2 NEG(1)
is a valid expression, "2 -(1)" or "2 - 1". Defining it as:
#define NEG(a) (-(a))
causes it to be a syntax error, which is what you want.

[...]
int x=1;

printf("%d",--1); //statement-1--This is compile time error.

printf("%d",-NEG(x)); //statement-2--It works and prints out 1
[...]

-NEG(x) expands to --x, not --1.

No, -NEG(x) expands to - - x. Try this:
printf("%d",-NEG(1));

It's slightly more correct to say that -NEG(x) expands to --x, but that
the two minus signs are separate tokens. For example, the following
program should print "--x", and not "- -x".

#define NEG(a) -a

#define XSTR(x) #x
#define STR(x) XSTR(x)

#include <stdio.h>

int
main(void)
{
puts(STR(-NEG(x)));
}
 

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,774
Messages
2,569,596
Members
45,141
Latest member
BlissKeto
Top