Macro for function and function pointer declarations? - c

I'm trying to create a Macro function for defining function pointers , functions etc.
Here's what I'm trying to do:
#define PRO_SIGNAL_MAX 5
#define PRO_SIGNAL( func, param ) (*func [ PRO_SIGNAL_MAX ])(param)
I want to use this to declare an array of function pointers of size PRO_SIGNAL_MAX.
So, when I use this here:
void PRO_SIGNAL( paint, (Pro_Window*) );
I want it to generate:
void (*paint [ 5 ])(Pro_Window*) ;
but it isn't working quite as I planned, I get this error:
pro_window.c|16|error: expected declaration specifiers or '...' before '(' token|
What exactly is the problem?

Omit the parentheses around Pro_Window*:
void PRO_SIGNAL(paint, Pro_Window*);
Macro parameters are substituted literally, so you ended up with:
void (*paint[PRO_SIGNAL_MAX])((Pro_Window*));
which is a syntax error.
Also, it is a good practice to enclose macro parameters in parentheses in the macro itself, since you never know whether the caller will pass an expression or a single token:
#define PRO_SIGNAL(func, param) (*(func)[PRO_SIGNAL_MAX])(param)

Its the (Pro_Window*) part. Your PRO_SIGNAL( paint, (Pro_Window*) ) will expand to
(*paint [ PRO_SIGNAL_MAX ])((Pro_Window*))
I suppose the compile is not happy about the nested parenthesis.
When baffled by macro expansion, it's often good to look at what the preprocessor actually fed the compiler. How to generate the preprocessed code varies with compilers, though.

Related

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++.

Function-like C macro without parentheses

I have encountered the following debug macro in an embedded device codebase:
extern void DebugPrint(uint8_t *s);
#define DEBUG_MSG(x) do { PRINT_CURRENT_TIME; \
DebugPrint x ; } while(0)
Since there are no parentheses around x in the macro body (at the DebugPrint x part), all calls to this macro (all over the codebase) add another set of parentheses around strings:
DEBUG_MSG(("some debug text"));
Is there any reason to do this? Does it simplify optimizing away these calls in release builds, or something like that? Or is it just plain nonsense?
I thought perhaps there would be additional overloads of DebugPrint with more arguments, but there are none.
Here's a theory:
The preprocessor parses the arguments of a macro expansion in a way that mimics the compiler's expression parsing. In particular it parses terms in parentheses as a single argument.
So the DEBUG_MSG author's intention might have been to enforce the use of parentheses.
This might make sense when the DebugPrint print function would actually be a printf style variadic function. You could call the function with a single string literal or with a variable number of arguments:
DEBUG_MSG(("reached this point in code"));
DEBUG_MSG(("value of x = %i", x));
But this is pure speculation. Can't you just ask the author?
I believe that no. Macros are replaced by the compiler, so they have nothing to do with execution speeds. This:
#define MACRO(x) do_something(x)
MACRO("test");
Is no different than this
#define MACRO(x) do_something x
MACRO(("test"));
Since the compiler will replace them both with the same output:
do_something("test");
which will then compile to produce the same object code.

how to concat a space with a symbol using c macro

#define var(N) variable ## N
var(1) got variable1
I want to get variable, how can I define the macro?
var( ) works, but it always give a warning. is there any other solutions?
In fact the version that you presented always needs a non-empty argument for N. If you have a modern C compiler you can use this construct:
#define var(...) variable ## __VA_ARGS__
This accepts empty arguments and you should be fine.
"modern" here means C as of 1999.
Don't use the argument inside the macro:
#define var(n) variable

How to pass a macro's result to another macro?

I have two macros in my C code the helps me to compose the name of certain variables. As an example, consider the following:
#define MACROA(name) A_##name
#define MACROB(name) B_##name
void *MACROB(MACROA(object));
So, I'm trying to declare a variable called B_A_object. However, this doesn't work and the compiler throws me the message:
object.c:27:21: error: a parameter list without types is only allowed in a function definition
void *MACROB(MACROA(object));
^
object.c:26:26: note: expanded from macro 'MACROB'
#define MACROB(name) B_##name
^
So, it seems the preprocessor is not taking the result of MACROA(object), but it is considering the expression itself so that it tries to make B_MACROA(object). So, what do I have to do to make the preprocessor consider the result of a macro passed to another macro?
The concatenation operator acts weird. It concatenates first and evaluates later:
void *MACROB(MACROA(object)); // The original line
void *B_MACROA(object); // Becomes this, nothing more to expand
You can solve it this way:
#define CONC(a,b) a ## b
#define MACROA(name) CONC(A_, name)
#define MACROB(name) CONC(B_, name)

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.

Resources