Ben said:
Some tasks can only be accomplished with a macro. Otherwise, use
a function: in general, they're safer.
An example:
I have in some of my programs a lot of pointers to structs.
struct a
{
char *s1;
char *s2
} *b;
char *s;
A general problem then is that such a pointer might be NULL and
therefore referencing a member of that struct is illegal.
s=b->s1; /*if b is NULL this doesn't work well...*/
Now if what I want is something like this:
if (b)
s=b->s1;
else
s=NULL;
That is I want to assign *something* to s, if b is NULL (or for that
matter b->s1 is NULL) I do want s to be NULL too. This could be written:
s=b?b->s1:NULL;
That's OK, so know if b isn't really a variable but rather a long
complex expression I need to type that twice to get the desired effect.
#define spt(ptr)(!(ptr))?NULL

tr
would make it possible to write
s=spt(b)->s1;
That trick is *not* possible with a function!
Oh, and before someone points it out, it is not entirely safe either, an
expression in the place of b with side effects would not do what is
intended! But it have helped me write some shorter and more (IMO)
readable code. The expression b is evaluated twice if it is non-NULL,
but as long as it doesn't have side effects and there is no speed
requirements or the compiler is good enough at optimizing that doesn't
matter.
It is even possible to chain them like this (obviously with some other
declarations necessary)
res=spt(spt(spt(ptr)->member)->member)->member;
This allows for every step to be NULL and expands to (line breaks
inserted for readability):
res=(!((!((!(ptr))?NULL

tr->member))?NULL

!(ptr))?NULL:
ptr->member->member))?NULL

!((!(ptr))?NULL

tr->member))?NULL:
(!(ptr))?NULL

tr->member->member->member;
and doing exactly what I want but much more readable with the macro
than without. Of course typing
if (ptr)
{
if (ptr->member)
{
if (ptr->member->member)
res=ptr->member->member->member;
else
res=NULL;
}
else
res=NULL;
}
else
res=NULL;
would also produce the same result but would not (again IMO) be as readable.
Oh, once again, don't try this at home unless you understand the
restriction "expression *must* be without side effects"