Macro which will not compile the function if not defined - c++

Currently using to show debug output when in debug mode:
#ifdef _DEBUG
#define printX(...) Serial.printf( __VA_ARGS__ )
#else
#define printX(...) NULL
#endif
yet this still include the printX in the result code, and the parameters which have been applied still consume memory, cpu power, and stack size, so my question is:
is there a way to have a macro, which is not including the function, and "ignoring" all of it's calls in the source when in "release mode" and basically not compile anything with it ?

A macro is a not a function. It does not consume any memory, cpu power, or stack size. This is because macros operate entirely at compile time, and just act as a text replacing mechanism. When the program is run, there are no macros which are "called".

The macro
#define printX(...) NULL
replaces printX function call with all its arguments with plain NULL. This is a textual replacement that happens before a compiler is able to take a look at the code, so any nested calls inside printX, e.g.
printX(someExpensiveCall())
will also be completely eliminated.

In my programs I include a line that says:
#define DEBUG_MODE
and I use it anywhere I want to compile with (or without) debug mode:
#ifdef DEBUG_MODE
print here all the info I need for debug and certainly don't want in released binary.
#endif
Before releasing the final binary I comment out the definition line.

Related

Exclude parts from compilation - still syntax-check

We have a pretty large project here in C++/.NET/Visual Studio, for performance testing we incuded some code that makes it possible to evaluate the execution time between certain points.
PERFORMANCE_TEST BeginMeasureTime("execute someCode")
someCode
PERFORMANCE_TEST EndMeasureTime("execute someCode")
Usually while developing the PERFORMANCE_TEST macro would be set to // so the evaluation code is switched off. So if code / interfaces etc. change and the code after the PERFORMANCE_TEST macro becomes invalid, the developer will not notice that.
Is there any smarter way to have the performance evaluation code only built in a special version of the project but still make sure that it stays consistent? How would you normally do something like that?
One easy way would be to change
PERFORMANCE_TEST xxx
to
PERFORMANCE_TEST(xxx)
Then instead of
#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST
#else
#define PERFORMANCE_TEST //
#endif
you could have
#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST(x) {x;}
#else
#define PERFORMANCE_TEST(x) if(0) { x; }
#endif
An optimizing compiler should generate no code for the second version if performance tests are disabled (or at the very least it'll not branch on the if), but it'll still be part of the compilation.
Alternatively, if build times aren't a huge concern you could simply always build both versions into separate directories.
It's been a while since I did something like this the following should be what you want. If the MACRO is defined then the function is included, else it the function is a noop and compiled out the code.
#ifdef MACRO
#define MACRO_NAME(arg1, arg2, ...) [code to expand to]
#else
#define MACRO_NAME(arg1, arg2, ...) noop
#endif
Update:
Ok so I slightly got the question a bit incorrect.
Most static analysis tools can be configured to scan certain #defines
CPPCheck for example can be given the following arguments.
-D<ID> Define preprocessor symbol. Unless --max-configs or
--force is used, Cppcheck will only check the given
configuration when -D is used.
Example: '-DDEBUG=1 -D__cplusplus'.
So you can then scan the code twice, thus achieving your goal.
I would say this is the best of both before you can add more scans if you add more #define
Or you can use some of the following to scan more configurations.
-f, --force Force checking of all configurations in files. If used
together with '--max-configs=', the last option is the
one that is effective.
and
--max-configs=<limit>
Maximum number of configurations to check in a file
before skipping it. Default is '12'. If used together
with '--force', the last option is the one that is
effective.
We used this type of operation at a previous company, we build code for WIN32, Pocket PC and WM5 and WM6 all from the same code base but had static checking on all build configurations. But the end result was the removal of non redundant code in all builds.

Using #define for printf, does it effect on speed

I am using
#define printInt(x) printf ("%d",x)
In main()
I can use it like this:
int var=10;
printInt (var);
Which is easier to use than typing
printf ("%d",var);
Will using my own #define for printing an int, float etc make my program slower?
No this will not effect the speed. The macro is expanded during pre-processing so that in every instance that you use printInt(myInt) what is actually passed to the compiler will be printf("%d", myInt). So I think the binary output would be identical either way.
No, it doesn't affect the speed of your program.
The #define instructions are processed by the preprocessor before your program is compiled.
For example the call
printInt(var);
is replaced with
printf ("%d",var);
by the preprocessor.
Therefore the compiler can't determine if a #define was used or not. In both cases it leads to the same code (and the same program). Thats the reason why it isn't possible that both programs differ in their speed.
EDIT: If you use a lot of #defines in your program, it is possible that the speed of the proprocessing step decreases. But in most cases this should be no problem.

increase c++ code verbosity with macros

I'd like to have the possibility to increase the verbosity for debug purposes of my program. Of course I can do that using a switch/flag during runtime. But that can be very inefficient, due to all the 'if' statements I should add to my code.
So, I'd like to add a flag to be used during compilation in order to include optional, usually slow debug operations in my code, without affecting the performance/size of my program when not needed. here's an example:
/* code */
#ifdef _DEBUG_
/* do debug operations here
#endif
so, compiling with -D_DEBUG_ should do the trick. without it, that part won't be included in my program.
Another option (at least for i/o operations) would be to define at least an i/o function, like
#ifdef _DEBUG_
#define LOG(x) std::clog << x << std::endl;
#else
#define LOG(x)
#endif
However, I strongly suspect this probably isn't the cleanest way to do that. So, what would you do instead?
I prefer to use #ifdef with real functions so that the function has an empty body if _DEBUG_ is not defined:
void log(std::string x)
{
#ifdef _DEBUG_
std::cout << x << std::endl;
#endif
}
There are three big reasons for this preference:
When _DEBUG_ is not defined, the function definition is empty and any modern compiler will completely optimize out any call to that function (the definition should be visible inside that translation unit, of course).
The #ifdef guard only has to be applied to a small localized area of code, rather than every time you call log.
You do not need to use lots of macros, avoiding pollution of your code.
You can use macros to change implementation of the function (Like in sftrabbit's solution). That way, no empty places will be left in your code, and the compiler will optimize the "empty" calls away.
You can also use two distinct files for the debug and release implementation, and let your IDE/build script choose the appropriate one; this involves no #defines at all. Just remember the DRY rule and make the clean code reusable in debug scenario.
I would say that his actually is very dependent on the actual problem you are facing. Some problems will benefit more of the second solution, whilst the simple code might be better with simple defines.
Both snippets that you describe are correct ways of using conditional compilation to enable or disable the debugging through a compile-time switch. However, your assertion that checking the debug flags at runtime "can be very inefficient, due to all the 'if' statements I should add to my code" is mostly incorrect: in most practical cases a runtime check does not influence the speed of your program in a detectable way, so if keeping the runtime flag offers you potential advantages (e.g. turning the debugging on to diagnose a problem in production without recompiling) you should go for a run-time flag instead.
For the additional checks, I would rely on the assert (see the assert.h) which does exactly what you need: check when you compile in debug, no check when compiled for the release.
For the verbosity, a more C++ version of what you propose would use a simple Logger class with a boolean as template parameter. But the macro is fine as well if kept within the Logger class.
For commercial software, having SOME debug output that is available at runtime on customer sites is usually a valuable thing to have. I'm not saying everything has to be compiled into the final binary, but it's not at all unusual that customers do things to your code that you don't expect [or that causes the code to behave in ways that you don't expect]. Being able to tell the customer "Well, if you run myprog -v 2 -l logfile.txt and do you usual thing, then email me logfile.txt" is a very, very useful thing to have.
As long as the "if-statement to decide if we log or not" is not in the deepest, darkest jungle in peru, eh, I mean in the deepest nesting levels of your tight, performance critical loop, then it's rarely a problem to leave it in.
So, I personally tend to go for the "always there, not always enabled" approach. THat's not to say that I don't find myself adding some extra logging in the middle of my tight loops sometimes - only to remove it later on when the bug is fixed.
You can avoid the function-like macro when doing conditional compilation. Just define a regular or template function to do the logging and call it inside the:
#ifdef _DEBUG_
/* ... */
#endif
part of the code.
At least in the *Nix universe, the default define for this kind of thing is NDEBUG (read no-debug). If it is defined, your code should skip the debug code. I.e. you would do something like this:
#ifdef NDEBUG
inline void log(...) {}
#else
inline void log(...) { .... }
#endif
An example piece of code I use in my projects. This way, you can use variable argument list and if DEBUG flag is not set, related code is cleared out:
#ifdef DEBUG
#define PR_DEBUG(fmt, ...) \
PR_DEBUG(fmt, ...) printf("[DBG] %s: " fmt, __func__, ## __VA_ARGS__)
#else
#define PR_DEBUG(fmt, ...)
#endif
Usage:
#define DEBUG
<..>
ret = do_smth();
PR_DEBUG("some kind of code returned %d", ret);
Output:
[DBG] some_func: some kind of code returned 0
of course, printf() may be replaced by any output function you use. Furthermore, it can be easily modified so additional information, as for example time stamp, is automatically appended.
For me it depends from application to application.
I've had applications where I wanted to always log (for example, we had an application where in case of errors, clients would take all the logs of the application and send them to us for diagnostics). In such a case, the logging API should probably be based on functions (i.e. not macros) and always defined.
In cases when logging is not always necessary or you need to be able to completely disable it for performance/other reasons, you can define logging macros.
In that case I prefer a single-line macro like this:
#ifdef NDEBUG
#define LOGSTREAM /##/
#else
#define LOGSTREAM std::clog
// or
// #define LOGSTREAM std::ofstream("output.log", std::ios::out|std::ios::app)
#endif
client code:
LOG << "Initializing chipmunk feeding module ...\n";
//...
LOG << "Shutting down chipmunk feeding module ...\n";
It's just like any other feature.
My assumptions:
No global variables
System designed to interfaces
For whatever you want verbose output, create two implementations, one quiet, one verbose.
At application initialisation, choose the implementation you want.
It could be a logger, or a widget, or a memory manager, for example.
Obviously you don't want to duplicate code, so extract the minimum variation you want. If you know what the strategy pattern is, or the decorator pattern, these are the right direction. Follow the open closed principle.

Empty "release" ASSERT macro crashes program?

Take a look at this code:
#include <cassert>
#ifdef DEBUG
#define ASSERT(expr) assert(expr)
#else
#define ASSERT(expr)
#endif /* DEBUG */
The program will run only if I have DEBUG defined, otherwise it will hang and terminate with no results. I am using MinGW in Eclipse Indigo CDT. Advice is appreciated!
It's hard to tell without looking at the actual code that is causing the issue. My guess: you are evaluating an expression with side-effects within an ASSERT(). For instance, ASSERT( ++i < someotherthing ) whithin a loop. You could confirm by temporary modifying the macro definition to just expr on NDEBUG builds. After confirming this is the cause, go to each and every ASSERT call you are issuing to ensure that the expressions are side-effects free.
You are almost certainly abusing assertions. An assertion expression must never have side effects.
When you say, assert(initialize_critical_space_technology());, and then you omit this entire line in the release build, you can imagine for yourself what will happen.
The only safe and sane way to use assertions is on values:
const bool space_init = initialize_critical_space_technology();
assert(space_init);
Some people introduce a VERIFY macro for something that always executes the code:
#define VERIFY(x) (x) // release
#define VERIFY(x) (assert(x)) // debug

C++ conditional compilation

I have the following code snippet:
#ifdef DO_LOG
#define log(p) record(p)
#else
#define log(p)
#endif
void record(char *data){
.....
.....
}
Now if I call log("hello world") in my code and DO_LOG isn't defined, will the line be compiled, in other words will it eat up the memory for the string "hello world"?
P.S. There are a lot of record calls in the program and it is memory sensitive, so is there any other way to conditionally compile so that it only depends on the #define DO_LOG?
This should be trivial to verify for yourself by inspecting the resulting binary.
I would say "no", since the expression totally goes away, the compiler will never see the string (it's removed by the preprocessor's macro expansion).
Since the preprocessor runs before the compiler, the line will not even exist when the compiler runs. So the answer is no, it does not use any memory at all.
No, it will not be in the binary. It will not even be compiled - the preprocessor will expand it into an empty string prior to the compilation, so the compiler will not even see it.
No. The preprocessor is executed prior to compilation, and so the code will never even be seen. I would like to add, though, that if you are interested in adding logging to your C++ application, you might want to use the Log4Cxx library. It uses similar macros which you can completely elide from your application, but when logging is enabled, it supports several different levels of logging (based on importance/severity) as well as multiple different "appenders" to which to send logging output (e.g. syslog, console, files, network I/O, etc.).
The full API documentation may be found at Log4Cxx API docs. Also, if you have any Java developers on board who have used Log4J, they should feel right at home with Log4Cxx (and convince you to use it).