Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a C macro contain temporary variables?

I have a function that I need to macro'ize. The function contains temp variables and I can't remember if there are any rules about use of temporary variables in macro substitutions.

long fooAlloc(struct foo *f, long size)
{
   long      i1, i2;
   double   *data[7];

   /* do something */
   return 42;
}

MACRO Form:

#define ALLOC_FOO(f, size) \
{\
   long      i1, i2;\
   double   *data[7];\
\
   /* do something */ \
}

Is this ok? (i.e. no nasty side effect - other than the usual ones : not "type safe" etc). BTW, I know "macros are evil" - I simply have to use it in this case - not much choice.

like image 367
Homunculus Reticulli Avatar asked Jan 06 '12 21:01

Homunculus Reticulli


Video Answer


2 Answers

There are only two conditions under which it works in any "reasonable" way.

  1. The macro doesn't have a return statement. You can use the do while trick.

    #define macro(x) do { int y = x; func(&y); } while (0)
    
  2. You only target GCC.

    #define min(x,y) ({ int _x = (x), _y = (y); _x < _y ? _x : _y; })
    

It would help if you explain why you have to use a macro (does your office have "macro mondays" or something?). Otherwise we can't really help.

like image 139
Dietrich Epp Avatar answered Sep 20 '22 15:09

Dietrich Epp


C macros are only (relatively simple) textual substitutions.

So the question you are maybe asking is: can I create blocks (also called compound statements) in a function like in the example below?

void foo(void)
{
    int a = 42;
    {   
        int b = 42;
        {
            int c = 42; 
        } 
    }
}

and the answer is yes.

Now as @DietrichEpp mentioned it in his answer, if the macro is a compound statement like in your example, it is a good practice to enclose the macro statements with do { ... } while (0) rather than just { ... }. The link below explains what situation the do { ... } while (0) in a macro tries to prevent:

http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html

Also when you write a function-like macro always ask yourself if you have a real advantage of doing so because most often writing a function instead is better.

like image 30
ouah Avatar answered Sep 17 '22 15:09

ouah