Reputation: 45
I bumped into the following macro while analyzing a code.
#define __COMMAND_HANDLER(name, extra ...) int name(struct command_invocation *cmd, ## extra)
The function name
is passed as an argument to __COMMAND_HANDLER
however there is no definition of this function anywhere else in the code. The cmd argument's type (command_invocation
) is defined. Basically I couldn't understand the functionality of this macro because I couldn't find the definition of the function name
. Is name some kind of pre-defined function in standard C library ? Does this macro definition make sense if name
is not defined ?
Upvotes: 2
Views: 176
Reputation: 4473
Durning preprocession, the preprocessor will replace all occurrences of __COMMAND_HANDLER(name, extra ...)
macro to its body with replacing each occurences of name
and extra...
inside its body to the tokens you specified.
This means in this case that whatever you enter for name
argument, it will be a function name, and extra...
will be its additional parameters beside the first one (struct command_invocation *cmd
).
For example the following line:
__COMMAND_HANDLER(foo, int param) {
/* definition */
}
after preprocessing will be:
int foo(struct command_invocation *cmd, int param) {
/* definition */
}
One important thing has to be clarified: the ##
before extra
and named variable argument (using extra...
instead of ...
) are not the part of the c standard but they are GNU extensions. The effect of ##
after comma lets you specify nothing for variable argument. Compiling your example with GCC (with -pedantic
flag) when it's used as follows, you will see warning messages:
/* The following example will print the following messages:
* warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
* warning: ISO C99 requires at least one argument for the "..." in a variadic
* macro
*/
__COMMAND_HANDLER(bar);
Normally the ##
is the operator for token concatenation, i.e. two tokens on either side of a ##
operator are combined into a single one. For example:
#include <stdio.h>
#define FOO(name, number) void name##number()
FOO(bar, 1) { puts("I'm first."); }
FOO(bar, 2) { puts("I'm second."); }
int main() {
bar1();
bar2();
return 0;
}
Upvotes: 1
Reputation: 46
In short: the macro is creating the function with the name specified by the parameter name
and optional additional arguments specified by extra ...
.
Note: names starting with a double underscore is implementation reserved and shouldn't be used.
The macro is variadic.
The second argument to the macro extra ...
provides a name to use instead of the default __VA_ARGS__
inside the function declaration macro. This is a GNU extension
## extra
is another GNU extension that specifies to the preprocessor that if the second argument to the macro __COMMAND_HANDLER
is omitted, the preceding comma can be removed and the function called without it.
The reason you can't find the declaration of name
is because it's a parameter to your macro! The macro itself is declaring a new function with whatever is in name, and the arguments provided, with the default first argument of struct command_invocation *cmd
.
Here are some examples:
Calling:
__COMMAND_HANDLER(cmd,char * w)
Would result in the function declaration of:
int cmd(struct command_invocation *cmd,char * w)
Whereas calling:
__COMMAND_HANDLER(cmd2)
would result in the function declaration of:
int cmd2(struct command_invocation *cmd)
Upvotes: 0
Reputation: 6171
This is a macro and name is a parameter. You use it like this:
__COMMAND_HANDLER(hello, char* world)
During pre-process stage, it would transform your code into:
int hello(struct command_invocation *cmd, char *world);
In this case, name is passed as hello, and extra = char* world. If you don't pass anything for extra, ## will discard the comma.
Upvotes: 0