473,657 Members | 2,727 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Strange MACRO Problem

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(("h ello", 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
Nov 14 '05 #1
10 2418

On Mon, 18 Jan 2004, Karim Thapa wrote:

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(("h ello", 5, 6)) );
Since removebrace(("h ello", 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
Nov 14 '05 #2

"Karim Thapa" <ka********@yah oo.com> wrote in message
news:cd******** *************** ***@posting.goo gle.com...
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(("h ello", 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(("h ello", 5, 6)) );

with

Foo(1, 2, removebrace("he llo", 5, 6) );

[..]

--
Vijay Kumar R Zanvar
My Home Page - http://www.geocities.com/vijoeyz/
Nov 14 '05 #3
In article <bu************ @ID-203837.news.uni-berlin.de>,
"Vijay Kumar R Zanvar" <vi*****@hotpop .com> wrote:
"Karim Thapa" <ka********@yah oo.com> wrote in message
news:cd******** *************** ***@posting.goo gle.com...
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(("h ello", 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(("h ello", 5, 6)) );

with

Foo(1, 2, removebrace("he llo", 5, 6) );


Most likely not, because now you are passing three arguments to a macro
that only expects one.
Nov 14 '05 #4
Karim Thapa wrote:
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(("h ello", 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;
}


--
Martin Ambuhl
Nov 14 '05 #5
[..]

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

Your problem solves if you replace

Foo(1, 2, removebrace(("h ello", 5, 6)) );

with

Foo(1, 2, removebrace("he llo", 5, 6) );


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.

--
vijay-z
Nov 14 '05 #6
Sorry, I made mistake while posting, it is actually

Foo(1, 2, removebrace("he llo", 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" <aj*@nospam.and rew.cmu.edu> wrote in message news:<Pi******* *************** *************@u nix42.andrew.cm u.edu>...
On Mon, 18 Jan 2004, Karim Thapa wrote:

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(("h ello", 5, 6)) );


Since removebrace(("h ello", 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

Nov 14 '05 #7
"Arthur J. O'Dwyer" <aj*@nospam.and rew.cmu.edu> wrote in message news:<Pi******* *************** *************@u nix42.andrew.cm u.edu>...
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.
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 ^^^^^^^^^^^^^^^ ^
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]

....
Nov 14 '05 #8
Karim Thapa wrote:
Sorry, I made mistake while posting, it is actually

Foo(1, 2, removebrace("he llo", 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:
[...]
#define removebrace(x) x


You should have gotten a compiler diagnostic. If you did not, turn the
warnings back on.
--
Martin Ambuhl
Nov 14 '05 #9
Vijay Kumar R Zanvar wrote:

#define removebrace(x) x
Your problem solves if you replace

Foo(1, 2, removebrace(("h ello", 5, 6)) );
with
Foo(1, 2, removebrace("he llo", 5, 6) );


Since when does supplying 3 arguments to a macro taking only one solve
anyone's problems?
--
Martin Ambuhl
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
1479
by: Dave | last post by:
Hello all, Here is the definition I'm using of a static const class member: template<typename T, typename U> const U directed_graph_t<T, U>::INFINITY = ( std::numeric_limits<U>::has_infinity ? std::numeric_limits<U>::infinity() : std::numeric_limits<U>::max()
2
1553
by: Tony Ciconte | last post by:
We have developed an Acc97 application and distribute it using the Wise installation system and SageKey scripts. The installations are rock solid and the product works well on all types of systems. However, we have notice a peculiar issue when running on either Windows 2000 or Windows XP systems. Specifically, the application uses the OutLook libraries to move information back and forth to MS OutLook. We check references when the...
26
2163
by: GS | last post by:
I am doing my first real embedded programming project and the supplied device libraries have a function definition that looks like this: void FCN(void) = { INTDEF, INTABS, (unsigned short) PTRDEF}; where INTDEF = some #defined integer INTABS = some absolute integer (e.g. 2) PTRDEF = some #defined pointer
1
1484
by: Shrishail Rana | last post by:
Hello all, Here's another mind puzzle from me :-) Today I tried to add a new resource to my program and VS.NET (v 7.0.9466) just died. What I mean by that is that it silently and quickly (immediately actually) closed its window. No errors, no access faults - nothing. Just died. I restarted it, tried to add a resource again and it repeated itself. I rebooted the computer (which I haven't done in a few weeks now), but it doesn't help...
5
1730
by: cmiddlebrook | last post by:
Greetings all, I have a class which contains a function with the following signature: MC_SDLImage* LoadImage(const std::string& file, int id); and I call this function in two places in my code. For one of the calls I am getting an unresolved external but it refers to the function as "LoadImageA", notice the capital A on the end. Usually I can fix linker errors pretty quickly but this one stumped me. In the end I tried
11
5439
by: vj | last post by:
Hello group, I am working on a compression tool and saw this puzzling bit shit behaviour on a VC++6.0 compiler. #include <iostream> using namespace std; typedef unsigned char uchar; #define NBITS(x) ((uchar)(~0u<<sizeof(0u)*8-(x) >>sizeof(0u)*8-(x))) // NBITS forms a byte containing specified number of bits turned on.
9
1943
by: Me | last post by:
Hi, I ran into a malloc problem but I can't find the solution. I try to read a file into a variable with malloc like this: BYTE *lcdata; lcdata = malloc(fsize*sizeof(BYTE));
0
1420
by: mmcd79 | last post by:
I'm wondering if anyone else is having this issue. It's driving me batty. It seems my mouse wants to "double click" on items when I'm just doing a single click. I thought it was the mouse so I swapped it out for another. Same thing happening with the new mouse. As I would highlight controls on a form in order to get the properties window, at frequent random times, the code behind would open with an method for the default event for...
20
366
by: dis_is_eagle | last post by:
Hi.I could not understand the output of the following program. #define swap(a,b) temp=a; a=b; b=temp; int main( ) { int i, j, temp; i=5; j=10; temp=0; if( i j)
0
8394
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8306
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8825
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
7327
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6164
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5632
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4152
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2726
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1955
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.