473,563 Members | 2,732 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

difference inbetween macro & function

Hi,

I learned my lesson about passing pointers, but now I have a question
about macros.

Why does the function work and the MACRO which is doing the same thing
on the surface, does not work in the following small example ?

#include <stdio.h>

#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)

double percent(double a, double b) {
return ((a - b) / a) * 100.0;
}

int main(void) {

printf("%g%%\n" , percent(1000, 100));
printf("%g%%\n" , PERCENTAGE(1000 , 100));

return 0;
}

Thank you !

jason
Nov 6 '07 #1
6 2292
On 6 Nov, 17:59, jason <ji...@notmal.c omwrote:
Hi,

I learned my lesson about passing pointers, but now I have a question
about macros.

Why does the function work and the MACRO which is doing the same thing
on the surface, does not work in the following small example ?

#include <stdio.h>

#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)

double percent(double a, double b) {
return ((a - b) / a) * 100.0;

}

int main(void) {

printf("%g%%\n" , percent(1000, 100));
printf("%g%%\n" , PERCENTAGE(1000 , 100));

return 0;

}

Thank you !

jason
Well, that macro isn't the same as percent(). You have to cast to
double, e.g.:

#define PERCENTAGE(a, b) ( (a - b) / (double) a * 100 )

Nov 6 '07 #2
On Tuesday 06 Nov 2007 10:29 pm jason <ji***@notmal.c omwrote in
article <47************ **********@drea der12.news.xs4a ll.nl>:
Hi,

I learned my lesson about passing pointers, but now I have a question
about macros.

Why does the function work and the MACRO which is doing the same thing
on the surface, does not work in the following small example ?

#include <stdio.h>

#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)

double percent(double a, double b) {
return ((a - b) / a) * 100.0;
}

int main(void) {

printf("%g%%\n" , percent(1000, 100));
printf("%g%%\n" , PERCENTAGE(1000 , 100));

return 0;
}

Thank you !
Macros have no concept of types because they are processed before the
compiler proper begins. In your example the constants in the macro
invocation are treated as integers causing the division by 'a' to be
truncated to zero.

Use a decimal point on the constants to force the compiler to treat them
as double values.

PERCENTAGE(1000 .0, 100.0);
Nov 6 '07 #3
In <47************ **********@drea der12.news.xs4a ll.nljason <ji***@notmal.c omwrites:
Why does the function work and the MACRO which is doing the same thing
on the surface, does not work in the following small example ?
#include <stdio.h>
#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)
double percent(double a, double b) {
return ((a - b) / a) * 100.0;
}
int main(void) {
printf("%g%%\n" , percent(1000, 100));
printf("%g%%\n" , PERCENTAGE(1000 , 100));
return 0;
}
You're using 1000 and 100 instead of 1000.0 and 100.0 and therefore all
of the calculations except for the final multiplication are done using
integer math instead of floating-point math.

Specifically, this part of the macro:

((a - b) / a)

Will expand to this:

((1000 - 100) / 1000)

Which further simplifies to this:

900 / 1000

And since these numbers are both integers, integer math is used, which
produces a reult of zero.

--
John Gordon A is for Amy, who fell down the stairs
go****@panix.co m B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

Nov 6 '07 #4
On Tue, 06 Nov 2007 17:38:02 +0000, John Gordon wrote:
In <47************ **********@drea der12.news.xs4a ll.nljason
<ji***@notmal.c omwrites:
>Why does the function work and the MACRO which is doing the same thing
on the surface, does not work in the following small example ?
>#include <stdio.h>
>#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)
>double percent(double a, double b) {
return ((a - b) / a) * 100.0;
}
>int main(void) {
> printf("%g%%\n" , percent(1000, 100)); printf("%g%%\n" ,
PERCENTAGE(1000 , 100));
> return 0;
}

You're using 1000 and 100 instead of 1000.0 and 100.0 and therefore all
of the calculations except for the final multiplication are done using
integer math instead of floating-point math.

Specifically, this part of the macro:

((a - b) / a)

Will expand to this:

((1000 - 100) / 1000)

Which further simplifies to this:

900 / 1000

And since these numbers are both integers, integer math is used, which
produces a reult of zero.
Ah sounds logical indeed..

Thank you all, for the answers & explanations.

Jas.
Nov 6 '07 #5
jason <ji***@notmal.c omwrites:
I learned my lesson about passing pointers, but now I have a question
about macros.

Why does the function work and the MACRO which is doing the same thing
on the surface, does not work in the following small example ?

#include <stdio.h>

#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)

double percent(double a, double b) {
return ((a - b) / a) * 100.0;
}

int main(void) {

printf("%g%%\n" , percent(1000, 100));
printf("%g%%\n" , PERCENTAGE(1000 , 100));

return 0;
}
Others have explained why your macro doesn't work. I'll offer some
additional advice.

You get 100 points (on a scale of 0 to whatever the heck) for posting
a complete program that exhibits the problem, but you lose 20 points
for merely telling us that it "does not work" without explaining *how*
it doesn't work. In this case, it was easy enough to figure out the
problem, but in general you should tell us *how* it didn't work --
i.e., what output you expected, what output you got, and perhaps why
you think your expected output is right and what you got is wrong.

A good resource for this kind of thing is
<http:°www.catb .org/~esr/faqs/smart-questions.html> .

As for your macro, leaving aside the type problem, I see two other
potential issues. First, it always evaluates the first argument
twice. This isn't necessarily a problem; the all-caps name warns
users that this is a macro, and this kind of thing might happen.

Second, for a function-like macro that expands to an expression, you
should always fully parenthesize the entire expression (which you did)
*and* each occurrence of an argument (which you didn't). Specifically:

#define PERCENTAGE(a, b) ((((a) - (b)) /(a)) * 100.0)

(Note: it's not *always* strictly necessary, but I find it much easier
to be consistent than to remember the cases where it isn't.)

This doesn't matter if the arguments are simple identifiers or
constants, but imagine what happens if the arguments are more complex
subexpressions. Macro expansion knows nothing about operator
precedence; it just blindly expands each argument in place. Here's an
example of how failing to parenthesize sufficiently:

#include <stdio.h>

#define SIX 1+5
#define NINE 8+1

int main(void)
{
printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
return 0;
}

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 6 '07 #6
"jason" <ji***@notmal.c oma écrit dans le message de news:
47************* *********@dread er12.news.xs4al l.nl...
On Tue, 06 Nov 2007 17:38:02 +0000, John Gordon wrote:
>In <47************ **********@drea der12.news.xs4a ll.nljason
<ji***@notmal. comwrites:
>>Why does the function work and the MACRO which is doing the same thing
on the surface, does not work in the following small example ?
>>#include <stdio.h>
>>#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)
>>double percent(double a, double b) {
return ((a - b) / a) * 100.0;
}
>>int main(void) {
>> printf("%g%%\n" , percent(1000, 100)); printf("%g%%\n" ,
PERCENTAGE(1000 , 100));
>> return 0;
}

You're using 1000 and 100 instead of 1000.0 and 100.0 and therefore all
of the calculations except for the final multiplication are done using
integer math instead of floating-point math.

Specifically , this part of the macro:

((a - b) / a)

Will expand to this:

((1000 - 100) / 1000)

Which further simplifies to this:

900 / 1000

And since these numbers are both integers, integer math is used, which
produces a reult of zero.

Ah sounds logical indeed..
It should also be noted that macro arguments must be parenthesized in the
expansion to prevent operator precedence problems:

Your definition of PERCENTAGE will not work as expected some of the
arguments are expressions:
#define PERCENTAGE(a, b) (((a - b) / a) * 100.0)

PERCENTAGE(1 + 2, 3) will expand as

(((1 + 2 - 3) / 1 + 2) * 100.0) which evaluates to 200.0 instead of the
expected 0.0

The fix is easy:
#define PERCENTAGE(a, b) ((((a) - (b)) / (a)) * 100.0)

Also note that the initial part of the computation will be done with integer
arithmetics if both a and b are integers.
A simple fix for this is:
#define PERCENTAGE(a, b) ((((double)(a) - (b)) / (a)) * 100.0)

The expression can actually be simplified a bit because / and * are left
associative, so ``(a / b) * c'' is the same is ``a / b * c'' and the left
operand of * is already a double so 100 can be used instead of 100.0.
#define PERCENTAGE(a, b) (((double)(a) - (b)) / (a) * 100)

Finally, you notice that a is evaluated twice in the expansion of the macro.
Invoking this macro with an expression with side effects as a first argument
will not perform as expected, and may even invoke undefined behaviour:

PERCENTAGE(comp ute_total_and reset(), 100) will invoke the function
compute_total_a nd_reset twice.

The only way to fix this is to use a function instead of a macro. In c99,
this function can be declared ``inline'' as a hint for the compiler to
generate code without a function call, but this is an optimisation you
should not be concerned with at this stage.

So remember this:
1- use functions, not macros.
2- if you break rule 1, always parenthesize the macro arguments in the
expansion
3- if you break rule 1, be careful about multiple evaluation, use capitals
for the macro name to make them obvious.
4- if you break rule 1, macros are untyped, be careful how the expansion
will evaluate depending on the types of the arguments.
5- don't break rule 1

--
Chqrlie.
Nov 8 '07 #7

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

Similar topics

13
3025
by: Mattias Campe | last post by:
Hi, Depending on if I get an image or a text of a certain URL, I want to do something different. I don't know in advance whether I'll get an image or a text. This is a URL that returns an image:...
2
5720
by: Aakash Jain | last post by:
Can someone explain me the difference between the following C++ macro and the function MAX: #define MAX(a, b) (((a) > (b)) ? (a) : (b)) template <class T> const T& MAX(const T& a, const T& b) { return (a > b ? a : b); }
7
1957
by: sachin_mzn | last post by:
Hi, It may be a silly question but I want to know the difference between #define macro and inline functions Is there any performance issue related to it. -Sachin
7
23532
by: Newbie_sw2003 | last post by:
Where should I use them? I am giving you my understandings. Please correct me if I am wrong: MACRO: e.g.:#define ref-name 99 The code is substituted by the MACRO ref-name. So no overhead. Execution is faster. Where will it be stotred?(Is it in bss/stack/?) FUNCTION:
4
4962
by: Thomas Matthews | last post by:
Hi, I have several translation units (modules) which contain static {local} variables. These function have short global accessor functions. I would like to change these functions into macros, but still preserve the data hiding issue. How do I construct a macro to access static {local} variables in a module? The macro will be in a header...
8
10852
by: lasek | last post by:
Hi...in some posts i've read...something about using macro rather then function...but difference ??. Best regards....
23
1891
by: yezi | last post by:
Hi, all: The 1st sendtence: int main(){ char string={""}; string = {" connected "}; ..... }
21
2293
by: MAx | last post by:
Hi, Could any one list possible number of diferences between a function and a macro? which one will be faster and why?? ex : function and a macro ti find max of two nums #define MAX(a,b) (a>b) ? a:b and int max(int a,int b)
11
5119
by: sunnyalways4u2000 | last post by:
hello sir, Sir will please tell me the exact difference between C and advanced C...what are the extra features or funcions...etc added in this advanced one.
0
7664
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...
0
7583
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...
0
8106
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
6250
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...
1
5484
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...
0
5213
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...
0
3626
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1198
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
923
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.