9

I have seen this snippet:

#define kthread_create(threadfn, data, namefmt, arg...) \
    kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)
  1. what does ## stand for ?
  2. what is the meaning of ## when it appears out of a macro ?
AstroCB
  • 12,337
  • 20
  • 57
  • 73
0x90
  • 39,472
  • 36
  • 165
  • 245
  • 1
    This is an interesting use. I've never seen it with variable arguments. Usually I've seen it used to concatenate an argument and string together. http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html – Josh Petitt Aug 21 '12 at 12:37

2 Answers2

10

Contrary to the other answers, this is actually GCC extension. When pasting variable args directly in, a problem occurs if no extra args were passed. Thus, GCC makes ## when used with __VA_ARGS__ or a varargs variable (declared with argname...). To paste if it contains a value, or remove the previous comma if not.

The documentation for this extension is here:

Second, the '##' token paste operator has a special meaning when placed between a comma and a variable argument. If you write

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

and the variable argument is left out when the eprintf macro is used, then the comma before the '##' will be deleted. This does not happen if you pass an empty argument, nor does it happen if the token preceding '##' is anything other than a comma.

eprintf ("success!\n")
      ==> fprintf(stderr, "success!\n");

The above explanation is ambiguous about the case where the only macro parameter is a variable arguments parameter, as it is meaningless to try to distinguish whether no argument at all is an empty argument or a missing argument. In this case the C99 standard is clear that the comma must remain, however the existing GCC extension used to swallow the comma. So CPP retains the comma when conforming to a specific C standard, and drops it otherwise.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
1

This "pastes" whatever passed in arg to the macro expansion. Example:

kthread_create(threadfn, data, namefmt, foo, bar, doo);

Expands to:

kthread_create_on_node(threadfn, data, -1, namefmt, foo, bar, doo);
Claudi
  • 5,224
  • 17
  • 30