C++ Preprocessor Decisions - c++

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.

Related

How to use "else if" with the preprocessor #ifdef?

In my project the program can do one thing of two, but never both, so I decided that the best i can do for one class is to define it depending of a #define preprocessor variable. The next code can show you my idea, but you can guess that it does not work:
#ifdef CALC_MODE
typedef MyCalcClass ChosenClass;
#elifdef USER_MODE
typedef MyUserClass ChosenClass;
#else
static_assert(false, "Define CALC_MODE or USER_MODE");
#endif
So i can do
#define CALC_MODE
right before this.
I can resign the use of static_assert if needed. How to do this?
Here's a suggestion, based largely on comments posted to your question:
#if defined(CALC_MODE)
typedef MyCalcClass ChosenClass;
#elif defined(USER_MODE)
typedef MyUserClass ChosenClass;
#else
#error "Define CALC_MODE or USER_MODE"
#endif

Combining preprocessor macros and variables

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

Preventing Undefined Macro

In C and C++, when using a macro like so:
#if ( 1 == __MY_MACRO__ )
// Some code
#endif
The compiler will not catch if MY_MACRO is not defined and will consider it 0. This could cause a lot of hidden bugs when the design of the code is intended such that the macro must be defined (non-zero).
Is there away to get to compiler to report this, even if the compiler natively doesn't look for such thing?
Use #if defined(__MY_MACRO__) to test if the macro value is defined.
#ifndef __MY_MACRO__
#error "MY_MACRO NOT DEFINED"
#endif
You can use #ifdef or ifndef to check if a macro is defined of not.
Example :
#ifndef MY_MACRO
# error "MY_MACRO is not defined"
#endif
More informations can be found here : https://gcc.gnu.org/onlinedocs/cpp/Ifdef.html
I have to resort to
#if !defined( __MY_MACRO__ )
MACRO_NOT_DEFINED; //to cause compiler error
#endif
#if ( 1 == __MY_MACRO__ )
//code
#endif
Which looks rather ugly.
Someone I know came up with a clever 1 liner
#if ( (1/defined(_MY_MACRO__) && 1 == _MY_MACRO__ ) )
//code
#endif
If _MY_MACRO__ is not defined, it will cause divide by zero error.
If the macro is used as compile switch try this way.
in a configuration file:
#define FEATURE_1_ENABLED() (1)
#define FEATURE_2_ENABLED() (0)
in place you checking the value:
#if FEATURE_1_ENABLED()
// whatever
#endif
in contrast to your example this does show error when macro is not visible by mistake (at least in my ide)

Preprocessor checking defined

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

Boolean in ifdef: is "#ifdef A && B" the same as "#if defined(A) && defined(B)"?

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