How to globally #define a preprocessor variable? - c++

I'm programming an Arduino sketch in C++. I want the user to be able to #definea constant directly in the sketch.ino file which will be needed to compile the code. The Arduino IDE uses a g++ compiler.
Let's assume we have three files:
sketch.ino
sketch.h
sketch.cpp
In sketch.h I defined
#define OPTION_1 0
#define OPTION_2 1
#define OPTION_3 2
#define OPTION_4 3
#define SLOW 0
#define FAST 1
In sketch.ino the user then defines MYOPTION:
#define MYOPTION OPTION_2
In sketch.h I use the variable to define macros:
#if MYOPTION == OPTION_1 | MYOPTION == OPTION_2
#define SPEED FAST
#else
#define SPEED SLOW
#endif
In sketch.cpp I use it to improve time critical code:
MyClass::foo() {
// do something
#if SPEED == FAST
// do more
#if MYOPTION == OPTION_2
// do something extra
#endif
#endif
#if MYOPTION == OPTION_4
// do something else
#endif
}
Unfortunately the definition of MYOPTION doesn't seem to be recognized inside sketch.cpp. Hower sketch.cpp does recognize variables defined in sketch.h. Is there a way to define preprocessor variables globally, so they can be accessed in any file that uses them?

Move the option definitions to a separate file, e.g. options.h. You could also define them in sketch.ino if you like.
Include options.h in sketch.ino and sketch.h.
Move all the code that relies on the MYOPTION macro from sketch.cpp to sketch.h.
Define MYOPTION in sketch.ino before including sketch.h:
#include "options.h"
#define MYOPTION OPTION_2
#include "sketch.h"
Here's an example of a popular library that uses this technique:
https://github.com/PaulStoffregen/Encoder
It allows the user to configure the use of interrupts from the sketch via the ENCODER_DO_NOT_USE_INTERRUPTS and ENCODER_OPTIMIZE_INTERRUPTS macros.

Related

define macro with conditional evaluation in C/C++

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.

how to comment values under #ifdef in one place

let's imagine we have a C++ project that should work on several platforms (for example, arm/arm64) and we need to have target-specific values for each of them.
Right now we do:
#ifdef PLATFORM_ARM
#define TIMEOUT_VALUE 0
#define OUR_MAGIC_VALUE 1
#elif PLATFORM_ARM64
#define TIMEOUT_VALUE 2
#define OUR_MAGIC_VALUE 3
#endif
where could I place a comment for each defined name that it could be accessed from each definition?
Note: I can't define each value in its own #ifdef like
// a comment for TIMEOUT_VALUE
#ifdef PLATFORM_ARM
#define TIMEOUT_VALUE 0
#elif PLATFORM_ARM64
#define TIMEOUT_VALUE 2
#endif
// a comment for OUR_MAGIC_VALUE
#ifdef PLATFORM_ARM
#define OUR_MAGIC_VALUE 1
#elif PLATFORM_ARM64
#define OUR_MAGIC_VALUE 2
#endif
because I have lists and trees of such values.
Thank you.
Edit 1:
for example, we have 6 targets and 4 of them support a FEATURE,
so we write:
#if defined(ARM)
#define FEATURE 1
#elif defined(ARM64)
#define FEATURE 0
#elif define(MIPS)
#define FEATURE 1
etc... for other platforms.
then I have code that reads this define somewhere:
#if FEATURE
do something. Note that this part can't be described in a target specific file, because it can have the same implementation for several targets.
#endif
and now I want to have a place to describe in general what this FEATURE means and do.
You can define a proxy macro and write a single comment for macro to be used by end user:
#ifdef PLATFORM_ARM
#define TIMEOUT_VALUE_IMPL 0
#define OUR_MAGIC_VALUE_IMPL 1
#elif PLATFORM_ARM64
#define TIMEOUT_VALUE_IMPL 2
#define OUR_MAGIC_VALUE_IMPL 3
#endif
// a comment for TIMEOUT_VALUE
#define TIMEOUT_VALUE TIMEOUT_VALUE_IMPL
// a comment for OUR_MAGIC_VALUE
#define OUR_MAGIC_VALUE OUR_MAGIC_VALUE_IMPL
You may also consider using constants instead of macros.

Is there an elegant solution for checking whether a preprocessor symbol is defined or not

Since preprocessor don't report an error when checking value of preprocessor's symbol that isn't actually defined (usually due to the lack of #include "some_header.h"), I use this cumbersome three line construction with "defined":
#if !defined(SOME_SYMBOL)
#error "some symbol isn't defined"
#endif
#if SOME_SYMBOL == 1
// Here is my conditionally compiled code
#endif
And the way with "#ifndef" is the same.
Is there a more elegant way to perform this check?
In your construction you could use an else block to skip the check for defined:
#if SOME_SYMBOL == 1
// Here is my conditionally compiled code
#else
// error
#endif
But in principle the comments are right. #if !defined and the shorthand #ifndef are the two available versions.
Currently, you are checking if SOME_SYMBOL is equals to 1. Do you execute different code based on that value ?
If not, you could simply use:
#ifdef SOME_SYMBOL
// Here is my conditionally compiled code
#else
// error
#endif
And now it's a short step to the typical c++ include guards. Copying from that wikipedia link, here is a grandparent.h file:
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
struct foo {
int member;
};
#endif /* GRANDPARENT_H */
Now, even if you end up including this header twice, it will only be executed once.

How to fight external include that always re-define it's stuff

For example assert.h:
...
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else /* NDEBUG */
...
This area isn't surrendered by #ifdef, #define, #endif or having #pragma once.
I want to define my own assert function, so I #undef it and creates it, but then when a file includes anything after that includes assert.h it overrides my assert function I made before that include...
For example:
#include "my_assert.hpp"
#include <iostream.h>
My my_assert will lose effect and use assert.h's define.

What use cases necessitate #define without a token-string?

I have encountered the #define pre-processor directive before while learning C, and then also encountered it in some code I read. But apart from using it to definite substitutions for constants and to define macros, I've not really understook the special case where it is used without a "body" or token-string.
Take for example this line:
#define OCSTR(X)
Just like that! What could be the use of this or better, when is this use of #define necessary?
This is used in two cases. The first and most frequent involves
conditional compilation:
#ifndef XYZ
#define XYZ
// ...
#endif
You've surely used this yourself for include guards, but it can also be
used for things like system dependencies:
#ifdef WIN32
// Windows specific code here...
#endif
(In this case, WIN32 is more likely defined on the command line, but it
could also be defined in a "config.hpp" file.) This would normally
only involve object-like macros (without an argument list or
parentheses).
The second would be a result of conditional compilation. Something
like:
#ifdef DEBUG
#define TEST(X) text(X)
#else
#define TEST(X)
#endif
That allows writing things like:
TEST(X);
which will call the function if DEBUG is defined, and do nothing if it
isn't.
Such macro usually appears in pair and inside conditional #ifdef as:
#ifdef _DEBUG
#define OCSTR(X)
#else
#define OCSTR(X) SOME_TOKENS_HERE
#endif
Another example,
#ifdef __cplusplus
#define NAMESPACE_BEGIN(X) namespace X {
#define NAMESPACE_END }
#else
#define NAMESPACE_BEGIN(X)
#define NAMESPACE_END
#endif
One odd case that I recently dug up to answer a question turned out to be simply commentary in nature. The code in question looked like:
void CLASS functionName(){
//
//
//
}
I discovered it was just an empty #define, which the author had chosen to document that the function accessed global variables in the project:
C++ syntax: void CLASS functionName()?
So not really that different from if it said /* CLASS */, except not allowing typos like /* CLAAS */...some other small benefits perhaps (?)
I agree with every answer, but I'd like to point out a small trivial thing.
Being a C purist I've grown up with the assertion that EACH AND EVERY #define should be an expression, so, even if it's common practice using:
#define WHATEVER
and test it with
#ifdef WHATEVER
I think it's always better writing:
#define WHATEVER (1)
also #debug macros shall be expressions:
#define DEBUG (xxx) (whatever you want for debugging, value)
In this way, you are completely safe from misuse of #macros and prevents nasty problems (especially in a 10 million line C project)
This can be used when you may want to silent some function. For example in debug mode you want to print some debug statements and in production code you want to omit them:
#ifdef DEBUG
#define PRINT(X) printf("%s", X)
#else
#define PRINT(X) // <----- silently removed
#endif
Usage:
void foo ()
{
PRINT("foo() starts\n");
...
}
#define macros are simply replaced, literally, by their replacement text during preprocessing. If there is no replacement text, then ... they're replaced by nothing! So this source code:
#define FOO(x)
print(FOO(hello world));
will be preprocessed into just this:
print();
This can be useful to get rid of things you don't want, like, say, assert(). It's mainly useful in conditional situations, where under some conditions there's a non-empty body, though.
As you can see in the above responses, it can be useful when debugging your code.
#ifdef DEBUG
#define debug(msg) fputs(__FILE__ ":" (__LINE__) " - " msg, stderr)
#else
#define debug(msg)
#endif
So, when you are debugging, the function will print the line number and file name so you know if there is an error. And if you are not debugging, it will just produce no output
There are many uses for such a thing.
For example, one is for the macro to have different behavior in different builds. For example, if you want debug messages, you could have something like this:
#ifdef _DEBUG
#define DEBUG_LOG(X, ...) however_you_want_to_print_it
#else
#define DEBUG_LOG(X, ...) // nothing
#endif
Another use could be to customize your header file based on your system. This is from my mesa-implemented OpenGL header in linux:
#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__))
# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */
# define GLAPIENTRY
# else
# define GLAPIENTRY __stdcall
# endif
#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */
# define GLAPIENTRY __stdcall
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
# define GLAPIENTRY
#endif /* WIN32 && !CYGWIN */
#ifndef GLAPIENTRY
#define GLAPIENTRY
#endif
And used in header declarations like:
GLAPI void GLAPIENTRY glClearIndex( GLfloat c );
GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
GLAPI void GLAPIENTRY glClear( GLbitfield mask );
...
(I removed the part for GLAPI)
So you get the picture, a macro that is used in some cases and not used in other cases could be defined to something on those cases and nothing to those other cases.
Other cases could be as follows:
If the macro doesn't take parameters, it could be just to declare some case. A famous example is to guard header files. Another example would be something like this
#define USING_SOME_LIB
and later could be used like this:
#ifdef USING_SOME_LIB
...
#else
...
#endif
Could be that the macro was used at some stage to do something (for example log), but then on release the owner decided the log is not useful anymore and simply removed the contents of the macro so it becomes empty. This is not recommended though, use the method I mentioned in the very beginning of the answer.
Finally, it could be there just for more explanation, for example you can say
#define DONT_CALL_IF_LIB_NOT_INITIALIZED
and you write functions like:
void init(void);
void do_something(int x) DONT_CALL_IF_LIB_NOT_INITIALIZED;
Although this last case is a bit absurd, but it would make sense in such a case:
#define IN
#define OUT
void function(IN char *a, OUT char *b);