32

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);
...
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
psihodelia
  • 29,566
  • 35
  • 108
  • 157
  • 3
    And you're not implementing any of the standard forms of vector multiplication here (not dot product, cross product, nor tensor product). – David Thornley Nov 20 '09 at 18:07
  • 1
    Component-wise multiplication has it's uses, but the dimensional limit imposed by the macro makes it not so useful. – outis Nov 20 '09 at 18:17
  • 1
    @outis: This is intended to be used in areas where the dimensional limit is strictly imposed by the very nature of the application area. Like in 3D graphics, for example. – AnT stands with Russia Nov 20 '09 at 18:30
  • 33
    But suppose it the number of dimensions in the universe changes, the code will break - this is the sort of shortsightedness that led to the Y2K problem. – Martin Beckett Nov 20 '09 at 18:41
  • 8
    Yeah... It like that famous quote from Xerox manual. One of the benefits of declaring PI as a named constant is that it helps you to adjust the code in case the value of Pi changes. – AnT stands with Russia Nov 20 '09 at 19:09
  • 1
    Vector products? Have you forgotten C has functions too? – MAK Nov 20 '09 at 19:44
  • Reference for the aforementioned quote from the Xerox FORTRAN manual regarding pi: http://en.wikiquote.org/wiki/Fortran – Arto Bendiken Jul 17 '11 at 17:38

18 Answers18

36
#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));
  ...
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • very nice, but I still cannot vote, sorry :( – psihodelia Nov 20 '09 at 18:16
  • 6
    Your macro-fu is impressive (you parenthesize correctly and know the `do...while(0)` technique), but there's still multiple evaluation problems that you really can't fix. – David Thornley Nov 20 '09 at 18:18
  • 15
    @David Thornley: "Multiple evaluation" with macros is what also gives us "lazy evaluation". It is as much of a problem as it is a feature. One just has to learn to use it properly. To say that danger of "multiple evaluation" somehow means that one shall not use macros, is exactly the same as to say that one shall not use division operator because there's a danger of dividing something by zero. – AnT stands with Russia Nov 20 '09 at 18:21
  • No need for a temp-var when swapping integers: #define SWAPINT(x, y) do { (x) ^= (y); (y) ^= (x); (x) ^= (y); } while(0) – Tomas Nov 20 '09 at 18:30
  • 7
    @Tomas: there's no need, but your way means that callers who want to do `SWAPINT(*xp, *yp)` now need to check `xp != yp` first. These days I don't see much point in adding an awkward edge case in order to (maybe) save a register and/or 4 bytes of stack. – Steve Jessop Nov 20 '09 at 19:17
  • @Ramónster: No, I couldn't. Do a search on it, it is a known trick and a popular question. For example, think what will happen to `if (condition) SWAP(a, b, int); else /* something */;` with my version and with yours. – AnT stands with Russia Nov 20 '09 at 19:19
  • @AndreyT: imperfect analogy. There are no operators that _look_ like division operators yet cause an error when dividing by one or two. That said, I don't have anything against macros, and the `IMPLIES` is really nice. – int3 Nov 20 '09 at 19:31
  • 3
    Nice, liking "IMPLIES" the most :) – Johannes Schaub - litb Nov 20 '09 at 20:16
  • I am very late to this party, but what does SET and ZERO do? – JPMC Jan 29 '15 at 04:25
  • 2
    @JPMC: `SET` simply assigns the given value `v` to all `n` elements of array `d`. `ZERO` uses `SET` to assign value `0` to all `n` elements of array `d`. – AnT stands with Russia Jan 29 '15 at 06:28
  • 1
    I'm curious, why not call it `ARRAY_SET` and `ARRAY_ZERO` to be consistent with `ARRAY_SIZE`? When I saw `SET`, I was sort of expecting that maybe it set a specific bit of a value or something. – Todd Lehman Jul 22 '15 at 21:31
  • 1
    @Todd Lehman: The names are just "stripped" versions from some real-life code. Of course, taking over such generic words as `SET` and `ZERO` with a macro is not a good idea in any case. But to address your point: the above `ARRAY_SIZE` macro is intended to be used with arrays only (not with pointers), while `SET` and `ZERO` are not tied to arrays at all - they can work with pointers as well. To continue to follow that convention, name `ARRAY_SET` in this context would make more sense with the following definition: `#define ARRAY_SET(a) SET(a, ARRAY_SIZE(a))`. Same for `ARRAY_ZERO`. – AnT stands with Russia Jul 22 '15 at 22:45
  • I'm not sure I understand `IMPLIES` can someone explain it to me? What is actually meant with it? Why would you assert that the array has 0 or negative length OR it's not NULL? (`assert(!(n > 0) || array != NULL)`) – vexe Aug 27 '15 at 18:06
  • @vexe: This condition effectively says: "if array length `n` is positive, then `array` pointer cannot be null. In all other cases we don't care what `array` is". – AnT stands with Russia Aug 27 '15 at 18:18
  • @AnT I see. But why would you want the assertion to succeed if `n` was negative? Why not `assert(n > 0 && array != NULL)`? I just can't think when it would be OK to have a negative length. Maybe that was not the best example to demonstrate `IMPLIES`? – vexe Aug 27 '15 at 18:47
  • @vexe: Well, I want to allow `n == 0` (i.e. "no array passed"). I don't really want to allow `n < 0`, but for the sake of simplicity I treated `n < 0` in the same way as `n == 0` (i.e. negative `n` also means `"no array passed"). In my code I'd actually make a point of using an *unsigned* type for `n`, which would eliminate the issue of negative `n` from consideration. With signed type a more appropriate assertion would be `assert(n >= 0 && IMPLIES(n > 0, array != NULL))`. – AnT stands with Russia Aug 27 '15 at 20:06
  • @vexe: Note again that I don't want to require `n > 0` here. I want to allow `n == 0` as well. And if `n == 0`, I don't want to impose any requirements on `array`. That's what `IMPLIES` helps me to achieve. – AnT stands with Russia Aug 27 '15 at 20:06
  • why do you have do while(0) ? – André Rosa Mar 24 '20 at 23:21
  • @AndréRosa The use of a do while loop is to turn the macro into an iteration statement, vs. a compound statement. Macros are often created like this so that the user of the macro can place a semicolon after its invocation and not run into a compiler error. Here is a short page from the GNU C Preprocessor documentation that answers this question in more detail: https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon – Brent Pappas Sep 23 '21 at 11:08
  • @AnT What do you mean by "none of the above can be implemented by a function in C"? Would `int implies(int x, int y) {return ( !(x) || (y) ); }` not be functionally the same as IMPLIES? I trust your judgment and am wondering what I am not seeing. – Brent Pappas Sep 23 '21 at 11:11
  • @Brent Pappas: My version imposes well-defined sequencing onto the order of evaluation of `x` and `y` (brought in by the sequencing properties of `||` operator). Your function does not. Granted, relying on that order is not generally not a good idea, but still formally functional version is not equivalent to macro version in that regard, – AnT stands with Russia Sep 24 '21 at 05:42
23

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.

Remo.D
  • 16,122
  • 6
  • 43
  • 74
19

for-each loop in C99:

#define foreach(item, array) \
    for(int keep=1, \
            count=0,\
            size=sizeof (array)/sizeof *(array); \
        keep && count != size; \
        keep = !keep, count++) \
      for(item = (array)+count; keep; keep = !keep)

int main() {
  int a[] = { 1, 2, 3 };
  int sum = 0;
  foreach(int const* c, a)
    sum += *c;
  printf("sum = %d\n", sum);

  // multi-dim array
  int a1[][2] = { { 1, 2 }, { 3, 4 } };
  foreach(int (*c1)[2], a1)
    foreach(int *c2, *c1) 
      printf("c2 = %d\n", *c2);
}
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
12

If you need to define data multiple times in different contexts, macros can help you avoid have to relist the same thing multiple times.

For example, lets say you want to define an enum of colors and an enum-to-string function, rather then list all the colors twice, you could create a file of the colors (colors.def):

c(red)
c(blue)
c(green)
c(yellow)
c(brown)

Now you can in your c file you can define your enum and your string conversion function:

enum {
#define c(color) color,
# include "colors.def"
#undef c
};

const char *
color_to_string(enum color col)
{
    static const char *colors[] = {
#define c(color) #color,
# include "colors.def"
#undef c
    };
    return (colors[col]);
};
srparish
  • 1,708
  • 1
  • 16
  • 22
7
#if defined NDEBUG
    #define TRACE( format, ... )
#else
    #define TRACE( format, ... )   printf( "%s::%s(%d)" format, __FILE__, __FUNCTION__,  __LINE__, __VA_ARGS__ )
#endif

Note that the lack of a comma between "%s::%s(%d)" and format is deliberate. It prints a formatted string with source location prepended. I work in real-time embedded systems so often I also include a timestamp in the output as well.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Shouldn't the NDEBUG one be `#define TRACE (format, ...) ((void)0)` to avoid traps like `if(cond) TRACE(...)` ? – Gregory Jul 17 '14 at 15:06
  • @Gregory : What is the "trap"? If you failed to place a semi-colon after the macro call, it is probably wrong in any case - `if(x) TRACE("y = %d", y );` would resolve to `if(x);` which will have no effect. – Clifford Jul 17 '14 at 15:38
  • My bad... I was pretty sure at one point I used a compiler for which `;` wasn't a valid statement but it's not a problem for GCC. assert.h still seems to use `#define assert(ignore)((void) 0)` though. – Gregory Jul 18 '14 at 15:44
  • That's because the C standard mandates that `assert` expand to a void expression, regardless of the value of `NDEBUG` – Gabriel Ravier Jul 30 '21 at 15:08
6

Foreach loop for GCC, specifically C99 with GNU Extensions. Works with strings and arrays. Dynamically allocated arrays can be used by casting them to a pointer to an array, and then dereferencing them.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define FOREACH_COMP(INDEX, ARRAY, ARRAY_TYPE, SIZE) \
  __extension__ \
  ({ \
    bool ret = 0; \
    if (__builtin_types_compatible_p (const char*, ARRAY_TYPE)) \
      ret = INDEX < strlen ((const char*)ARRAY); \
    else \
      ret = INDEX < SIZE; \
    ret; \
  })

#define FOREACH_ELEM(INDEX, ARRAY, TYPE) \
  __extension__ \
  ({ \
    TYPE *tmp_array_ = ARRAY; \
    &tmp_array_[INDEX]; \
  })

#define FOREACH(VAR, ARRAY) \
for (void *array_ = (void*)(ARRAY); array_; array_ = 0) \
for (size_t i_ = 0; i_ && array_ && FOREACH_COMP (i_, array_, \
                                    __typeof__ (ARRAY), \
                                    sizeof (ARRAY) / sizeof ((ARRAY)[0])); \
                                    i_++) \
for (bool b_ = 1; b_; (b_) ? array_ = 0 : 0, b_ = 0) \
for (VAR = FOREACH_ELEM (i_, array_, __typeof__ ((ARRAY)[0])); b_; b_ = 0)

/* example's */
int
main (int argc, char **argv)
{
  int array[10];
  /* initialize the array */
  int i = 0;
  FOREACH (int *x, array)
    {
      *x = i;
      ++i;
    }

  char *str = "hello, world!";
  FOREACH (char *c, str)
    printf ("%c\n", *c);

  /* Use a cast for dynamically allocated arrays */
  int *dynamic = malloc (sizeof (int) * 10);
  for (int i = 0; i < 10; i++)
    dynamic[i] = i;

  FOREACH (int *i, *(int(*)[10])(dynamic))
    printf ("%d\n", *i);

  return EXIT_SUCCESS;
}

This code has been tested to work with GCC, ICC and Clang on GNU/Linux.

Lambda expressions (GCC only)

#define lambda(return_type, ...) \
  __extension__ \
  ({ \
    return_type __fn__ __VA_ARGS__ \
    __fn__; \
  })

int
main (int argc, char **argv)
{
  int (*max) (int, int) = 
    lambda (int, (int x, int y) { return x > y ? x : y; });
  return max (1, 2);
}
Joe D
  • 2,855
  • 2
  • 31
  • 25
6

Someone else mentioned container_of(), but didn't provide an explanation for this really handy macro. Let's say you have a struct that looks like this:

struct thing {
    int a;
    int b;
};

Now if we have a pointer to b, we can use container_of() to get a pointer to thing in a type safe fashion:

int *bp = ...;
struct thing *t = container_of(bp, struct thing, b);

This is useful in creating abstract data structures. For example, rather than taking the approach queue.h takes for creating things like SLIST (tons of crazy macros for every operation), you can now write an slist implementation that looks something like this:

struct slist_el {
    struct slist_el *next;
};

struct slist_head {
    struct slist_el *first;
};

void
slist_insert_head(struct slist_head *head, struct slist_el *el)
{
    el->next = head->first;
    head->first = el;
}

struct slist_el
slist_pop_head(struct slist_head *head)
{
    struct slist_el *el;

    if (head->first == NULL)
        return NULL;

    el = head->first;
    head->first = el->next;
    return (el);   
}

Which is not crazy macro code. It will give good compiler line-numbers on errors and works nice with the debugger. It's also fairly typesafe, except for cases where structs use multiple types (eg if we allowed struct color in the below example to be on more linked lists than just the colors one).

Users can now use your library like this:

struct colors {
    int r;
    int g;
    int b;
    struct slist_el colors;
};

struct *color = malloc(sizeof(struct person));
color->r = 255;
color->g = 0;
color->b = 0;
slist_insert_head(color_stack, &color->colors);
...
el = slist_pop_head(color_stack);
color = el == NULL ? NULL : container_of(el, struct color, colors);
Community
  • 1
  • 1
srparish
  • 1,708
  • 1
  • 16
  • 22
5
#define COLUMNS(S,E) [ (E) - (S) + 1 ]


struct 
{
    char firstName COLUMNS ( 1, 20);
    char LastName  COLUMNS (21, 40);
    char ssn       COLUMNS (41, 49);
}

Save yourself some error prone counting

EvilTeach
  • 28,120
  • 21
  • 85
  • 141
4

This one is from linux kernel (gcc specific):

#define container_of(ptr, type, member) ({                  \
const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - offsetof(type,member) ); })

Another missing from other answers:

#define LSB(x) ((x) ^ ((x) - 1) & (x))   // least significant bit
Alexandru
  • 25,070
  • 18
  • 69
  • 78
2

I also like this one:

#define COMPARE_FLOATS(a,b,epsilon) (fabs(a - b) <= epsilon * fabs(a))

And how you macros-haters do fair floating-point comparisons?

psihodelia
  • 29,566
  • 35
  • 108
  • 157
  • 1
    Why would you use a macro instead of a function for that? And what happens when you use 'COMPARE_FLOATS(a,b-x,eps)'? – Niki Nov 20 '09 at 18:00
  • 1
    Not to mention this fails badly if a is 0.0. – David Thornley Nov 20 '09 at 18:08
  • 8
    "how you macros-haters do fair floating-point comparisons" static inline function. – Steve Jessop Nov 20 '09 at 18:11
  • 7
    There is not such thing as "macro hater". Every time you see a "macro heater", it is in reality a beginner that is trying to present himself as more mature programmer than he really is by parroting what he thinks sounds as "mature" maxima. – AnT stands with Russia Nov 20 '09 at 18:26
  • That's fine if you want to compare them incorrectly. Here's how to do it right: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm – Tim Allman Nov 20 '09 at 18:53
  • 2
    @AndreyT: Given that I'm a macro hater, would you care to estimate how many years I've worked professionally in C and C++, and how many courses I've taught at the University level on programming in C? – David Thornley Nov 20 '09 at 19:21
  • 3
    I hate macros too. I also hate lawnmowers - I generally acknowledge the need for shorter grass, I just don't enjoy the process of using the one to achieve the other. I've used macros in another language which were much richer (for instance you could loop without resorting to a recursive include) and yet which were also easier to use correctly than C macros. – Steve Jessop Nov 20 '09 at 19:45
  • 2
    @Steve: Yes, I suppose I should clarify. I hate C macros. I love Lisp macros. – David Thornley Nov 20 '09 at 20:24
  • 1
    Certainly proves your academic credentials ;-) – Steve Jessop Nov 22 '09 at 01:36
  • 4
    @David Thornley: Is it relevant? A grandma that was driving from her house to her favorite grocery store for 40 years technically has 40 years of driving experience. Does that make her a good driver? Good programmers never hate anything, since absolutely everything has its time and place. – AnT stands with Russia Nov 22 '09 at 06:59
  • 1
    @Andrey: actually it is relevant. That grandmother is not a "beginner". You asserted that every macro-hater is a beginner, not that every macro-hater is a bad programmer. But even pretending you'd said "non-good" in the first place, it's absurd. Acknowledging the necessity of a technique, and using it correctly, is not identical with liking it, and you can still be annoyed there isn't something better. Further, if it were true that good programmers believe everything has its time and place, then no good programmer would ever deprecate or remove any feature in a new release. – Steve Jessop Nov 23 '09 at 12:26
  • 1
    But anyway, I think this has now fully descended to the "no true Scotsman" argument. Andrey says, "no good programmer disagrees with me". David says, "I'm a good programmer, and I disagree with you". Andrey says, "but if you disagree with me, then you cannot possibly be a good programmer". – Steve Jessop Nov 23 '09 at 12:28
  • @Steve: Features don't get deprecated out of pure hate. No programmer would ever deprecate a feature until an adequate replacement feature is implemented. – AnT stands with Russia Nov 23 '09 at 16:31
  • But the reason you develop a replacement might well be that you hate the original. – Steve Jessop Nov 23 '09 at 21:50
  • 2
    I love macros, but I do my floating-point comparisons the way god intended -- strict equality. – Stephen Canon Nov 24 '09 at 06:11
  • 1
    Btw, noted "bad programmer" Jon Skeet hates the "lock" statement in C# ;-p – Steve Jessop Nov 24 '09 at 14:15
  • Sorry, forgot the link: http://stackoverflow.com/questions/282329/what-are-five-things-you-hate-about-your-favorite-language/282342#282342 – Steve Jessop Nov 25 '09 at 12:04
  • 1
    No true "no true Scotsman" argument would descend to *this* level – John Lawrence Aspden Oct 26 '11 at 15:33
  • @StephenCanon, make sure you don't write software for NASA. – Shahbaz Sep 19 '12 at 13:01
  • 1
    @Shahbaz: I would much prefer that NASA engineers know what they're doing and use strict-equality comparisons when appropriate than they not understand floating-point and blindly throw epsilons around without actually understanding the problem because some guy on the internet said to. There are situations in which approximate comparisons are appropriate, and there are situations in which exact comparisons are appropriate. Because of the work I do (math library development), I happen to see many more of the latter. – Stephen Canon Sep 19 '12 at 13:16
  • @StephenCanon, from what I had understood from FPUs, they lose precision in shifting etc and what should in theory yield the same value as another expression, may in the end happen to be slightly different. Perhaps you know very well every detail of floating point operations, but that's not the case with most of the programmers. Your other comment could easily mislead a programmer new to this area. Given the nature of this site, I'd say that's not so good. – Shahbaz Sep 19 '12 at 13:29
2

Just the standard ones:

#define LENGTH(array) (sizeof(array) / sizeof (array[0]))
#define QUOTE(name) #name
#define STR(name) QUOTE(name)

but there's nothing too spiffy there.

outis
  • 75,655
  • 22
  • 151
  • 221
  • 1
    Aside: someone posted a LENGTH macro from Google that would cause a compile time error if passed a pointer, but I haven't been able to find it again. Does anyone know the macro and have a link to the answer (or another page) that shows it? – outis Nov 20 '09 at 18:10
  • This one works for one-dimensional arrays, but you need to pass it the element type: `#define REQUIRE_ARRAY(T, X) (void)(sizeof (((char(*)(T(*)[]))0)(&(X))))` – Johannes Schaub - litb Nov 20 '09 at 20:59
  • The following works in C99 also for dimensions greater than 1. You need to call `REQUIRE_ARRAY2` for an array with 2 dimensions, for example: `#define REQUIRE_ARRAY2(T, X) (void)(sizeof (((char(*)(T(*)[*][*]))0)(&(X))))` – Johannes Schaub - litb Nov 20 '09 at 21:19
  • 1
    @outis - Quite late to the party, but I believe `#define IS_ARRAY(a) ((void *)&a == (void *)a)` works as a _runtime_ test for whether something is an array or a pointer (unless the pointer is pointing to itself, which may happen as part of a circularly linked structure, but is somewhat uncommon). – Chris Lutz Jul 08 '11 at 12:09
  • 2
    The party never ends. The [Google LENGTH macro](http://stackoverflow.com/questions/4415524/common-array-length-macro-for-c/4415646#4415646) may have been the one posted by Michael Burr in answer to ["Common array length macro for C?"](http://stackoverflow.com/questions/4415524/common-array-length-macro-for-c/4415646#4415646). Note that it's not a test whether something is an array but a macro that results in the length of an array or an error for other types. – outis Aug 25 '11 at 18:42
2
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))

Find the closest 32bit unsigned integer that is larger than x. I use this to double the size of arrays (i.e. the high-water mark).

user172818
  • 4,518
  • 1
  • 18
  • 20
1

also multi-type Minimum and Maximum like that

//NOTE: GCC extension !
#define max(a,b) ({typeof (a) _a=(a); typeof (b) _b=(b); _a > _b ? _a:_b; })
#define min(a,b) ({typeof (a) _a=(a); typeof (b) _b=(b); _a < _b ? _a:_b; })
psihodelia
  • 29,566
  • 35
  • 108
  • 157
  • 2
    It's so short, it's scary. Also, this is a textbook example of why *not* to use macros. (because the arguments are (conditionally) evaluated multiple times) – justin Nov 20 '09 at 17:45
  • *or* (haven't had enough coffee) you're working with copied objects – justin Nov 20 '09 at 17:47
  • 1
    I think, there was gcc extension for min/max. Something like `a >? b` – Xeor Nov 20 '09 at 17:47
  • @Justin: If you're going to work with copied objects, you may as well use functions. This is not something that can be effectively done with C macros. – David Thornley Nov 20 '09 at 18:12
  • 5
    @Justin: Huh? The above code uses GCC extensions specifically to avoid multiple evaluations. There's no multiple evaluatuion in the above. – AnT stands with Russia Nov 20 '09 at 18:16
  • 1
    @Xeor: Those were g++ extensions and have been deprecated since gcc 4.0. http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html#Min-and-Max – jamessan Nov 20 '09 at 19:27
  • also three parameter version, useful sometimes: #define max(a,b,c) (a) > (b) ? ((a) > (c) ? (a) : (c)) : ((b)>(c) ? (b) : (c)) – Hernán Nov 21 '09 at 07:32
  • 1
    @Hernán, and what is with four parameters? I'd go for max(max(a, b), c) instead – quinmars Dec 11 '09 at 00:32
  • @quinmars: that's also ok -- but I use C++ inlines and templates, anyway ;) – Hernán Jul 27 '10 at 00:33
1

Checking whether a floating point x is Not A Number:

#define ISNAN(x) ((x) != (x))
psihodelia
  • 29,566
  • 35
  • 108
  • 157
1

Pack bytes,words,dwords into words,dwords and qwords:

#define ULONGLONG unsigned __int64
#define MAKEWORD(h,l) ((unsigned short) ((h) << 8)) | (l)
#define MAKEDWORD(h,l) ((DWORD) ((h) << 16)) | (l)
#define MAKEQWORD(h,l) ((ULONGLONG)((h) << 32)) | (l) 

Parenthesizing arguments it's always a good practice to avoid side-effects on expansion.

Hernán
  • 4,527
  • 2
  • 32
  • 47
0

This one is awesome:

#define NEW(type, n) ( (type *) malloc(1 + (n) * sizeof(type)) )

And I use it like:

object = NEW(object_type, 1);
psihodelia
  • 29,566
  • 35
  • 108
  • 157
  • 9
    What's with the `1+` allocating an extra byte for every allocation? – John Ledbetter Nov 20 '09 at 18:00
  • 2
    And why the cast? Never use that cast on the result of `malloc()` or related function. It takes time to type, and the only time it does anything is if you forgot to `#include `. If I do that, I'd rather have the diagnostic than have stuff continue to probably work. – David Thornley Nov 20 '09 at 18:11
  • 2
    malloc in a macro? are you serious? Noone will ever know where that memory leak came from. – Johannes Rudolph Nov 20 '09 at 18:14
  • 3
    The macro's named `NEW`—seems pretty clear to me it might allocate memory. Also, the cast is needed for C++, which will not implicitly convert a void * to another type. – Left For Archive Nov 20 '09 at 18:23
  • 5
    @LnxPrgr3: If you're writing in C++: DON'T DO THAT! Use `new` instead, and never use macros like this. – David Thornley Nov 20 '09 at 19:19
  • 5
    This failing to work in C++ is arguably a feature. It tells you that you've mistakenly run the wrong compiler. If you really want to compile your C with a C++ compiler, you could always define different versions of the macro according to whether __cplusplus is set. Using this macro at all in genuine C++ is questionable, and calling it NEW in C++ when it has nothing to do with `new` probably isn't a good plan. – Steve Jessop Nov 20 '09 at 19:29
  • Why are you adding 1 after multiplying `n` by the size of the type? Are you afraid that someone might pass `n` of zero? What if they pass a negative value? – Todd Lehman Jul 22 '15 at 21:59
0

One (of the very few) that I use regularly is a macro to declare an argument or variable as unused. The most compatible solution to note this (IMHO) varies by compiler.

justin
  • 104,054
  • 14
  • 179
  • 226
-1

TRUE and FALSE seem to be popular.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134