Strange MACRO Problem

K

Karim Thapa

Why following macro does not work?

#define removebrace(x) x

void Foo(int a, int b, char *txt, int d, int e);

main()
{


...
Foo(1, 2, removebrace(("hello", 5, 6)) );

...


}

I expected following expansion by compiler.

Foo(1, 2, "hello", 5, 6);

But it didnt work. When I see disassembly, only 3 arguments are pushed
into the stack, pointer to string "hello", value 2 and value 1 before
calling function 'Foo', instead of all 5 arguments.

However, if I do not use macro 'removebrace', all five arguments get
pushed to the stack before calling function 'Foo', and it works fine.

Any help, why MACRO removebrace does not work. I use MSVC 6.

Interestingly, this macro works fine in following statement

p = q * removebrace(a+b)

which results in

p = (q*a) + b

Karim

My previous post appeared to be lost so posting it again. Excuse me if
you receive two copy
 
A

Arthur J. O'Dwyer

Why following macro does not work?

#define removebrace(x) x

In other words, 'removebrace' is almost -- but not quite -- a no-op.
In particular, assuming 'foo' is not a #defined identifier,

removebrace(foo) ==> foo

for all 'foo'.
void Foo(int a, int b, char *txt, int d, int e);

main()
{
..
Foo(1, 2, removebrace(("hello", 5, 6)) );

Since removebrace(("hello", 5, 6)) expands to ("hello, 5, 6), this
whole line expands to

Foo(1, 2, ("hello", 5, 6) );

This doesn't match the prototype, so the compiler should give you
a diagnostic error message.
I expected following expansion by compiler.

Foo(1, 2, "hello", 5, 6);

Why on earth would you expect *that*?
But it didnt work. When I see disassembly, only 3 arguments are pushed
into the stack, pointer to string "hello", value 2 and value 1 before
calling function 'Foo', instead of all 5 arguments.

That's because your compiler has adequate constant-expression
optimization. It knows that since "hello" and 5 have no side-effects,
they can be simply discarded.
However, if I do not use macro 'removebrace'
[and remove both pairs of the extra parentheses]
, all five arguments get
pushed to the stack before calling function 'Foo', and it works fine.

Naturally.
Any help, why MACRO removebrace does not work. I use MSVC 6.

It does work. It replaces removebrace(x) by x.
Interestingly, this macro works fine in following statement

p = q * removebrace(a+b)

which results in

p = (q*a) + b

No, it results in

p = q * a+b

which has the same effect; but you've inserted a pair of
parentheses where they don't belong.

There is no C macro 'foo' such that 'foo((bar))' replaces to 'bar'
in general for all text 'bar', if that's what you're looking for.
What are you *really* trying to do, and why?

-Arthur
 
V

Vijay Kumar R Zanvar

Karim Thapa said:
Why following macro does not work?

#define removebrace(x) x

void Foo(int a, int b, char *txt, int d, int e);

main()
{


..
Foo(1, 2, removebrace(("hello", 5, 6)) );

This is equivalent to:

Foo ( 1,2, ("hello", 5, 6 ) );

which in turn is equivalent to:

Foo (1, 2, 6 );

Since the signature of Foo says expect 5 arguments, this one
will generate an error. Know/read about comma operator.

[..]
Any help, why MACRO removebrace does not work. I use MSVC 6.

This hasn't got anyting to do with MSVC 6.

Your problem solves if you replace

Foo(1, 2, removebrace(("hello", 5, 6)) );

with

Foo(1, 2, removebrace("hello", 5, 6) );

[..]
 
C

Christian Bau

"Vijay Kumar R Zanvar said:
Karim Thapa said:
Why following macro does not work?

#define removebrace(x) x

void Foo(int a, int b, char *txt, int d, int e);

main()
{


..
Foo(1, 2, removebrace(("hello", 5, 6)) );

This is equivalent to:

Foo ( 1,2, ("hello", 5, 6 ) );

which in turn is equivalent to:

Foo (1, 2, 6 );

Since the signature of Foo says expect 5 arguments, this one
will generate an error. Know/read about comma operator.

[..]
Any help, why MACRO removebrace does not work. I use MSVC 6.

This hasn't got anyting to do with MSVC 6.

Your problem solves if you replace

Foo(1, 2, removebrace(("hello", 5, 6)) );

with

Foo(1, 2, removebrace("hello", 5, 6) );

Most likely not, because now you are passing three arguments to a macro
that only expects one.
 
M

Martin Ambuhl

Karim said:
Why following macro does not work?

#define removebrace(x) x

void Foo(int a, int b, char *txt, int d, int e);

main()
{
Foo(1, 2, removebrace(("hello", 5, 6)) );
}

This snippet, BTW, is self-contradictory. Using implict int for the
retutn type of main is OK in C89 but not C99; leaving off the return value
is OK in C99 (where there is an implicit "return 0;") but not in C89.
I expected following expansion by compiler.

Foo(1, 2, "hello", 5, 6);

But it didnt work. When I see disassembly, only 3 arguments are pushed
into the stack, pointer to string "hello", value 2 and value 1 before
calling function 'Foo', instead of all 5 arguments.

All is as it should be. `x' is ("hello",5,6), not "hello",5,6.
Any help, why MACRO removebrace does not work. I use MSVC 6.

It works as it should.
Interestingly, this macro works fine in following statement

p = q * removebrace(a+b)

which results in

p = (q*a) + b

No braces were there to be removed by removebace in your example above.
The parallel case is:
#define removebrace(x) x
int main(void)
{
int a = 1, b = 2, c = 3;
c = c * removebrace((a + b));
return 0;
}

expanding to:

int main()
{
int a = 1, b = 2, c = 3;
c = c * (a + b);
return 0;
}
 
V

Vijay Kumar R Zanvar

[..]
Most likely not, because now you are passing three arguments to a macro
that only expects one.

True. I am committed to do one mistake per posting!! :))

Thanks.
 
K

Karim Thapa

Sorry, I made mistake while posting, it is actually

Foo(1, 2, removebrace("hello", 5, 6) );


Can some one explain now why macro removebrace does not
work as expected ?

I expected following expansion by compiler.

Foo(1, 2, "hello", 5, 6);

But it didnt work. When I see disassembly, only 3 arguments are pushed
into the stack, pointer to string "hello", value 1 and 2 before
calling function 'Foo', instead of all 5 arguments.

However, if I do not use macro 'removebrace', all five arguments get
pushed to the stack before calling function 'Foo'

Any help, why MACRO removebrace does not work. I use MSVC 6.

Karim

Arthur J. O'Dwyer said:
Why following macro does not work?

#define removebrace(x) x

In other words, 'removebrace' is almost -- but not quite -- a no-op.
In particular, assuming 'foo' is not a #defined identifier,

removebrace(foo) ==> foo

for all 'foo'.
void Foo(int a, int b, char *txt, int d, int e);

main()
{
..
Foo(1, 2, removebrace(("hello", 5, 6)) );

Since removebrace(("hello", 5, 6)) expands to ("hello, 5, 6), this
whole line expands to

Foo(1, 2, ("hello", 5, 6) );

This doesn't match the prototype, so the compiler should give you
a diagnostic error message.
I expected following expansion by compiler.

Foo(1, 2, "hello", 5, 6);

Why on earth would you expect *that*?
But it didnt work. When I see disassembly, only 3 arguments are pushed
into the stack, pointer to string "hello", value 2 and value 1 before
calling function 'Foo', instead of all 5 arguments.

That's because your compiler has adequate constant-expression
optimization. It knows that since "hello" and 5 have no side-effects,
they can be simply discarded.
However, if I do not use macro 'removebrace'
[and remove both pairs of the extra parentheses]
, all five arguments get
pushed to the stack before calling function 'Foo', and it works fine.
Naturally.

Any help, why MACRO removebrace does not work. I use MSVC 6.

It does work. It replaces removebrace(x) by x.
Interestingly, this macro works fine in following statement

p = q * removebrace(a+b)

which results in

p = (q*a) + b

No, it results in

p = q * a+b

which has the same effect; but you've inserted a pair of
parentheses where they don't belong.

There is no C macro 'foo' such that 'foo((bar))' replaces to 'bar'
in general for all text 'bar', if that's what you're looking for.
What are you *really* trying to do, and why?

-Arthur
 
D

daizisheng

Arthur J. O'Dwyer said:
On Mon, 18 Jan 2004, Karim Thapa wrote: ....
Foo(1, 2, ("hello", 5, 6) );

This doesn't match the prototype, so the compiler should give you
a diagnostic error message.


Why on earth would you expect *that*?
^^^^^^^^^^^^^^^^
it is strange,here.
the value of the expression ("hello",5,6) is 6,not "hello"??
i think value 6 would be pushed,not "hello".
calling function 'Foo', instead of all 5 arguments.

That's because your compiler has adequate constant-expression
optimization. It knows that since "hello" and 5 have no side-effects,
they can be simply discarded.
However, if I do not use macro 'removebrace'
[and remove both pairs of the extra parentheses]
....
 
M

Martin Ambuhl

Karim said:
Sorry, I made mistake while posting, it is actually

Foo(1, 2, removebrace("hello", 5, 6) );


Can some one explain now why macro removebrace does not
work as expected ?

Because you gave it 3 arguments and it only takes 1:
[...]
You should have gotten a compiler diagnostic. If you did not, turn the
warnings back on.
 
M

Martin Ambuhl

Vijay Kumar R Zanvar wrote:

Your problem solves if you replace

Foo(1, 2, removebrace(("hello", 5, 6)) );
with
Foo(1, 2, removebrace("hello", 5, 6) );

Since when does supplying 3 arguments to a macro taking only one solve
anyone's problems?
 
K

Karim Thapa

Most likely not, because now you are passing three arguments to a macro
that only expects one.

God! While doing something complex, I missed this silly point.

I have new problem now. I will post a new thread.

Thanks - Karim
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top