What does this #define syntax mean? - c

I came across this one, don't understand.
#define IDEBUG(a...)
What does the "(a...)" mean?

That's a variadic macro.
Quoting verbatim from the linked page:
A macro can be declared to accept a variable number of arguments much as a function can. The syntax for defining the macro is similar to that of a function. Here is an example:
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
This kind of macro is called variadic. When the macro is invoked, all the tokens in its argument list after the last named argument (this macro has none), including any commas, become the variable argument. This sequence of tokens replaces the identifier VA_ARGS in the macro body wherever it appears. Thus, we have this expansion:
eprintf ("%s:%d: ", input_file, lineno)
==> fprintf (stderr, "%s:%d: ", input_file, lineno)
And for that specific form, quoting further down in the page:
If your macro is complicated, you may want a more descriptive name for the variable argument than __VA_ARGS__. CPP permits this, as an extension. You may write an argument name immediately before the `...'; that name is used for the variable argument. The eprintf macro above could be written
#define eprintf(args...) fprintf (stderr, args)

Variable number of parameters. See variadic macros

It is a variadic macro.
A variadic macro is a macro that accepts a variable number of arguments. The feature has been introduced in C99.
The form
#define IDEBUG(a...) printf(a)
with the parameter a... is a GNU extension, a gives a name to the __VA_ARGS__ identifier.
The standard C99 form would be
#define IDEDBUG(...) printf(__VA_ARGS__)

Related

How can I tokenize and strize the __func__ macro in C?

I want to tokenize and strize, with macros, the name of the function we are in, to overload the function (with dlopen()), in C.
I found similar things with __LINE__ and __FILE__, but it seems to be a bit different in the case with __func__...
I tried that:
#define OVERLOAD2(f) printf("Trying to overload function %s...", #f)
#define OVERLOAD1(f) OVERLOAD2(f)
#define OVERLOAD OVERLOAD1(__func__)
int main() {
OVERLOAD;
}
Compiling with different standards of compilation (c99, gnu11) doesn't change the result; instead of printing:
Trying to overload function main...
It prints:
Trying to overload function __func__...
How can I correct those macros?
Here is what the C11 draft says about __func__:
1 The identifier __func__ shall be implicitly declared by the
translator as if, immediately following the opening brace of each
function definition, the declaration
static const char __func__[] = "function-name";
As you see __func__, unlike __FILE__ and __LINE__, is no preprocessor macro, so you can't evaluate it during the preprocessing stage.
But in your code, you don't even need to do that. Just change
#define OVERLOAD2(f) printf("Trying to overload function %s...", #f)
to
#define OVERLOAD printf("Trying to overload function %s...", __func__)
as you can see in the standard's description of __func__, it's already a string. No need to stringize it.
If you need the function name as a "bare word" at compile time, e.g. an implicit #define __FUNC__ myfunc, you're out of luck.
It's not possible in standard C. GCC additionally provides __FUNCTION__, but despite its all-caps name, the GCC manual says:
Neither of them is a macro; the preprocessor does not know the name of
the current function.
MSVC provides __FUNCTION__ as a macro but it's defined to a string and you can't strip away the double quotes.
Only way around that is writing your own preprocessor or rethink your approach

Macro with variable length of parameters

Is there a way to #define a macro with variable length of parameters?
#define CALL(ar1, ar2, ar3)
do something
#endif
in C code
CALL(0);
CALL(0,1);
CALL(0,1,2)
all invoke the above CALL macro. If ar2, ar3 not used, preprocessor just ignore the line with ar2 or ar3.
Yes, take a look at this one: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
Key word is __VA_ARGS__ ( Variadic Macros ):
A macro can be declared to accept a variable number of arguments much as a function can. The syntax for defining the macro is similar to that of a function. Here is an example:
#define eprintf(...) fprintf (stderr, __VA_ARGS__)

A #define in C with three dots

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))
This is definition for these 2 macros; later in the code LOGI and LOGW are used this way
LOGI("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y,
event.acceleration.z);
and this way
LOGW("Unable to eglMakeCurrent");
Since I try to avoid complex macros and #define in general, I can't get what this macro actually means. What is the role for the 3 dots notation here? What does this #define change later in the code?
Obviously I know that the 3 dots are used to indicate and indefinite amount of arguments, but I don't know how to read this situation.
The C99 standard introduced variadic macros, i.e., function-like macros that can take a variable number of arguments.
Quoting the latest draft of the C standard, section 6.10.3:
If the identifier-list in the macro definition does not end with an
ellipsis, the number of arguments (including those arguments
consisting of no preprocessing tokens) in an invocation of a
function-like macro shall equal the number of parameters in the macro
definition. Otherwise, there shall be more arguments in the invocation
than there are parameters in the macro definition (excluding the ...).
There shall exist a ) preprocessing token that terminates the
invocation.
The identifier __VA_ARGS__ shall occur only in the replacement-list of
a function-like macro that uses the ellipsis notation in the
parameters.
...
If there is a ... in the identifier-list in the macro definition,
then the trailing arguments, including any separating comma
preprocessing tokens, are merged to form a single item: the variable
arguments. The number of arguments so combined is such that,
following merger, the number of arguments is one more than the number
of parameters in the macro definition (excluding the ...).
And in the next subsection:
An identifier __VA_ARGS__ that occurs in the replacement list shall
be treated as if it were a parameter, and the variable arguments shall
form the preprocessing tokens used to replace it.
So you can invoke LOGI or LOGW with as many arguments as you like, and they'll all be expanded at the place specified in the definition by the reference to __VA_ARGS__.

what is ## in c?

I have seen this snippet:
#define kthread_create(threadfn, data, namefmt, arg...) \
kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)
what does ## stand for ?
what is the meaning of ## when it appears out of a macro ?
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.
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);

How, exactly, does the double-stringize trick work?

At least some C preprocessors let you stringize the value of a macro, rather than its name, by passing it through one function-like macro to another that stringizes it:
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
Example use cases here.
This does work, at least in GCC and Clang (both with -std=c99), but I'm not sure how it works in C-standard terms.
Is this behavior guaranteed by C99?
If so, how does C99 guarantee it?
If not, at what point does the behavior go from C-defined to GCC-defined?
Yes, it's guaranteed.
It works because arguments to macros are themselves macro-expanded, except where the macro argument name appears in the macro body with the stringifier # or the token-paster ##.
6.10.3.1/1:
... After the arguments for the
invocation of a function-like macro
have been identified, argument
substitution takes place. A parameter
in the replacement list, unless
preceded by a # or ## preprocessing
token or followed by a ##
preprocessing token (see below), is
replaced by the corresponding argument
after all macros contained therein
have been expanded...
So, if you do STR1(THE_ANSWER) then you get "THE_ANSWER", because the argument of STR1 is not macro-expanded. However, the argument of STR2 is macro-expanded when it's substituted into the definition of STR2, which therefore gives STR1 an argument of 42, with the result of "42".
As Steve notes, this is guarenteed, and it has been guarenteed since the C89 standard -- that was the standard the codified the # and ## operators in macros and mandates recursively expanding macros in args before substituting them into the body if and only if the body does not apply a # or ## to the argument. C99 is unchanged from C89 in this respect.

Resources