I can check predefined value like:
#ifdef SOME_VAR
// Do something
#elif
// Do something 2
#endif
If I have to check 2 values instead of 1. Are there any operator:
#ifdef SOME_VAR and SOME_VAR2
// ...
#endif
Or I have to write:
#ifdef SOME_VAR
#ifdef SOME_VAR2
// At least! Do something
#endif
#endif
The standard short-circuiting and operator (&&) along with the defined keyword is what is used in this circumstance.
#if defined(SOME_VAR) && defined(SOME_VAR2)
/* ... */
#endif
Likewise, the normal not operator (!) is used for negation:
#if defined(SOME_VAR) && !defined(SOME_OTHER_VAR)
/* ... */
#endif
You can use the defined operator:
#if defined (SOME_VAR) && defined(SOME_VAR2)
#endif
#ifdef and #ifndef are just shortcuts for the defined operator.
You can write:
#if defined(SOME_VAR) && defined(SOME_VAR2)
// ...
#endif
#if defined(A) && defined(B)
One alternative is to get away from using #ifdef and just use #if, since "empty symbols" evaluate to false in the #if test.
So instead you could just do
#if SOME_VAR && SOME_OTHER_VAR
// -- things
#endif
But the big side effect to that is that you not only need to #define your variables, you need to define them to be something. E.g.
#define SOME_VAR 1
#define SOME_OTHER_VAR 1
Commenting out either of those #defines will make the above #if test fail (insofar as the enclosed stuff not being evaluated; the compiler will not crash or error out or anything).
Related
In Visual Studio 2015, #define USE_SQLDB directive doesn't do what I expect.
I have a minimal example to explain the issue
#include "stdafx.h"
#define USE_SQLITE
//#define USE_MYSQL
#define USE_SQLDB (defined(USE_SQLITE) || defined(USE_MYSQL))
int main()
{
#if defined(USE_SQLITE)
puts("SQLITE"); // OK
#endif
#if defined(USE_MYSQL)
puts("MYSQL"); // Grayed out - OK
#endif
// Should expand to defined(USE_SQLITE) || defined(USE_MYSQL)
#if USE_SQLDB
puts("SQLITE or MYSQL"); // Grayed out - NOT OK
#endif
#if defined(USE_SQLITE) || defined(USE_MYSQL)
puts("SQLITE or MYSQL"); // OK
#endif
return 0;
}
I expect the USE_SQLDB to be true, but it isn't.
What's wrong here?
this is simply not valid preprocessor stuff
#define USE_SQLDB (defined(USE_SQLITE) || defined(USE_MYSQL))
you are mixing c and preproc. You need
#if defined(USE_SQLITE) || defined(USE_MYSQL)
#define USE_SQLDB
#endif
It is undefined behavior: Ref
If the defined operator appears as a result of a macro expansion, the
C standard says the behavior is undefined.
and from MSDN:
The defined directive can be used in an #if and an #elif directive,
but nowhere else.
In my C++ code I have to execute certain code under two conditions: because of a preprocessor macro OR a boolean variable check. For example:
bool done=false;
#ifdef _DEBUG
executeDebugCode();
done=true;
#endif
if (inputParam && !done)
executeDebugCode();
Is there a way to write the above code in a more elegant way, without repeating the executeDebugCode() function call two times?
EDIT:
the executeDebugCode() function should be executed once, and if one of the two condition is met. For example a function that should be executed in DEBUG mode only, that could be set by preprocessor macro or command line parameter.
Assuming that you want to execute this code only once, if at least one of these conditions is true:
if ( inputParam
#ifdef DEBUG
|| true
#endif
)
{
executeDebugCode();
}
The form I see most for this, and which tends to work well, is do make the exact check performed depend on _DEBUG, so you'd get:
#ifdef _DEBUG
#define SHOULD_EXECUTE_DEBUG_CODE() 1
#else
#define SHOULD_EXECUTE_DEBUG_CODE() inputParam
#endif
if (SHOULD_EXECUTE_DEBUG_CODE())
executeDebugCode();
Note that if inputParam is a local variable (as Sambuca points out in the comments), this macro SHOULD_EXECUTE_DEBUG_CODE cannot be used in other functions, and for maintainability, it may be worth adding #undef SHOULD_EXECUTE_DEBUG_CODE at the end of the function to prevent accidental misuse.
How about something like this :
bool debugEnabled = inputParam;
#ifdef _DEBUG
debugEnabled = true;
#endif
if (debugEnabled)
executeDebugCode()
ie. use one flag to control the code behavior, but allow that flag to be set in different ways.
My approach would be something like this
#ifdef _DEBUG
#define SHOULD_EXECUTE 1
#else
#define SHOULD_EXECUTE 0
#endif
if (SHOULD_EXECUTE || inputParam) {
executeDebugCode();
}
This way your if-statement shows right away that you're checking on a preprocessor define and another (boolean) condition.
This will not generate any overhead in runtime if DEBUG is not enabled.
#ifdef _DEBUG
#define MY_DEBUG true
#else
#define MY_DEBUG false
#endif
if ( inputParam || MY_DEBUG )
executeDebugCode();
I have some C++ code, and want to perform an action if the __APPLE__ or __linux macros are defined.
If I did it as a normal if conditional, it would be easy using ||:
if (something || something) { .. code .. }
But as of what I know there is no || operator for #ifdef statements. How would I check if __APPLE__ or __linux is defined using a single #ifdef statement?
You can't in a single #ifdef would a single #if do instead?
#if defined(__APPLE__) || defined(__linux)
this also works if you prefer
#if defined __APPLE__ || defined __linux
In my C++ there is.
#if defined(__APPLE__) || defined(__linux)
// ...
#endif
Sorry I know this is basic, but perhaps it doesn't exist or I'm not googling the right words.
Is there and an if not (is that ifndef?) an AND and an OR so I could do something like:
if not DEBUG and MACOS
I think something like #if !defined(DEBUG) && defined(MACOS) should do it.
#ifndef and #if do different things so it depends on what you want. #ifndef is true when there is no defined preprocessor symbol that matches the name following. #if is true when the following preprocessor expression evaluates to non-zero.
You can use the standard && and || operators.
#if !defined(DEBUG) && defined(MACOS)
#error "Ouch!"
#endif
tests, if those macros/values are defined (even set to 0 means defined). Leave out the "defined()" and test again a value, depending on your macros, like
#if DEBUG==0 && MACOS==1
#error "Spam!"
#endif
#if !DEBUG && MACROS
or
#if !DEBUG & !MACROS
depending on what you are looking for. defined() can also help
#if !defined(DEBUG) && defined(MACROS)
#if !(defined(DEBUG) && defined(MACOS))
or
#if !defined(DEBUG) && !defined(MACOS)
depending on what you're trying to evaluate.
#if, #else and #endif are general.
Use #define to declare and #undef to undeclare.
Use #ifdef to check if is declared and #ifndef to check, if is not declared.
Example:
#ifndef LABEL
#define LABEL some_value // declares LABEL as some_value
#else
#undef LABEL // undeclare previously declared LABEL...
#define LABEL new_value // to declare a new_value
#endif
Check out the Boost preprocessing library. It can accomplish a large number of tasks using the preprocessor.
In C++, is this:
#ifdef A && B
the same as:
#if defined(A) && defined(B)
?
I was thinking it wasn't, but I haven't been able to find a difference with my compiler (VS2005).
They are not the same. The first one doesn't work (I tested in gcc 4.4.1). Error message was:
test.cc:1:15: warning: extra tokens at
end of #ifdef directive
If you want to check if multiple things are defined, use the second one.
Conditional Compilation
You can use the defined operator in
the #if directive to use expressions
that evaluate to 0 or 1 within a
preprocessor line. This saves you from
using nested preprocessing directives.
The parentheses around the identifier
are optional. For example:
#if defined (MAX) && ! defined (MIN)
Without using the defined operator,
you would have to include the
following two directives to perform
the above example:
#ifdef max
#ifndef min
The following results are the same:
1.
#define A
#define B
#if(defined A && defined B)
printf("define test");
#endif
2.
#ifdef A
#ifdef B
printf("define test");
#endif
#endif
For those that might be looking for example (UNIX/g++) that is a little different from the OP, this may help:
`
#if(defined A && defined B && defined C)
const string foo = "xyz";
#else
#if(defined A && defined B)
const string foo = "xy";
#else
#if(defined A && defined C)
const string foo = "xz";
#else
#ifdef A
const string foo = "x";
#endif
#endif
#endif
#endif
As of VS2015 none of the above works. The correct directive is:
#if (MAX && !MIN)
see more here