Returning value from a macro which prints some debug messages alongwith expression evaluation

  • Thread starter Srinivas Mudireddy
  • Start date
S

Srinivas Mudireddy

Hi,
I am running in to a problem and let me paraphrase it with a fake use
case.

Say, I have a macro like
#define MIN(x, y) ((x) < (y) ? (x) : (y))

Now how do I still return a value from this macro if I want to add
some debug messages? For example, I want to rewrite above macro as

#define MIN(x, y) \
{ \
if ((x) < (y)) \
{ \
printf("MIN is first arg"); \
} \
else \
{ \
printf("MIN is second arg"); \
} \
//Need something here which would return min value \
}

I could implement this macro as an inline function but we have ~15
such macros in the data path which get executed for each packet. We
are worried that performance will be impacted if compiler doesn't
actually make the functions inline.

Please let me know if there is a way to solve this problem.

Thx,
Sri
 
A

Antoninus Twink

Now how do I still return a value from this macro if I want to add
some debug messages? For example, I want to rewrite above macro as

#define MIN(x, y) \
{ \
if ((x) < (y)) \
{ \
printf("MIN is first arg"); \
} \
else \
{ \
printf("MIN is second arg"); \
} \
}

Try using the comma operator:

#define MIN(x,y) ((x) < (y) ? printf("MIN is first arg"), (x) : \
printf("MIN is second arg"), (y))
 
S

Seebs

Say, I have a macro like
#define MIN(x, y) ((x) < (y) ? (x) : (y))

Now how do I still return a value from this macro if I want to add
some debug messages? For example, I want to rewrite above macro as

Usually, this is the time to do inline functions.
#define MIN(x, y) \
{ \
if ((x) < (y)) \
{ \
printf("MIN is first arg"); \
} \
else \
{ \
printf("MIN is second arg"); \
} \
//Need something here which would return min value \
}

You really can't do this, although.

#define MIN(x, y) ((x) < (y) ? ((printf("MIN is first arg\n"), (x)) : ((printf("MIN is second arg\n"), (y)))

In short, don't try to embed statements in a macro, but do be aware that
function calls are just expressions, and the comma operator is your friend.
I could implement this macro as an inline function but we have ~15
such macros in the data path which get executed for each packet. We
are worried that performance will be impacted if compiler doesn't
actually make the functions inline.
Please let me know if there is a way to solve this problem.

Oh, come ON.

You're talking about *PRINTING DIAGNOSTICS*. The chances that the
function call overhead is going to be noticeable compared to the time
I/O takes are very small.

Here is my suggestion: Just do it with inline functions, because they
will almost certainly work and do what you want, and will be clear and
understandable. Then measure your performance. If it's not good enough,
THEN start looking at clever hacks.

But your first choice should probably be to think very hard about whether
calling printf at all is even the right choice. Consider:

extern char *queued_diagnostics[MAX_DIAGNOSTICS_PER_PACKET];
extern int queued_diagnostic_index;
/* Usenet posts want terser names than real code sometimes */
#define qd queued_diagnostics
#define qdi queued_diagnostics_index

#define MIN(x,y) ((x) < (y) ? (qd[qdi++] = "MIN: first is smaller", (x)) : (qd[qdi++] = "MIN: second is smaller", (y)))

/* now... */
MIN(2,3);
for (int i = 0; i < qdi; ++i) {
printf("%s\n", qd);
}

Now, if you do this, you have to watch out -- you can't call MIN twice without
intervening sequence points, because the qdi++ could bite you.

The rationale of something like this is that you might want to do all
your operations first, then do the output later -- or possibly in another
thread, using some kind of mutex to check on when the processing thread
is busy doing something else.

Which is to say: If you seriously need to worry about the performance
difference of inline functions, don't call printf() inside a macro, and
try bringing up your issues in a newsgroup specific to your target platform,
because the right way to do this in Windows might be very different from
the right way to do it in Unix.

-s
 
P

Peter Nilsson

Antoninus Twink said:
Try using the comma operator:

#define MIN(x,y) ((x) < (y) ? printf("MIN is first arg"), (x) : \
   printf("MIN is second arg"), (y))

The comma operator has lower precedence than the conditional
operator. Your macro will return (y) each time because it's
parsed as (<expr>, (y)).

Try...

#define MIN(x, y) \
( (x) < (y) ? puts("MIN is first arg"), (x) \
: (puts("MIN is second arg"), (y)) )
 

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
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top