Double slash comment substituition within a macro - c

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 ().

Related

C Macro expansion within a macro

While testing a C software, I'd like to use macros to generate function calls. Using codewarrior 5.2 (very old) compiler -because I don't have choice, I don't know if this is standard behavior.
in macros.h
#define RUNTEST(i) \
testcase_index = i; \
__PREFIX__##_testCase_##i()
in test_foo.c
#include "macros.h"
#define __PREFIX__ foo
RUNTEST(10);
Apparently __PREFIX__ is not expanded, and preprocessor generates a call to __PREFIX___testcase_10(), which of course will fail at linking time.
Copying everything in the same file doesn't seem to change anything.
Is there a simple way out?
Alternative
I also tried #define __PREFIX__() foo to force macro expansion. In that case, it almost works, and now generates foo _testcase_10() (with a space), which of course won't compile.
I've done a simplified version of your question here (without assigning to the testcase index):
.h:
#define PASTER(x, y) x##_testCase_##y
#define EVAL(x, y) PASTER(x, y)
#define RUNTEST(i) EVAL(__PREFIX__, i)
.c
#define __PREFIX__ foo
// whatever
RUNTEST(1);
Explanation:
From the C standard:
6.10.3.1 Argument substitution
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. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
So now that we have this, I'll walk through the expansion of RUNTEST(1):
EVAL(__PREFIX__, i)
PASTER(foo, 1)
foo##_testCase_##1
foo_testCase_1

Function-style macro with no-op if a condition is false

Suppose I have the following construct in multiple places in my code and want to make my code more legible:
#if HAVE_LIBFOOBAR
foobar_func(data);
#endif
I was thinking of writing a function-style macro around this, which would handle the conditionals, making the occurrences in the code look like a regular function call:
foobar_func_if_available(data)
If the condition is true, this would be replaced with a call to the actual function, else it would be a no-op.
Thus, something like:
#if HAVE_LIBFOOBAR
#define foobar_func_if_available(x) foobar_func(x)
#else
#define foobar_func_if_available(x) {}
#endif
Questions:
Does {} work as a no-op? Is it safe from having unintended effects (such as being used in an unbracketed if statement)? If not, what would I use?
Do I have to have two independent #defines wrapped in conditionals, or is there a way to do it the other way round (one #define with the conditionals inside the function-style macro)?
Edit: it has been suggested that this is a duplicate of another question, but in my opinion it is not: the other question asks “what is the problem solved with this construct”, mine is “what construct will solve my problem”. Indeed the other question has a possible solution to my problem, it does not cover all aspects of my question.
Create a dummy function and make the #define point at it (conditionally):
#if HAVE_LIBFOOBAR
#define foobar_func_if_available(x) foobar_func(x)
#else
int dummy(int ignored)
{
return 0;
}
#define foobar_func_if_available(x) dummy(x)
#endif
Or just :
#define foobar_func_if_available(x) 0
You cannot achieve it with a single #define.
You do not need {} as a no-op, you can define an empty expression in a number of ways:
#define foobar_func_if_available(x)
#define foobar_func_if_available(x) ;
#define foobar_func_if_available(x) do{}while(0)
There are circumstances where either of these may cause syntactic issues, but for void functions neither is likely to cause a problem - the solution breaks down for non-void functions however.
A better solution avoiding function-like macros altogether is to define the function body conditionally:
void foobar_func( int n )
{
#if defined HAVE_LIBFOOBAR
// do something
#else
// do nothing
#endif
}
whether the empty function results in no code is a matter for the compiler and the optimisation level applied, but importantly the code will work syntactically in all situations where a call to foobar_func() is valid. To worry about it being a no-op or not is probably sweating the small stuff.
Macros like ((int)0) or ((void)0) are probably the most flexible/safest no-op macros. They're flexible because you can use them
in expressions (unlike do{}while(0)) and they don't break if-else like {} or ; would.
Example of how {} (or ;) macros break if-else:
#define foo() {}
if(1) foo(); else bar(); //syntax error because if(1) {}; else bar(); was pasted
If the macro should emulate an integer returning function, it's better to use a casted integer literal over a plain integer constant as integer constants (and especially zeros) are usable in more contexts (case labels, bitfield sizes, array sizes , null pointer constants) than non-const integer expressions.
You don't need to have two macros as in:
#if HAVE_LIBFOOBAR
#define foobar_func_if_available(x) foobar_func(x)
#else
#define foobar_func_if_available(x) ((void)0) /*if foobar_func returns void*/
#endif
You can put the condition inside the macro:
#define foobar_func_if_available(x) \
(HAVE_LIBFOOBAR?foobar_func(x):((void)0))
Even a very dumb compiler should be able to optimize the constant conditional out.
But if you rely on an empty HAVE_LIBFOOBAR evaluating to 0 inside an #if, then the above won't work -- HAVE_LIBFOOBAR will need to be an integer.
(
You could do
#if !HAVE_LIBFOOBAR
#undef HAVE_LIBFOOBAR
#define HAVE_LIBFOOBAR 0
#endif
#define foobar_func_if_available(x) \
(HAVE_LIBFOOBAR?foobar_func(x):((void)0))
to normalize an empty HAVE_LIBFOOBAR into 0 but unless you will reuse the now assured HAVE_LIBFOOBAR's definedness, it seems like an unnecessary complication over the original two foobar_func_if_available macros.
)

C Macro change every other time

Can a C macro be expressed to expand to a different code block every other time, so that the macro that is written stays the same? (aka without macro variables or macro1 / macro2)
I want
macro
macro
macro
macro
to expand to
function1();
function2();
function1();
function2();
I tried to use #undef followed by #define to alternate what the macro pastes, but quickly found that you cannot have directives in macros.

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.

Resources