Page 1 of 1

#define

Posted: Tue Nov 06, 2007 9:30 pm
by Zacariaz
i was wondering if anyone would care to take a minute or two explaining a little tiny thing for me.

Code: Select all

#define AND(a, b) (a&b)
// vs.
bool AND(bool a, bool b) {
    return (a&b);
}
besides no input and returntype when using #define, what is the real difference really?

I realize this is something i should know, but well... i dont.

Regards

Posted: Tue Nov 06, 2007 9:34 pm
by JackScott
You'll find that if you pass a complex expression ( for instance '2-1') to the #define, you'll get interesting results.

Code: Select all

#define AND(a,b) ((a)&(b))
is a better way to write it.

To answer your question, apart from that, there is only one crucial difference. The function is stored in the binary and called, whereas the definition will be replaced at compile time. For things like this, where function < function overhead, it's better to go either the inline route, or use a #define like you did.

Posted: Tue Nov 06, 2007 10:09 pm
by Alboin
Yayyak wrote:overhead, it's better to go either the inline route
IIRC, most good compilers do inline automatically during those situations.

Posted: Tue Nov 06, 2007 10:32 pm
by Zacariaz
I think i get it, thanks for the explanation.

Posted: Tue Nov 06, 2007 11:17 pm
by Solar
Some more:

You cannot take the address of the macro, i.e. you cannot pass it's function pointer to some other function.

Inlining of the function by the compiler only works when the function is defined in the translation unit, i.e. if the compiler sees only the function declaration (e.g. in some "utils.h"), it cannot inline it.

The user can undefine the macro.

The macro "vanishes" in the binary, i.e. when you're debugging the code, you don't see AND anymore, but only the expanded code.

Posted: Wed Nov 07, 2007 12:58 am
by AndrewAPrice
Playing with defines can be fun. You can set up your header files so each time they're included a different set on functions are included.

If you have one main header file which includes multiple header files, it may take a while to compile each of the source files which includes the main header. In this case you could set up a system where by you use "define" which parts you would not like included.

Posted: Wed Nov 07, 2007 1:01 am
by Candy
MessiahAndrw wrote:If you have one main header file which includes multiple header files, it may take a while to compile each of the source files which includes the main header. In this case you could set up a system where by you use "define" which parts you would not like included.
How about, not including a main header file to begin with?

Posted: Thu Nov 08, 2007 8:04 pm
by TomTom

Code: Select all

static __inline int do_something(int a, int b)
{
    return a + (a / b);
}
vs.

Code: Select all

#define do_something(a,b) (a + (a / b))
now let's make up some code that uses do_something like a function:

Code: Select all

int get_a(void)
{
    printf("get_a()\n");
    return 5;
}

int get_b(void)
{
    printf("get_b()\n");
    return 2;
}

int main(void)
{
    printf("do_something() == %d\n", do_something(get_a(), get_b());
    return 0;
}
If you run the code you're going to get different results. Use function-like macros carefully. Also, inlined function enable the compiler to perform type checks.

Posted: Thu Nov 08, 2007 8:21 pm
by Alboin
Hables en Inglés, por favor. :)

[edit] If you want to comment on this sentence, please do it here [/edit]

Posted: Thu Nov 08, 2007 10:08 pm
by TomTom
oops, for some reason I thought this was a German forum at the time I wrote the reply...