Home > front end >  Use of comma vs do-while in C macro
Use of comma vs do-while in C macro

Time:11-01

Is there a downside to doing this:

#define get_and_mark(name, b) get_val(name, &b), b = b | 0x80

rather than this:

#define get_and_mark(name, b) \
  do { \
    get_val(name, &b); \
    b = b | 0x80; \
  } while (0)

As far as I can see, the comma should also be safe for use in loops, branches etc. But is it really?

CodePudding user response:

If fixed up as Gerhardh says:

#define get_and_mark(name, b) (get_val(name, &(b)), (b) = (b) | 0x80)

then the first version can be used in an expression such as:

if (get_and_mark(name, b) != 0)

but the second cannot. Which semantic do you want? Do you want the invocation in an if condition to be a compile-time error?

Note that since b is mentioned multiple times in the expansion, you can't use get_and_mark(name, b[i ]). Also, note that you could use (b) |= 0x80 for the assignment in both variants:

#define get_and_mark(name, b) (get_val(name, &(b)), (b) |= 0x80)

#define get_and_mark(name, b) \
    do { \
        get_val(name, &(b)); \
        (b) |= 0x80; \
    } while (0)

You could use the comma operator in the second variant — though there's no need to do so.

Why not use an inline function?

static inline int get_and_mark(const char *name, int *b)
{
    get_val(name, b);
    return (*b |= 0x80);
}

You'd invoke it with get_and_mark(name, &b)? (Obviously, I'm guessing at the type of name, but fixing that if I'm wrong is easy.)

  • Related