Conditional inside C macro? - c-preprocessor

Is there any way to do this conditional at compile time instead of at runtime?
"flag" will always be a constant. A() and B() are macros.
#define DEMO(flag, p) if (flag) A(p); else B(p)
Why do I want to do this? Because macro A may or may not exist, depending on the underlying hardware (macro A controls hardware on a microcontroller).
If DEMO is called with "flag" that evaluates to false, it doesn't matter - it should compile. But if DEMO is called with "flag" that evaluates to true, I want to see a build error.
ADDED:
The intended use is like this:
DEMO(true, p); // this should cause a build error
DEMO(false, p); // this should compile OK
DEMO(0, p); // should be OK
DEMO(1 == 2, p); // should be OK
DEMO(1 == 1, p); // should cause a build error
The passed parameter is always a constant, but not always the same constant.

Is there any way to do this conditional at compile time instead of at runtime?
Sure:
// add or remove this definition
#define flag
#if defined(flag)
#define DEMO(p) A(p)
#else
#define DEMO(p) B(p)
#endif
ADDED in response to OP's addition:
#define DEMOfalse(p) B(p)
#define DEMOtrue(p) A(p)
#define DEMO(flag,p) DEMO##flag(p)
This uses the "stringizing" operator (##) which replaces ##flag with the actual source code text you call the macro with.
DEMO(true,p) will expand to DEMOtrue(p), which expands to A(p). If you pass true and A is not defined, your build will fail.
DEMO(false,p) will expand to DEMOfalse(p), then B(p), which will build whether or not A is defined.
EDIT in response to OP's edit:
A macro cannot contain preprocessor statements (well, it can, but they won't processed by the preprocessor), so there's no way to put a compile time conditional in the macro, hence the approaches shown above.

Instead of copying the whole macro body, you can create sub-macros to be conditionally-compiled:
Duplicate part of the code:
#ifdef FLAG
# define COND_MACRO(a, b) ((a) == (b))
#else
# define COND_MACRO(a, b) ((a) < (b))
#endif
#define MY_MACRO(a, b)
if (COND_MACRO(a, b))
do_smth();
Duplicate the whole code:
#ifdef FLAG
# define MY_MACRO(a, b)
if ((a) == (b))
do_smth();
#else
# define MY_MACRO(a, b)
if ((a) < (b))
do_smth();
#endif

Related

print only if _DEBUG defined: c

I want to print info only if _DEBUG is defined
#define DEBUG(y) y == true ? #define _DEBUG true : #define _DEBUG false
#ifdef _DEBUG
#define Print(s) printf(s);
#endif
Getting Error:
error: '#' is not followed by a macro parameter
Any suggestion how to achieve this with pre-processor directives?
I intend to use it from my main as:
DEBUG(true);
Print("Inside main in debug mode");
You cannot redefine a MACRO at run-time.
Neither you can have a #define inside of another #define, like you try in the first line of your code.
You can do something like this:
#ifdef _DEBUG
#define Print(s) printf("%s", s)
#else
#define Print(s)
#endif
And use it from your main as:
#define _DEBUG
Print("Inside main in debug mode");
#undef _DEBUG
Print("Inside main debug mode off");
If you really need to switch debug on and off at run-time, your can do something like this:
void PrintIf(BOOL dbg, char * msg)
{
if (dbg)
{
printf("%s", msg)
}
}
And use it like this
y = TRUE;
PrintIf(y,"Inside main in debug mode");
y = FALSE;
PrintIf(y,"Inside main debug mode off");
Try this:
#ifdef DEBUG
#define Print(s) printf("%s", s)
#else
#define Print(s)
#endif
Then:
#define DEBUG
Print("Inside main in debug mode");
I intend to use it from my main as:
DEBUG(y);
Print("Inside main in debug mode");
Sorry, but ifdef are compile time (not run-time). You could use a global bool and runtime checking to enable and disable debug.
You can't create preprocessor statements with macros as you are trying to do; it doesn't work and isn't allowed. For conditional printing, see C #define macro for debug printing.
The problem occurs here:
#define DEBUG(y) y == true ? #define _DEBUG true : #define _DEBUG false
When introducing #defines, the definition # occurs at the beginning of the line, not later (although) preprocessors generally allow one or two line indents.) You need to rewrite your #define eliminating the ternary operator simply as:
#ifdef _DEBUG
#define Print(s) printf(s);
#endif
While you may extend you defines with macros, you often introduce additional errors. It is generally better to stick to wrapping your _DEBUG code simply in #ifdef statements:
#ifdef _DEBUG
fprintf (stderr, "your error messages\n"); // using standard printf/fprintf instead of macros
...
#endif /* _DEBUG */
Macros are substituted at preprocessing stage and
#define DEBUG(y) y == true ? #define _DEBUG true : #define _DEBUG false
this statement will be evaluated at compile time.
Conditional operator (ternary operator) are evaluated at compile time. So you are getting this error and # operator must always be used at the beginning of the statement that is the second mistake you are doing.
You can better use it this way
#define DEBUG
printf ("true");
#else
printf ("false");
You can also define this macro dynamically by using the gcc option -D
gcc -D DEBUG filename.c -o outputFile
The first line is incorrect:
#define DEBUG(y) y == true ? #define _DEBUG true : #define _DEBUG false
You cannot use #define inside preprocessor directive (like another #define)
And it does not make sense, since preprocessing happens before the real compilation (so before run time, when your y has some value). Read the cpp preprocessor documentation. Recall that sometimes the preprocessor is even a different program (/lib/cpp) but is today the first phase of most C compilers.
You could ask for the preprocessed form of your source code (e.g. with gcc -C -E source.c > source.i if using GCC) and look at that form with a pager (less source.i) or your editor.

What does the c precompiler do with macros defined as (void)0

I have some macros that are defined based on compiler flags. I'm trying to decide whether I would rather have the macro defined as (void)0 or have it undefined and cause a compile time error.
i.e.
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) (void)0
#endif
int main(void) {
...
PRINTF("something");
...
}
vs.
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#endif
int main(void) {
...
#ifdef DEBUG
PRINTF("something");
#endif
...
}
I'm not sure which technique I prefer. On one hand wrapping every PRINTF statement with #ifdef's would be ugly. On the other hand it would be nice to know at compile time if I've called a function that doesn't really work in the context.
I think the deciding factor will be whether or not having the (void)0 macros is going to affect the size of the executable.
When the code is compiled, what happens to the (void)0's? If PRINTF is defined as (void)0, does that mean the executable is going to contain some sort of (void)0 instruction or will it be completely ignored?
(void) 0;
is an expression statement with no side-effect. Any sane implementation will optimize this statement out (what else an implementation could do with such a statement?).
Having (void) 0 as a macro definition is endorsed by the C Standard as it appears in (C11) 7.2p1 for assert macro definition if NDEBUG is defined:
#define assert(ignore) ((void)0)
Note that defining:
#define PRINTF(...) (void)0
instead of
#define PRINTF(...)
has an advantage. In the first case, you have an expression (like a function that returns no value) and so it is usable for example in a comma expression or in a conditional expression.
For example:
// Comma expression
printf("test"), PRINTF("Hi Dennis");
// Conditional expression
test-expr ? perror("Hello") : PRINTF("world");
This two expression statements are only valid with the former PRINTF definition (with (void) 0).
It'll be completely ignored, you can confirm this by looking at the assembly output (gcc -S will generate file.s, the asm output), compare with and without the (void)0 line and see that it is completely the same.
A half way decent compiler will optimise away dead (unreachable) code, so you can:
#ifdef DEBUG
#define PRINTF(...) if (1) { printf(__VA_ARGS__) ; }
#else
#define PRINTF(...) if (0) { printf(__VA_ARGS__) ; }
#endif
which has the big advantage of allowing the compiler to check the debug code, no matter whether you are working with/without your DEBUG turned on -- which reduces the risk of ending up with painful teeth marks in your backside.

#define IDENTIFIER without a token

What does the following statement mean:
#define FAHAD
I am familiar with the statements like:
#define FAHAD 1
But what does the #define statement without a token signify?
Is it that it is similar to a constant definition?
Defining a constant without a value acts as a flag to the preprocessor, and can be used like so:
#define MY_FLAG
#ifdef MY_FLAG
/* If we defined MY_FLAG, we want this to be compiled */
#else
/* We did not define MY_FLAG, we want this to be compiled instead */
#endif
it means that FAHAD is defined, you can later check if it's defined or not with:
#ifdef FAHAD
//do something
#else
//something else
#endif
Or:
#ifndef FAHAD //if not defined
//do something
#endif
A real life example use is to check if a function or a header is available for your platform, usually a build system will define macros to indicate that some functions or headers exist before actually compiling, for example this checks if signal.h is available:
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif/*HAVE_SIGNAL_H*/
This checks if some function is available
#ifdef HAVE_SOME_FUNCTION
//use this function
#else
//else use another one
#endif
Any #define results in replacing the original identifier with the replacement tokens. If there are no replacement tokens, the replacement is empty:
#define DEF_A "some stuff"
#define DEF_B 42
#define DEF_C
printf("%s is %d\n", DEF_A, DEF_B DEF_C);
expands to:
printf("%s is %d\n", "some stuff", 42 );
I put a space between 42 and ) to indicate the "nothing" that DEF_C expanded-to, but in terms of the language at least, the output of the preprocessor is merely a stream of tokens. (Actual compilers generally let you see the preprocessor output. Whether there will be any white-space here depends on the actual preprocessor. For GNU cpp, there is one.)
As in the other answers so far, you can use #ifdef to test whether an identifier has been #defined. You can also write:
#if defined(DEF_C)
for instance. These tests are positive (i.e., the identifier is defined) even if the expansion is empty.
#define FAHAD
this will act like a compiler flag, under which some code can be done.
this will instruct the compiler to compile the code present under this compiler option
#ifdef FAHAD
printf();
#else
/* NA */
#endif

Is there a way to both check a macro is defined and it equals a certain value at the same time

I regularly use object-like preprocessor macros as boolean flags in C code to turn on and off sections of code.
For example
#define DEBUG_PRINT 1
And then use it like
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
However, it comes a problem if the header file that contains the #define is forgotten to be included in the source code. Since the macro is not declared, the preprocessor treats it as if it equals 0, and the #if statement never runs.
When the header file is forgotten to be included, non-expected, unruly behaviour can occur.
Ideally, I would like to be able to both check that a macro is defined, and check that it equals a certain value, in one line. If it is not defined, the preprocessor throws an error (or warning).
I'm looking for something along the lines of:
#if-def-and-true-else-throw-error(DEBUG_PRINT)
...
#endif
It's like a combination of #ifdef and #if, and if it doesn't exist, uses #error.
I have explored a few avenues, however, preprocessor directives can't be used inside a #define block, and as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
This may not work for the general case (I don't think there's a general solution to what you're asking for), but for your specific example you might consider changing this sequence of code:
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
to:
if (DEBUG_PRINT == 1) {
printf("%s", "Testing");
}
It's no more verbose and will fail to compile if DEBUG_PRINT is not defined or if it's defined to be something that cannot be compared with 1.
as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
It can't be an error because the C standard specifies that behavior is legal. From section 6.10.1/3 of ISO C99 standard:
After all replacements due to macro expansion and the defined unary
operator have been performed, all remaining identifiers are replaced with the pp-number
0....
As Jim Balter notes in the comment below, though, some compilers (such as gcc) can issue warnings about it. However, since the behavior of substituting 0 for unrecognized preprocessor tokens is legal (and in many cases desirable), I'd expect that enabling such warnings in practice would generate a significant amount of noise.
There's no way to do exactly what you want. If you want to generate a compilation failure if the macro is not defined, you'll have to do it explicitly
#if !defined DEBUG_PRINT
#error DEBUG_PRINT is not defined.
#endif
for each source file that cares. Alternatively, you could convert your macro to a function-like macro and avoid using #if. For example, you could define a DEBUG_PRINT macro that expands to a printf call for debug builds but expands to nothing for non-debug builds. Any file that neglects to include the header defining the macro then would fail to compile.
Edit:
Regarding desirability, I have seen numerous times where code uses:
#if ENABLE_SOME_CODE
...
#endif
instead of:
#ifdef ENABLE_SOME_CODE
...
#endif
so that #define ENABLE_SOME_CODE 0 disables the code rather than enables it.
Rather than using DEBUG_PRINT directly in your source files, put this in the header file:
#if !defined(DEBUG_PRINT)
#error DEBUG_PRINT is not defined
#endif
#if DEBUG_PRINT
#define PrintDebug([args]) [definition]
#else
#define PrintDebug
#endif
Any source file that uses PrintDebug but doesn't include the header file will fail to compile.
If you need other code than calls to PrintDebug to be compiled based on DEBUG_PRINT, consider using Michael Burr's suggestion of using plain if rather than #if (yes, the optimizer will not generate code within a false constant test).
Edit:
And you can generalize PrintDebug above to include or exclude arbitrary code as long as you don't have commas that look like macro arguments:
#if !defined(IF_DEBUG)
#error IF_DEBUG is not defined
#endif
#if IF_DEBUG
#define IfDebug(code) code
#else
#define IfDebug(code)
#endif
Then you can write stuff like
IfDebug(int count1;) // IfDebug(int count1, count2;) won't work
IfDebug(int count2;)
...
IfDebug(count1++; count2++;)
Yes you can check both:
#if defined DEBUG && DEBUG == 1
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
In this example even when #define DEBUG 0 but it is not equal to 1 thus nothing will be printed.
You can do even this:
#if defined DEBUG && DEBUG
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
Here if you #define DEBUG 0 and then D(1,2,3) also nothing will be printed
DOC
Simply create a macro DEBUG_PRINT that does the actual printing:
#define DEBUG_PRINT(n, str) \
\
if(n == 1) \
{ \
printf("%s", str); \
} \
else if(n == 2) \
{ \
do_something_else(); \
} \
\
#endif
#include <stdio.h>
int main()
{
DEBUG_PRINT(1, "testing");
}
If the macro isn't defined, then you will get a compiler error because the symbol is not recognized.
#if 0 // 0/1
#define DEBUG_PRINT printf("%s", "Testing")
#else
#define DEBUG_PRINT printf("%s")
#endif
So when "if 0" it'll do nothing and when "if 1" it'll execute the defined macro.

Function-like macro definition in C

I'd like to define a function like MACRO . i.e.
#define foo(x)\
#if x>32\
x\
#else\
(2*x)\
#endif
that is,
if x>32, then foo(x) present x
else, foo(x) present (2*x)
but my GCC complains about:
int a = foo(31);
I think C preprocessor should be handle this correctly. since at compile time, it knows x=33. it could replace foo(33) with (2*33)
You can as follows
#define foo(x) ((x) > 32 ? (x) : (2 * (x)))
But that evaluates x multiple times. You can instead create a static function, which is cleaner
static int foo(int x) {
if(x > 32)
return x;
return 2 * x;
}
Then you are also able to pass things to foo that have side effects, and have the side effect happen only one time.
What you have written is using the #if, #else and #endif preprocessor directives, but you need to use language constructs if you pass variables to the macro and want to evaluate their values. Using if, and else statements as in the actual language constructs don't work either, because control flow statements don't evaluate to values. In other words, an if statement is steering control flow only ("if A, then execute B, else execute C"), not evaluating to any values.
#define \
foo(x) \
({ \
int xx = (x); \
int result = (xx > 32) ? xx : (2*xx); \
result; \
})
int a = foo(31);
Expands out to
int a = if 31>32
31
else
(2*31)
endif;
That's how C macros work, via simple, dumb substitution. If you expect gcc to do anything more complex or intelligent with them, then your expectation is erroneous.
Given that, it's easy to see why your code won't work. An alternative that would suffice for this example would be:
#define foo(x) (x > 32 ? x : 2*x)
On the other hand, I would question whether macros are really the appropriate tool for such a thing to begin with. Just put it in the function and the compiler will inline the code if it thinks it will speed it up.
Consider:
int x = rand()
int y = foo( x );
x is not known at compile time.
The problem is not about the theory: provided that you, for some reason, want to have a macro that expands differently according to the value of a parameter passed to it, and this parameter is a constant, known to the macro preprocessor, there's no reason why it couldn't work... for a generic macro processor... But cpp unluckly does not allow the presence of other macro processor "commands" into a macro definition...
So your
#define foo(x) \
#if x>32 \
x \
#else \
2*x \
#endif
does not expand to
#if X>32
X
#else
2*X
#endif
where X is the known parameter (so change X to e.g. 31), which requires another pass by the preprocessor.
Moreover newlines are ignored, while they are important for such an use; otherwise, the following could be considered as a trick (that need another preprocessing pass however)
#define foo(x,y) \
y if x>32 \
x \
y else \
2*x \
y endif
that with foo(20,#) produces
# if 20>32 20 # else 2*20 # endif
which would work, if it would be
# if 20>32
20
# else
2*20
# endif
... but it is not (and as said, the output of the preprocessor must be feeded to the preprocessor again...)
So my answer is that if you need these things, you can't use the C preprocessor; you should use a uncommon (not standard?) C preprocessor, or just another macro processor, and if you need the sort of things that "cpp" has to "integrate" itself with C, then you can't use a generic one (like M4) so easily...

Resources