C: Empty parentheses trailing the #define directive name; there's a body to the directive - c-preprocessor

#define __HAL_DBGMCU_FREEZE_TIM2() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM2_STOP)
What is the meaning of () here?

The empty parameter list in #define __HAL_DBGMCU_FREEZE_TIM2() is
unnecessary but innocuous. It is fairly common practice to define a macro
with an empty parameter list to document the fact that it is a function-like
macro, rather than the definition of a constant.

Related

C preprocessor - concatenating strings without multiple resolving

I have a macro that points to another macro:
#define USART1 ((USART_TypeDef *) USART1_BASE)
#define PIPE1 USART1
I'm trying to add a static text which I will use as a function definition (USART1 becomes USART1_IRQHandler). I tried something like:
#define _IRQ(NAME) NAME ## _IRQHandler
void _IRQ(PIPE1)(void) {
//...
}
but the name resolves as PIPE1_IRQHandler instead of USART1_IRQHandler. Then I tried #NAME to get the value of PIPE1, but it had fully resolved to the most low-level representation:
((USART_TypeDef *) ((((uint32_t)0x40000000) + 0x10000) + 0x3800))
Is there any way to get USART1_IRQHandler?
No, there isn't.
Macro arguments which participate in concatenation (##) and stringification (#) are not expanded at all in the course of replacing the macro with its definition. Consequently, it is common to pass arguments through an indirect macro so that they will be expanded fully befire being passed to the macro which concatenates or stringifies them.
There is no mechanism for partial expansion. It's basically all or nothing.
If you want to build up complicated chains of macro substitution, you need to avoid using words both as macros and as token pieces, as in your example.

Do function like macros need a mandatory parentheses? I am confused after referring the GCC cpp manual

Here is what confuses me:
To define a function-like macro, you use the same '#define' directive, but you put a pair of parentheses immediately after the macro name.
I believe this is to make the code stand out for people other than the author of the program. Like other rules of CAPS for macro names. But the following is where I get confused:
A function-like macro is only expanded if its name appears with a pair of parentheses after it. If you write just the name, it is left alone.
I disagreed instantly after reading it. And gcc -E verified that in the following code
#define FUNC display()
void display()
{
printf("Display\n");
}
int main()
{
FUNC;
return 0;
}
The pre-processed output shows the content of the main() function as expected:
int main()
{
display();
return 0;
}
So what am I missing here? The pre-processor is for tokenizing the source, the macro expansion is a token and the above code was processed that way, the pre-processor isn't supposed to check anything or verify anything, it just dumps tokens. In that case what is the gcc manual trying to convey.
I am learning C programming, so I might be misunderstanding it a great deal as it frequently happens, I searched for a proper explanation and finally resorted to asking here. Please help me with this.
When you define:
#define FUNC display()
FUNC is not a function-like macro; it is an object-like macro that expands to a function call.
A function-like macro looks like:
#define FUNC() display()
Now you must write FUNC() to invoke it. Or, more frequently, it will have arguments:
#define MIN(x, y) ((x) > (y) ? (x) : (y))
and that can be invoked with:
int min = MIN(sin(p), cos(q));
with cautions about the number of times the arguments are expanded.
See also getc() as macro and C standard library function definition. It includes the standard's explanation of why it is important that the simple name of a function-like macro without a following open parenthesis is not expanded, which is what the quote from the GCC manual is telling you.
When a function-like macro is defined, the open parenthesis must 'touch' the macro name:
#define function_like(a) …
#define object_like (…)
Because there's a space after object_like, the open parenthesis is part of the replacement text, not the start of an argument list. When the function-like macro is invoked, there may be spaces between the macro name and the argument list:
function_like (x) // Valid invocation of function_like macro.
However, if you wrote:
int (function_like)(double a) { return asin(a) + 2 * atanh(a); }
this is not an invocation of the function-like macro because the token after function_like is not an open parenthesis.
There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.
You may define any valid identifier as a macro, even if it is a C keyword. The preprocessor does not know anything about keywords. This can be useful if you wish to hide a keyword such as const from an older compiler that does not understand it. However, the preprocessor operator can never be defined as a macro, and C++'s named operators cannot be macros when you are compiling C++.

Embedding preprocessor directive into function name

I want to embed a preprocessor directive into a function name. Basically I want to make a macro that takes a preprocessor define as argument and concatenates it's defined VALUE to get a function name.
Basically this:
#define PREFIX foo
#define CALL(P, x) _##P_bar(x)
...then
CALL(PREFIX, x) should become _foo_bar(x)
Unfortunately this results in _P_bar instead of _foo_bar.
Is it possible to make it work as above?
The C standard defines special behavior for macro parameters immediately preceded and followed by ## operator. In such case they are not fully expanded. This is why your code did not behave as you expected. To further expand a parameter, you have to use it in a way that it is not immediately preceded or followed by ## operator. Try the following:
#define PREFIX foo
#define CALL2(P,x) _##P##_bar(x)
#define CALL(P, x) CALL2(P,x)
CALL(PREFIX, x)

What do the parentheses around a function name mean?

In one of my project source files, I found this C function definition:
int (foo) (int *bar)
{
return foo (bar);
}
Note: there is no asterisk next to foo, so it's not a function pointer. Or is it?
What is going on here with the recursive call?
In the absence of any preprocessor stuff going on, foo's signature is equivalent to
int foo (int *bar)
The only context in which I've seen people putting seemingly unnecessary parentheses around function names is when there are both a function and a function-like macro with the same name, and the programmer wants to prevent macro expansion.
This practice may seem a little odd at first, but the C library sets a precedent by providing some macros and functions with identical names.
One such function/macro pair is isdigit(). The library might define it as follows:
/* the macro */
#define isdigit(c) ...
/* the function */
int (isdigit)(int c) /* avoid the macro through the use of parentheses */
{
return isdigit(c); /* use the macro */
}
Your function looks almost identical to the above, so I suspect this is what's going on in your code too.
The parantheses don't change the declaration - it's still just defining an ordinary function called foo.
The reason that they have been used is almost certainly because there is a function-like macro called foo defined:
#define foo(x) ...
Using (foo) in the function declaration prevents this macro from being expanded here. So what is likely happening is that a function foo() is being defined with its body being expanded from the function-like macro foo.
The parentheses are meaningless.
The code you show is nothing but an infinite recursion.
When defining a function pointer, you sometimes see strange parentheses that do mean something. But this isn't the case here.

Double slash comment substituition within a macro

I am developing a PIC MCU program on an ansi-compliant compiler (Microchip XC8).
There are two operation modes, determined via macros during compilation time.
So that I don't want to duplicate one function-like macro due to one line of code, I would like to know if there is any way to write a macro such as
#define FOO //
so that when FOO is substituted it will actually cancel the rest of the line.
Writing a function instead of a macro is out of the question because the delay generated by function calls would disrupt the tight timings of my program (around some microseconds).
You can't make a macro expand to comment out the line, no. // in a macro definition is a comment following the definition, it's not expanded, and IIRC there's a rule saying that you cannot construct a // using token-pasting. Even if you can, expanding it doesn't mean that the macro starts a comment. Basically, you don't get to change the comment syntax using macros.
You could do:
#if DO_NOTHING_MODE
#define FOO(ARG1)
#else
#define FOO(ARG1) ARG1
#endif
and use it like:
#define FUNCTION_LIKE_MACRO(ARG1, ARG2) \
required line; \
FOO(optional line;) \
Although a more common idiom is to design the macro to accept an expression as its argument, rather than a whole line:
#if DO_NOTHING_MODE
#define FOO(ARG1) ((void)0)
#else
#define FOO(ARG1) (ARG1)
#endif
and use it like FOO(optional line);
Either way, if the macro argument has commas in it, then the caller needs to enclose them in parentheses FOO((1,2)), although in C99 you can avoid that by making FOO a variadic macro:
#define FOO(...) (__VA_ARGS__)
You can use the #ifndef directive to achieve the same effect:
#ifndef FOO
your_line_of_code
#endif
EDIT: #SteveJessop made me see I didn't pay attention to this sentence of the OP "I don't want to duplicate one function-like macro due to one line of code". Here is what could be done in that case, if duplicating the function-like macro is not wanted:
// When FOO is defined, BLA in FUNC macro is a no-operation (null statement)
#ifndef FOO
#define BLA() a++
#else
#define BLA()
#endif
#define FUNC() \
BLA(); \
b++;
Comments are removed from the source before macro replacement occurs, so there's no way to define a macro exactly like that. However, it is certainly possible to pass an additional parameter into the macro to specify which code it should generate, or conditionally define the macro depending on the mode for which you are compiling.
#define FOO(...) __VA_ARGS__
And then use FOO(your code here) instead of FOO your code here in the macro.
If your platform doesn't have C99, you can instead use
#define FOO(x) x
and just make sure the argument doesn't contain a , not enclosed in ().

Resources