Macros

H

Harry

Hi all,Nice Day to you


I have a piece of code as

# define prod(a,b)=a*b
main()
{
int x=2;
int y=3;
printf("%d",prod(x+2,y-10));
}

will the macro be evaluated as (2+2)*(3-10)=4* -7 =-28.

I executed this code,but this o/p is not coming.
What is the reason?

Is it that expressions should not be passed as arguments to macro
functions...

can anyone help me out...

thanks in advance.
 
R

raxitsheth2000

1. will throw comile error,
why ?

2. macro will not add any '(' or ')' macro will blindly replace the
string.
x+2 * y- 10
= x + (2*Y) -10
=...do it urself



--raxit sheth
 
W

Walter Roberson

Harry said:
I have a piece of code as
# define prod(a,b)=a*b
main()
{
int x=2;
int y=3;
printf("%d",prod(x+2,y-10));
}
will the macro be evaluated as (2+2)*(3-10)=4* -7 =-28.

No, each dummy argument will be *textually* dropped into place exactly
as specified. Thus, your line would expand to

printf("%d",x+2*y-10);

This is why you very often see () in macros, such as

# define prod(a,b) ((a)*(b))


Some comments:

- don't use = in the macro definition
- remember to include stdio.h
- look in the FAQ for information about why you want to use a different
way of declaring main
- try adding a \n after the %d or else you might not get -any- output
- notice that when I defined prod(a,b) I enclosed the (a)*(b) in ().
That's because whatever is textually right next to prod(a,b) might happen
to have a higher compilation priority.
- return a value from main. You omitted the 'int' qualifier of
return type, which is not legal in C99, so you cannot take advantage
of the C99 requirement that not returning anything be equivilent
to returning 0; hence you must return something yourself.
 
M

Martin Ambuhl

Harry said:
Hi all,Nice Day to you


I have a piece of code as

# define prod(a,b)=a*b
main()
{
int x=2;
int y=3;
printf("%d",prod(x+2,y-10));
}

will the macro be evaluated as (2+2)*(3-10)=4* -7 =-28.

Obviously not, since macro expansion is just text replacement.
[Also obviously not because of the spurious '=' in the macro definition.
Please post your real code next time.]
prod(x+2,y-10) is expanded to
x+2 * y-10
which is the same as
x + 2*y - 10 = 2 + 2*3 - 10 = 2 + 6 - 10 = -2
I executed this code,but this o/p is not coming.
What is the reason?

Because you forgot to parenthesize your macro properly. Any basic
textbook should have this information (if you bothered to read it). The
macro should be
#define prod(a,b) ((a)*(b))
or better, use an inline function:
inline int prod(int a, int b) { return a*b; }
Is it that expressions should not be passed as arguments to macro
functions...

No, but write your macros correctly. The biggest gotcha with
expressions is that they may be evaluated more than once, possibly with
nasty unforeseen consequences. The prototypical case is
#define prod(a,b) ((a)*(b))
{
int a = 2, b;
/* ... */
b = prod(a++,a++);
/* ... */
}

Please try consulting your elementary textbook at some point in learning C.
 
S

santosh

Harry said:
Hi all,Nice Day to you

I have a piece of code as

# define prod(a,b)=a*b

What's the = doing here?
main()
{
int x=2;
int y=3;
printf("%d",prod(x+2,y-10));
}

will the macro be evaluated as (2+2)*(3-10)=4* -7 =-28.

The macro will be expanded during preprocessing. The actual evaluation
of the remnants of the expansion takes place later.

In the above code, prod(x+2, y-10) will be expanded to x+2*y-10 then to
2+2*3-10. Now the * operator has a higher precedence than +, so the
expression becomes 2 + 6 - 10 and finally -2.
I executed this code,but this o/p is not coming.
What is the reason?

When writing macros always use parenthesis unless you're sure about
it's use.
To do what you probably expect change the macro definition to:
#define prod(a,b) ((a) * (b))
 
P

Peter Shaggy Haywood

Groovy hepcat Walter Roberson was jivin' on Tue, 28 Nov 2006 07:57:39
+0000 (UTC) in comp.lang.c.
Re: Macros's a cool scene! Dig it!
No, each dummy argument will be *textually* dropped into place exactly
as specified. Thus, your line would expand to

printf("%d",x+2*y-10);

No, it would expand to this:

printf("%d",=x+2*y-10);

which is a syntax error.
- don't use = in the macro definition

Exactly.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
H

Harry

Peter said:
Groovy hepcat Walter Roberson was jivin' on Tue, 28 Nov 2006 07:57:39
+0000 (UTC) in comp.lang.c.
Re: Macros's a cool scene! Dig it!


No, it would expand to this:

printf("%d",=x+2*y-10);

which is a syntax error.


Exactly.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?



Sorry guys,that = is not present in the maro expansion.It was my
mistake & thanks for clearing the doubt.
 
J

John Bode

Harry said:
Hi all,Nice Day to you


I have a piece of code as

# define prod(a,b)=a*b

Macro definitions do not use the '=' operator; in this case, it will
cause a syntax error when the macro is expanded. You want to rewrite
this as

#define prod(a,b) (a)*(b)
main()
{
int x=2;
int y=3;
printf("%d",prod(x+2,y-10));
}

will the macro be evaluated as (2+2)*(3-10)=4* -7 =-28.

As you have written it, the macro will expand to =x+2*y-10, which will
result in a syntax error. Even if you didn't have the extraneous '='
in the expansion, you'll get bitten by precedence rules, since x+2*y-10
evaluates as x+(2*y)-10. That's why you should define the macro as

#define prod(a,b) (a)*(b)

Written this way, prod(x+2,y-10) will expand to (x+2)*(y-10), which is
what you want.
I executed this code,but this o/p is not coming.
What is the reason?

You don't have a newline in your format string, so the output isn't
being flushed immediately. Either add the newline to the format
string, or add an fflush() statement after the printf:

printf("%d\n", prod(x+2,y-10));

or

printf("%d", prod(x+2,y-10));
fflush(stdout);
Is it that expressions should not be passed as arguments to macro
functions...

You can, you just need to put parens around each argument to avoid
precedence issues.

You do need to be careful if the expression involves side effects (such
as using the autoincrement or autodecrement operator); for example, if
you have the macro definition

#define square(x) (x)*(x)

and you call it as

y = square(a++);

you'll invoke undefined behavior.
 
W

Walter Roberson

John Bode said:
Harry wrote:
You want to rewrite
this as
#define prod(a,b) (a)*(b)

double x = 3.14159;
int half = (int) prod(0.5,x);

With your #define, this would expand to (int)(0.5)*(x)
which is ((int)0)*(x) which will become ((double)(int)0)*(x) by
promotion, which will become (double)0 after the mutiplication,
and then the (double) will be implicitly cast to int for the assignment.

If, though, you had used #define prod(a,b) ((a)*(b)) then
(int)((0.5)*(x)) which would do the multiplication as a double,
take the 1.57<whatever> result and explicitly cast that to int, yielding
1 in this example, which would then be assigned into half.

I would suggest to you that most people would find it unacceptably
surprising that prod(0.5,x) can produce different results depending
on what happens to be before the prod() invocation. The principle
of Least Surprise would thus suggest that your suggested #define
is not the best one.
 
K

Keith Thompson

Harry said:
Peter "Shaggy" Haywood wrote: [...][snip]
No, it would expand to this:

printf("%d",=x+2*y-10);

which is a syntax error.
[snip]

Sorry guys,that = is not present in the maro expansion.It was my
mistake & thanks for clearing the doubt.

The way to avoid that kind of mistake is to post the *exact* code that
you actually fed to your compiler. Copy-and-paste it, don't try to
re-type it. If you re-type it, you will inevitably introduce
irrelevant errors, and we won't be able to resist the temptation to
discuss them at great length. If you're lucky, we *might* eventually
get back to your actual problem.

Also, it's usually not necessary to quote the entire article to which
you're replying. Just quote enough so that your followup makes sense
on its own; trim anything that's not relevant, as I've done here. In
particular, don't quote signatures unless you're actually commenting
on them.
 
K

Keith Thompson

Frederick Gotham said:
Harry:

#define PROD(a,b) ((a)*(b))

This macro will fail if either "a" or "b" contain a comma.

Only if the comma (presumably a comma operator) is at the top level of
the argument expression -- but such an expression can't be used
directly as a function argument either. You just have to parenthesize
the argument. For example:

#include <stdio.h>

#define PROD(a,b) ((a)*(b))

int main(void)
{
printf("PROD((1,2), (3,4)) = %d\n",
PROD((1,2), (3,4)));
return 0;
}

If I had written PROD(1,2, 3,4), the compiler would have no way of
knowing which comma does what.

That's why the grammar for a function call requires each argument to
be an "assignment-expression", not a more general "expression".
 
O

onkar

I think it will throw compile error - parse error (to be more precise)
printf will be expanded as

printf("%d",=x+2*y-10);

regards,
Onkar Mahajan
 
K

Keith Thompson

onkar said:
I think it will throw compile error - parse error (to be more precise)
printf will be expanded as

printf("%d",=x+2*y-10);
[...]

Please don't top-post. Read the following:

http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

I suggest reading other responses before posting your own. News
servers don't necessarily receive all articles in the same order, but
several people have already pointed out this error, and the original
poster has already acknowledged it and been advised on how to avoid
such errors in the future.
 
J

John Bode

Walter said:
[snip]

If, though, you had used #define prod(a,b) ((a)*(b)) then
(int)((0.5)*(x)) which would do the multiplication as a double,
take the 1.57<whatever> result and explicitly cast that to int, yielding
1 in this example, which would then be assigned into half.

You're right, of course. I should know better by now; my only excuse
was that I was tossing that off while waiting for a build to finish,
and didn't take time to really think it through.
 

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

No members online now.

Forum statistics

Threads
474,076
Messages
2,570,565
Members
47,200
Latest member
Vanessa98N

Latest Threads

Top