Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The most useful user-made C-macros (in GCC, also C99)? [closed]

What C macro is in your opinion is the most useful? I have found the following one, which I use to do vector arithmetic in C:

#define v3_op_v3(x, op, y, z) {z[0]=x[0] op y[0]; \                                z[1]=x[1] op y[1]; \                                z[2]=x[2] op y[2];} 

It works like that:

v3_op_v3(vectorA, +, vectorB, vectorC); v3_op_v3(vectorE, *, vectorF, vectorJ); ... 
like image 443
psihodelia Avatar asked Nov 20 '09 17:11

psihodelia


People also ask

Why are macros useful in C?

Macro in C programming is known as the piece of code defined with the help of the #define directive. Macros in C are very useful at multiple places to replace the piece of code with a single value of the macro. Macros have multiple types and there are some predefined macros as well.

What are the most common predefined macros in C?

Predefined Macros in C99 standard: This macro gives value similar to __STDC_VERSION__, in that it expands to a version number. __OBJC__ Macro:: __OBJC__ Macro has value 1 if the Objective-C compiler is in use. __OBJC__ is used to test whether a header is compiled by a C compiler or an Objective-C compiler.

Where macros are stored in C?

Macros are not stored in memory anywhere in the final program but instead the code for the macro is repeated whenever it occurs. As far as the actual compiler is concerned they don't even exist, they've been replaced by the preprocessor before they get that far.


2 Answers

#define IMPLIES(x, y) (!(x) || (y))  #define COMPARE(x, y) (((x) > (y)) - ((x) < (y))) #define SIGN(x) COMPARE(x, 0)  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))  #define SWAP(x, y, T) do { T tmp = (x); (x) = (y); (y) = tmp; } while(0) #define SORT2(a, b, T) do { if ((a) > (b)) SWAP((a), (b), T); } while (0)  #define SET(d, n, v) do{ size_t i_, n_; for (n_ = (n), i_ = 0; n_ > 0; --n_, ++i_) (d)[i_] = (v); } while(0) #define ZERO(d, n) SET(d, n, 0) 

And, of course, various MIN, MAX, ABS etc.

Note, BTW, that none of the above can be implemented by a function in C.

P.S. I would probably single out the above IMPLIES macro as one of the most useful ones. Its main purpose is to facilitate writing of more elegant and readable assertions, as in

void foo(int array[], int n) {   assert(IMPLIES(n > 0, array != NULL));   ... 
like image 164
AnT Avatar answered Oct 05 '22 17:10

AnT


The key point with C macros is to use them properly. In my mind there are three categories (not considering using them just to give descriptive names to constants)

  1. As a shorthand for piece of codes one doesn't want to repeat
  2. Provide a general use function
  3. Modify the structure of the C language (apparently)

In the first case, your macro will live just within your program (usually just a file) so you can use macros like the one you have posted that is not protected against double evaluation of parameters and uses {...}; (potentially dangerous!).

In the second case (and even more in the third) you need to be extremely careful that your macros behave correctly as if they were real C constructs.

The macro you posted from GCC (min and max) is an example of this, they use the global variables _a and _b to avoid the risk of double evaluation (like in max(x++,y++)) (well, they use GCC extensions but the concept is the same).

I like using macros where it helps to make things more clear but they are a sharp tool! Probably that's what gave them such a bad reputation, I think they are a very useful tool and C would have been much poorer if they were not present.

I see others have provided examples of point 2 (macros as functions), let me give an example of creating a new C construct: the Finite state machine. (I've already posted this on SO but I can't seem to be able to find it)

 #define FSM            for(;;)  #define STATE(x)       x##_s   #define NEXTSTATE(x)   goto x##_s 

that you use this way:

 FSM {     STATE(s1):       ... do stuff ...       NEXTSTATE(s2);      STATE(s2):       ... do stuff ...       if (k<0) NEXTSTATE(s2);        /* fallthrough as the switch() cases */      STATE(s3):       ... final stuff ...       break;  /* Exit from the FSM */  }  

You can add variation on this theme to get the flavour of FSM you need.

Someone may not like this example but I find it perfect to demonstrate how simple macros can make your code more legible and expressive.

like image 32
Remo.D Avatar answered Oct 05 '22 17:10

Remo.D