Debug macro vs. Debug variable - c++

Below is an example of using a debug variable
class A{
public:
A(bool debug):m_debug(debug){};
~A(){};
void Test(){
for(int i=0;i<1000000;i++){
// do something
if(m_debug) print();
}
}
void print(){
std::cout << "something" << std::endl;
}
private:
bool m_debug;
};
Below is an example of using a debug macro preprocessor
#include "Preprocessor.h"
class A{
public:
void Test(){
for(int i=0;i<1000000;i++){
// do something
#ifdef DEBUG
print();
#endif
}
}
void print(){
std::cout << "something" << std::endl;
}
};
In Preprocessor.h is simply
#define DEBUG
The good thing about using a debug variable is the class has one less dependency on a global preprocessor header. The good thing about the macro approach is that there are 1000000 less if statement executed at run time, which might be critical for lets say graphics application when every single fps counts. What would be considered as a better approach?

The better approach is to use preprocessor, however, it do not necessary a new header file to define the macro.
You can set the flag at compiling, using -DMACRO_NAME or, in your case, -DDEBUG.

As long as the job is printing debug info, the precedent is to use macros like Visual Studio does (debug/release build). However in Qt world, there is class QLoggingCatagory where you can enable/disable logging sections. It calls the function QLoggingCategory::isDebugEnabled()every time a message is being logged out which makes me think it is not a major issue for performance at least for normal use.
That said if we comapare Visual Studio MFC application with Qt application, MFC applications are lighting fast. This could be attributed at least in part because it uses macros and the difference can be noticed rather easily in debug and release build as well where macro/debug info is the main difference.
Given all this evidence my vote is for macros approach in your case for maximum performance.

First, the macro way is better for both benefits in memory and if testing(though this is really minor cost). Do you have any special scenarios to use the debug variable?
why not define the A::Test() in the CPP file? thus the global preprocessor header could be moved to the CPP file. Anyway, I don't think expose such debug details in the header is a good idea.

Another alternative, if you do not like having a bunch of #ifdef DEBUG / #endif lines, you could create a macro that outputs it's argument if defined (much like the assert macro).
#ifdef DEBUG
#define PRINT(x) (x)
#else
#define PRINT(x)
#endif
PRINT( std::cout << "something" << std::endl );

The code path does not get much more minimal than "compiled away". However, if you are willing to perform a refactoring step, you can make the run-time debug version cheaper at the cost of a larger executable.
The idea is to make the debug state a template parameter of a refactored version of Test() so that it may or may not print a debug statement on each iteration. The compiler's dead code elimination pass will then optimize away the statement in the case false is passed to the template, since template parameters will be treated as compile time constants in the template expansion.
The fully optimized version can still use conditional compilation to always disable debug output, of course.
template <bool Debug>
void TestDebug(){
for(int i=0;i<1000000;i++){
// do something
if (Debug) print();
}
}
void Test(){
#ifdef DEBUG
if(m_debug) TestDebug<true>();
else TestDebug<false>();
#else
TestDebug<false>();
#endif
}

Related

Unused variable warning from debugging code

I've built a logging system that compiles in two platforms:
1) A debug platform where the logging calls are interleaved in the code.
2) An on-chip platform in which the logging calls should not appear in the code, due to hard limitations on code size and run time.
To achieve my goal I used C macros:
#ifdef DEBUG_PLATFORM
#define LOG(log) std::sstream s; s<<log; log_func(s);
#else
#define LOG(log) ;
#endif
Alas, the unused variable compiler warning is giving me a hard time. For example the following code will compile in the debug platform but not in the online platform:
int a = 5;
int b = func(1,2,3);
LOG("a: "<<a<<" b: "<< b)
I'd like to free the user from thinking on these issues and doing tricks to avoid the warning (like adding (void)a). Most users don't compile the online platform and these type of errors will be found in retrospective and will cause a lot of inconvenience.
I am not allowed to change the compiler flags, using unused variable warnings is a must.
Does anybody have an idea how to overcome this difficulty?
Is there a way to instruct the compiler to ignore the warning for all variables inside some scope?
I would suggest you logging a variable at a time:
#ifdef DEBUG_PLATFORM
#define LOG(log) { std::stringstream s; s<< #log << '=' << log << ' '; log_func(s); }
#else
#define LOG(log) (void) log;
#endif
#log will print the variable name.
(void) log will make the compiler ignore that it has not been used.
You could log more variables provided that you put more macro versions, but it will be messy. With #log and with (void) log, you can no longer pass "a: " << a to LOG

Replace 'Define macro' with empty implementation

I usually use the #define macro to add code that will be here while compiling as debug time and not while compiling as release. For instance:
#ifdef NDEBUG
# define LOG(msg) (void)msg
#else
# define LOG(msg) MyDebugLogger(msg)
#endif
Instead of that, I was thinking of using plain function and, just not providing the body for the release method:
void MyDebugLogger(std::string const& msg);
In MyDebugLogger.cpp:
void MyDebugLogger(std::string const& msg)
{
#ifdef NDEBUG
std::clog << msg << "\n"; // Or whatever
#else
(void)msg;
#endif
}
I'm expecting that the compilers will have the power to strip out the call and add no extra cost in Release. Am I correct?
For some reason, could it be a bad practice?
EDIT: My question is: If I use macros as before, I know that in Release mode, the executable will be smaller and faster, as all the code has been removed.
If I use the function, will it be the same? As the compiler may understand that the function does nothing and is not necessary. (Or it will add an extra, even small, for calling an empty function)
practically you would do the same as with the macro:
void MyDebugLogger(std::string const& msg)
{
#ifdef NDEBUG
std::clog << msg << "\n"; // Or whatever
#endif
}
You'r example should work, with a little tweak. In your current version the compiler "sees" just the function signature and will emit a call to it's symbol, which will later be resolved via the linker, so it can't optimize it out on it's own. (Link Time Optimizations might help with that, but that depends very much on you'r setup and dynamic linking would make this impossible). So maybe try something like this
in the header:
// Assuming you are using clang or gcc,
// but is required to not give an error by the standard and probably
// not even needed.
[[gnu::always_inline]]
void MyDebugLogger(std::string const& msg [[maybe_unused]])
{
#ifdef NDEBUG
MyDebugLoggerImplementation(msg);
#endif
}
And then implement it in you .cpp file. Another benefit of this method is that you
method needs the Logger to be compiled with NDEBUG while this method gives the client code the choice.

c++ force compiler to opt out some piece of code

I have a piece of code:
// some code, which only do sanity check
expensive checks
// sanity check end
Now how do I tell the compiler to force it to opt out
this piece? Basically it means when I compile with -O2 or
O3, I don't want it to be there...
Thanks!
You can accomplish this with a constant and a single if/def pair. This allows the code to still be compiled and checked for errors but omitted during optimization. This can prevent changes that might break the check code from going undetected.
#if defined(USE_EXPENSIVE_CHECKS) || defined(DEBUG)
#define USE_EXPENSIVE_CHECKS_VALUE true
#else
#define USE_EXPENSIVE_CHECKS_VALUE false
#endif
namespace {
const bool useExpensiveChecks = USE_EXPENSIVE_CHECKS_VALUE;
};
void function()
{
if(useExpensiveChecks == true)
{
// expensive checks
}
}
Instead of relying on the compiler to optimize the code out, you could pass the compiler an additional symbol definition only when you want the code to run:
// some code, which only do sanity check
#ifdef my_symbol
expensive checks
#endif
// sanity check end
Using macros and conditionals in the preprocessor is really the only way to avoid code being generated by the compiler.
So, here's how I would do it:
#ifdef NEED_EXPENSIVE_CHECKS
inline expensive_checking(params...)
{
... do expensive checking here ...
}
#else
inline expensive_checking(params...)
{
}
#endif
Then just call:
some code
expensive_checking(some_parameters...)
some other code
An empty inlined function will result in "no code" in any decent, modern compiler. Use -DNEED_EXPENSIVE_CHECKS in your debug build settings, and don't use that in release build.
I have also been known to use a combination of macro and function, such as this:
#ifdef NEED_EXPENSIVE_CHECKS
#define EXPENSIVE_CHECKS(stuff...) expensive_checks(__FILE__, __LINE__, stuff...)
inline expensive_checks(const char *file, int line, stuff ...)
{
if (some_checking)
{
cerr << "Error, some_checking failed at " << file << ":" << line << endl;
}
}
#else
#define EXPENSIVE_CHECKS(stuff...)
#endif
Now, you get information on which file and what line when something fails, which can be very useful if the checks are made in many places (and you can use __function__ or __pretty_function__ to get the function name as well, if you wish).
Obviously, the assert() macro will essentially do what my macro solution does, except it usually doesn't provide the filename and line-number.
Move your checks into a different function, then import cassert and write assert(expensive_check()). When you want to disable the checks, use #define NDEBUG before the inclusion of cassert.

Simple ways to disable parts of code

This isn't a typical question to solve a specific problem, it's rather a brain exercise, but I wonder if anyone has a solution.
In development we often need to disable or switch some parts of code to check different approaches. To do this we use comments or #defines, but my favorite is:
//*
[code here]
//*/
Now when you remove just the first slash the code will become commented-out.
The question: is there any way to implement similar if-else code switch? I tried to find it but I always had some problem and couldn't find a working solution.
And maybe do you know any similar tricks?
Wrapping the code with #if 0 does the trick but then you still need to edit the code to enable/disable it. That's not much better than just using the comment block.
Note that you can also use a defined preprocessor constant:
#ifdef ENABLE_TESTS
// code that you want to run ONLY during tests
#endif
Now when building the code, you can selectively define/un-define this constant in your build process - IDE/makefile/build script/command-line - without needing to edit the code:
$ gcc -DENABLE_TESTS source.c
I've added this answer to counter-balance all of the early #if 0 answers, but this construct from the accepted answer is the best answer to the specific question: /**/ foo(); /*/ bar(); /**/. Please use such comment tricks sparingly.
#if 0
...disabled code here
#endif
I'm not sure I should post this because it's not something I think is 'good code', but I'll admit to having used the following technique as a quick-n-dirty way to be able to quickly switch between two small snippets of code when I'm just checking something out:
// in the following , foo() is active:
/**/ foo(); /*/ bar(); /**/
Now just remove one of the asterisks at the front:
// now bar() is active:
/*/ foo(); /*/ bar(); /**/
Of course, this should never make it past the "just checking things out" phase...
Preprocessor if-else also works
#if 1
// ... enabled if 1
#else
// ... enabled if 0
#endif
Use some preprocessor logic to help you out here:
#if 0
//code goes here
#endif
Enjoy
Sometimes I use the below trick to switch between two lazy comments.
//* <-- remove the first slash
[code block 1]
/*/
[code block 2]
//*/
Well, if the code that needed to be disabled once or twice before finalizing, I prefer to use hotkeys provided by IDE to comment that code out, and later comment in. Yes, I need to select the code block first, but I prefer not to include one more debugging variable/preprocessor directive/if statement every time I need to disable a part of code. This happens to be most of the time.
If, on the other hand, I need to repeatedly switch between 2 code blocks to find the right thing, then I use a if (0) / if (1) to disable/enable code block.
[code block 1]
Later
if (0)
{
[code block 1]
}
else
{
[code block 2]
}
If you're doing checks at compile time, you can use Gigi's answer, which will conditionally not compile sections of code. Note that the preprocessor has no knowledge of variables, or sizeof, or other things handled by the compiler (so using something like 4 == sizeof(int) will not fly)
If you want to compile in little bits of debugging code that should not ever get run, you can use regular conditional statements, like such
bool debugging = false;
// banana banana banana
if (debugging)
{
// do a bunch of stuff here
}
You can then use a debugger to access the skipped section by assigning debugging to true.
Macro is the way to do this..
#define COMPILE
#ifdef COMPILE
//code to comment begins
cout<<"ha ha ha"<<endl;
//code to comment ends
#endif
To disable the code, just comment out #define compile line
Synchronously switching on/off chunks of code scattered across the program is sometimes a need too.
Inspired by this earlier post by Graham I cooked up something like this:
void doNothing(){}
#define DO_IF(flag, code) flag ? code : doNothing();
This can be for instance used as follows:
DO_IF(collectStats, recordStats());
DO_IF(collectStats, store(pullStat()));
An that is even better:
#define DO_IF(flag,code) if( flag ) { code; }
1 ? foo() : bar();
This executes foo(). Change the 1 to a 0 to execute bar() instead.
Unlike the suggestions involving preprocessor directives or comments, both possible branches are compiled, so you get the full benefit of the compiler's syntax checking.
Sometimes i use this approach to just not overbloat the code by infinite sequence of if-endif definitions.
debug.hpp
#ifdef _DEBUG
#define IF_DEBUG(x) if(x)
#else
#define IF_DEBUG(x) if(false)
#endif
example.cpp
#include "debug.hpp"
int a,b, ... ,z;
...
IF_DEBUG(... regular_expression_here_with_a_b_z ...) {
// set of asserts
assert(... a ...);
assert(... b ...);
...
assert(... z ...);
}
This is not always effective, because compiler may warn you about unused variables has used inside such disabled blocks of code. But at least it is better readable and unused variable warnings can be suppressed for example like this:
IF_DEBUG(... regular_expression_here_with_a_b_z ...) {
// set of asserts
assert(... a ...);
assert(... b ...);
...
assert(... z ...);
}
else {
(void)a;
(void)b;
....
(void)z;
}
It is not always a good idea, but at least helps to reorganize the code.
the following logic should contain the simplest approach
if(isMode1)
{
//Code for mode1
}
else
{
//Code for other modes
}
although I think the correct way is to use PreProcessor Directives
In my code, I like to do this in my main.cpp file:
#define CRAZY_EXPERIMENT
#ifdef TEST
#include "Test.h"
#elif ANOTHER_TEST
#include "AnotherTest.h"
#elif CRAZY_EXPERIMENT
#include "CrazyExperiment.h"
#else
int main(int argc, int * argv[]){
runTheProgramLikeNormal();
}
#endif
The header files you see all contain their own main(). There is only ever one main() function in the program based on what is defined in the first #define there. If the statement is omitted entirely, it defaults to the canonical main() function you see written.
This makes it easy to write tests for my program that only focus on one or two components by themselves. And the best part is that the test headers are neatly quarantined from my code, so no test code gets left in (or even linked in) by mistake.

Linking of Method calls

I had to define a new set of wrappers for existing methods.
These new wrappers intend to help in debugging by including certain tracing information.
Original Source Code:
Sample.c ::
Caller{
void functionA(){
funcB();
}
}
Callee{
void funcB(){
}
}
Modified Code with Traditional Wrapper Functionality:
Sample.h ::
#define funcB wrapperFuncB //not visible to Callee
Caller{
void functionA(){ //this gets redirected to wrapperFuncB cos of #define
funcB();
}
}
Callee{
void wrapperFuncB(){
if(DEBUG){ //value of DEBUG is set at runtime
//COLLECT Trace data
}else{
funcB();
}
}
void funcB(){
}
}
This mechanism has the additional overhead of :
1] All calls to funcB is routed to wrapperFuncB, irrespecitve of DEBUG enabled or not
2] An additional method frame [wrapperFuncB] has to be created, irrespecitve of DEBUG enabled or not
3] An overhead of a conditional check
If the methods are identical, you could use something like this:
#ifdef __DEBUGING
#define myClass debug_class
#else
#define myClass actual_class
#endif
In this way, you can selectively choose which class you are using in your code, the actual one or the wrapper one. There may be a few problems though, because this was just the first idea that came to mind.
Alternatively you could put your debug statements like this
#ifdef DEBUG_ENABLE
DEBUG_LOG(X) printf(x)
#else
DEBUG_LOG(X) do{}while(0)
void FunctionA()
{
DEBUG_LOG("\n Debugging function",__func__);
}
You can use the same routine without wrappers. Advantage would be the logs would make the code little bit easier to understand and you can enable and disable them using the compiler options.
As function wrapperFuncB will have the same signature as funcB, you can simply do this without the need of a new class.
#ifdef __DEBUG__
#define funcB wrapperFuncB
#else
#define funcB actualFuncB
#end
so when you are not debugging or collecting trace info, you can simply turn it off by not defining DEBUG and there will be no overhead
Edit: Updated after getting comments from user170008
I dont think #ifdef __DEBUG__ kind of thing can be used at run time. Most probably you will have to rely on command line params to differentiate between a debug or normal run.
But what ever way you use just create a function pointer and set it according to what kind of run you are doing e.g
void (*funcB)(void);
if(debug)
funcB=debugFuncB;
else
funcB=actualFuncB;
after this you can simply use funcB as you are using now i.e funcB();