Using logical operators with macros - c

I have a piece of code which I want to include if either of two macros are defined
#ifdef MACRO1 || MACRO2
void foo()
{
}
#endif
How do I accomplish this in C?

Besides #ifdef, the preprocessor supports the more general #if instruction; actually, #ifdef MACRO is a shortcut for #if defined(MACRO), where defined is a "preprocessor function" that returns 1 if the macro is defined; so, you can do:
#if defined(MACRO1) || defined(MACRO2)
void foo()
{
}
#endif

#if defined(MACRO1) || defined(MACRO2)

Here the NOT version if needed:
#if !defined(MACRO1) && !defined(MACRO2)
...
#endif

#if defined(Macro 1) + defined(Macro 2) == 1
<Code>
#endif

Related

Is there a way to check that a macro is defined as a specific thing?

As far as I know, #ifdef can only check if a macro is defined, not what a macro is defined as.
#define MY_NUMBER 1
.
.
.
#ifdef MY_NUMBER
function();
#endif
I've tried something like this:
#define MY_NUMBER 1
.
.
.
#ifdef MY_NUMBER 1
function();
#endif
and the compiler issues the following:
warning: extra tokens at end of #ifdef directive
and the value of the macro is not taken into account (it's just ignored).
How do I check if a macro has a specific value?
Just like in conditional statements, you can use equality (==) or inequality (< / > / <= / >=) in your preprocessor directives:
#if MY_NUMBER == 1
function1();
#elif MY_NUMBER == 2
function2();
#else
function3();
#endif

Cannot resolve function-like macro inside conditional compilation block

Consider the following - I want to check with #if #endif whether a
token is defined somewhere in the code.
I am using a CONCAT(input) macro that should glue the constant and changing parts of the token that I want to check.
Unfortunately, the approach presented below causes a compilation error:
error: missing binary operator before token "("
I have found the expressions that can be put inside a #if #endif block:
https://gcc.gnu.org/onlinedocs/cpp/If.html#If
And apparently it states that:
Macros. All macros in the expression are expanded before actual computation of the expression’s value begins.
It turns out that (CONCAT(test)) should be resolved, but it is not.
Is there any workaround allowing to resolve concatenated token names correctly in a conditional compilation block?
#include <stdio.h>
#define CONCAT(input) string##input
#define stringtest 1
int main(void)
{
#if defined(CONCAT(test)) && (CONCAT(test)==1)
printf("OK");
#else
printf("NOT");
#endif
return 0;
}
If you use just: #if CONCAT(test) == 1 it will work and is enought.
The statement #if defined(CONCAT(test)) does not work because CONCAT(test) will be evaluated to stringtest which will be evaluated to 1, and you can't use defined on a numerical constant.
A different situation came to my mind - what if I want to check whether the token is eg. != 1 Then if it is not defined anywhere, the condition will evaluate to true. So there would be no difference between token not defined and token being different than 1.
You could handle == 0 equal to not defined. So you could use: #if CONCAT(test) != 0 && CONCAT(test) != 1 where CONCAT(test) != 0 means defined(CONCAT(test)). That is the only alternative, because you can't get macro expansion work in a #ifdef or #if defined() statement, see this question which is very similar to yours.
The gcc documentation says:
Conditionals written like this:
#if defined BUFSIZE && BUFSIZE >= 1024
can generally be simplified to just #if BUFSIZE >= 1024, since if BUFSIZE is not defined, it will be interpreted as having the value zero.
Also it can be helpful if you check macro expansion by using gcc -E yourSource.cpp.
gcc --help:
-E Preprocess only; do not compile, assemble or link
You can't do that. Only literals can be used.
You should check for macro directly:
#include <stdio.h>
#define CONCAT(input) string##input
#define stringtest 1
int main(void) {
#if stringtest == 1
printf("OK");
#else
printf("NOT");
#endif
return 0;
}
Since you don't need defined check, you can use like this:
#define CONCAT(input) string##input
#define stringtest 1
int main(void) {
#if CONCAT(test) == 1
printf("OK");
#else
printf("NOT");
#endif
return 0;
}

Usage of #ifndef directive

I'm trying to use #ifndef as below.
#ifndef MACRO1 || #ifndef MACRO2
....
#endif
I already tried:
#ifndef (MACRO1 || MACRO2)
..
#endif
But for both cases am getting below error
error: extra tokens at end of #ifndef directive
Use the #if preprocessor directive instead:
#if !defined(MACRO1) || !defined(MACRO2)
#ifdef and #ifndef are special abbreviations for #if defined(...) and #if !defined(...). However, they can only be used for a single macro and do not allow for logical operations. So, if checking for multiple macros, use #if with the defined() operator instead. Being a regular operatior, this can be combined with logical operations, as the for !defined() already does.
You can use following code
#if !defined(MACRO1) || !defined(MACRO2)
#endif
You can use the defined operator in the #if directive to use
expressions that evaluate to 0 or 1 within a preprocessor line.
You can use logical operators in preprocessor directives, but in order to check something defined, use the defined directive:
#if !defined MACRO1 || !defined MACRO2
....
#endif

Difference between preprocessor directives #if and #ifdef

What is the difference (if any) between the two following preprocessor control statements.
#if
and
#ifdef
You can demonstrate the difference by doing:
#define FOO 0
#if FOO
// won't compile this
#endif
#ifdef FOO
// will compile this
#endif
#if checks for the value of the symbol, while #ifdef checks the existence of the symbol (regardless of its value).
#ifdef FOO
is a shortcut for:
#if defined(FOO)
#if can also be used for other tests or for more complex preprocessor conditions.
#if defined(FOO) || defined(BAR)

C Preprocessor testing definedness of multiple macros

I searched the site but did not find the answer I was looking for so here is a really quick question.
I am trying to do something like that :
#ifdef _WIN32 || _WIN64
#include <conio.h>
#endif
How can I do such a thing? I know that _WIN32 is defined for both 32 and 64 bit windows so I would be okay with either for windows detection. I am more interested in whether I can use logical operators like that with preprocessor directives, and if yes how, since the above does not work.
Compiling with gcc I get :
warning: extra tokens at end of #ifdef directive , and it basically just takes the first MACRO and ignores the rest.
Try:
#if defined(_WIN32) || defined(_WIN64)
// do stuff
#endif
The defined macro tests whether or not a name is defined and lets you apply logical operators to the result.
You must use #if and special operator defined
I think it should be possible this way:
#if defined block1 || defined block2 /*or any other boolean operator*/
/*Code*/
#endif
More information here
Use defined:
#if defined(A) || defined(B)
#include <whatever.h>
#endif

Resources