Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using and returning output in C macro

Tags:

I'm trying to instrument some code to catch and print error messages. Currently I'm using a macro somethng like this:

#define my_function(x) \   switch(function(x)) { \     case ERROR: \       fprintf(stderr, "Error!\n"); \       break; \   } 

Normally, I never capture the function output and this works fine. But I've found a couple cases where I also need the return value of function(). I tried something like the following, but this produces a syntax error.

#define my_function(x) \   do { \     int __err = function(x); \     switch(__err) { \       case ERROR: \         fprintf(stderr, "Error!\n"); \         break; \     } \     __err; \   } while(0) 

I could declare a global variable to hold the return value of the function, but that looks ugly and my program is multithreaded, so that's likely to cause problems. I'm hoping there's a better solution out there.

like image 251
Michael Mior Avatar asked Aug 20 '10 15:08

Michael Mior


People also ask

Can we use return in macro in C?

Macros just perform textual substitution. They can't return anything - they are not functions.

What is the output of C program with macros?

12) What is the output of C program with macros.? Explanation: Inside main the statment printf("Error=%d",10) is substituted. printf("Error=%d",10);

What is macro in C with example?

A macro is a fragment of code that is given a name. You can define a macro in C using the #define preprocessor directive. Here's an example. Here, when we use c in our program, it is replaced with 299792458 .

How #define works in C?

The #define creates a macro, which is the association of an identifier or parameterized identifier with a token string. After the macro is defined, the compiler can substitute the token string for each occurrence of the identifier in the source file.


2 Answers

GCC has a feature called statement expressions

So if define macro like

#define FOO(A) ({int retval; retval = do_something(A); retval;}) 

then you will be able to use it like

foo = FOO(bar); 
like image 181
qrdl Avatar answered Sep 23 '22 15:09

qrdl


This is relatively complicated code, there is not much reason to have it in a macro. Make it inline (C99) or static (C89) or both if you really want to place it in a header file. With any reasonable compiler this then should result in the same efficiency as a macro.

like image 41
Jens Gustedt Avatar answered Sep 22 '22 15:09

Jens Gustedt