In the source code of stdbool.h in LLVM project, it reads:
/* Don't define bool, true, and false in C++, except as a GNU extension. */
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool, bool, false, true as a GNU extension. */
#define _Bool bool
#define bool bool
#define false false
#define true true
#endif
In the last 4 lines there are three lines of the from #define X X. Why would you do that? What difference does it make? Wouldn't this force compiler to just replace, say, true with true?
The only reason I can think of is, that preprocessor statements like
#ifdef bool
// do some stuff or define bool
#endif
in other c files include afterwards will work proper and not trying to redefine bool in another way like
#define bool int
which would interfere with the first definition
#define X X
has the effect that "the pre-processor conditional"*:
#ifdef X
is "true" "succeeds".*
* update
It would make the difference that true, false etc are now macros. So code like this
#if defined(true)
...
#else
...
#endif
would be affected.
Related
is there a way/trick to make a #define directive evaluate some condition?
for example
#define COM_TIME_DO(COND, BODY) \
#if (COND) BODY
#else
#endif
it's ok also to use template but body must be an arbitrary (correct in the context is used to) piece of code, simply just present or not in the source depending of COND.
as it is now the previous code doesn't even compile.
the goal of this question is primarly a better knowledge of the language and what i'm trying to do is define a debug macro system that i can activate selectively on certain parts of code for example:
A.hpp
#define A_TEST_1 1
#define A_TEST_2 0
Class A {
...
COM_TIME_DO(A_TEST_1,
void test_method_1();
)
COM_TIME_DO(A_TEST_2,
void test_method_2();
)
};
A.cpp
COM_TIME_DO(A_TEST_1,
void A::test_method_1() {
...
})
COM_TIME_DO(A_TEST_2,
void A::test_method_2() {
...
})
i was just asking if it was POSSIBLE because i like it more than the #if ... #endif.
If the expression of the condition will always expand to 1 or 0 (or some other known set of values) it is possible to implement such a macro.
#define VALUE_0(...)
#define VALUE_1(...) __VA_ARGS__
#define COM_TIME_DO_IN(A, ...) VALUE_##A(__VA_ARGS__)
#define COM_TIME_DO(A, ...) COM_TIME_DO_IN(A, __VA_ARGS__)
However, do not use such code in real life. Use #if and write clear, readable and maintainable code that is easy to understand for anyone.
is there a way/trick to make a #define directive evaluate some condition?
This depends on what the condition actually is.
Since you mentioned #if I'm assuming you'd like to evaluate an integer constant expressions.
Doing this in a macro single macro isn't possible, without implementation defined _Pragmas, but you can do it with an include + a macro definition:
#define COM_TIME_DO ((1 > 2), true, false)
#include "com-time-do.h"
// ^-- generates: false
#define COM_TIME_DO ((1 == 1), true_func();, false_func();)
#include "com-time-do.h"
// ^-- generates: true_func();
where com-time-do.h is defined as follows:
// com-time-do.h
#define SCAN(...) __VA_ARGS__
#define SLOT_AT_COND(a,b,c) a
#define SLOT_AT_THEN(a,b,c) b
#define SLOT_AT_ELSE(a,b,c) c
#if SCAN(SLOT_AT_COND COM_TIME_DO)
SCAN(SLOT_AT_THEN COM_TIME_DO)
#else
SCAN(SLOT_AT_ELSE COM_TIME_DO)
#endif
#undef COM_TIME_DO
Although, as KamilCuk said, please write reasonable code and don't use this.
This question already has answers here:
Why does clang's stdbool.h contain #define false false
(2 answers)
Closed 6 years ago.
stdbool.h contains this code:
#if __cplusplus < 201103L
/* Defining these macros in C++98 is a GCC extension. */
#define bool bool
#define false false
#define true true
#endif
Why does gcc need to redefine standard C++ types?
Although #define fnord fnord won't generally change the way the identifier fnord is processed, it will cause #ifdef fnord to report the macro as defined. If other code might do something like
#ifndef true
#define true 1
#endif
Having a #define true true would cause such conditional definition to be skipped.
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 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).
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.