Simple ways to disable parts of code - c++

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.

Related

How to handle defines in C++ with pre processor instructions (gTest background)?

I am used to handle defines like the following code snipped shows. The paramA is initialized with 1 (edit: defined as 1) and can be used in the code. So far so good...
#define paramA 1
int main(void)
{
int varTest1 = 0;
if(paramA < 2)
{
varTest1 = 1;
}
else
{
varTest1 = 2;
}
return 0;
}
Now I'm dealing with a code where I receive the following define:
#define ALGO_FEATURE ALGO_FEATURE_A
First question: What kind of type is "ALGO_FEATURE_A" ? What does here happen? Is it some kind of text define? Or is this even legal? It actually builds and seams to be valid from my point of view.
My goal is to react (I'm doing unittests with gTest) on different algo features with different tests. So if "ALGO_FEATURE" is "ALGO_FEATURE_A" I would like to call different tests than in case it is "ALGO_FEATURE_B".
Current approach looks like this (according to the first code snipped). But it does not work... No matter which one of the following versions. The result is always that the if condition is true.
First approach (while debugging it always run into the first option, even if the if conditions are switched.
#if (ALGO_FEATURE == ALGO_FEATURE_B)
EXPECT_TRUE(FALSE); // this line is always run, even if ALGO_FEATURE is not ALGO_FEATURE_B
#elif (ALGO_FEATURE == ALGO_FEATURE_A)
EXPECT_TRUE(TRUE); // this line is never reached even if it should be true
#endif
How can I adapt this approach ?
Thanks for your time !
paramA is initialized with 1
No, paramA is replaced by the source text 1 wherever it appears.
What kind of type is ALGO_FEATURE_A
It isn't a type. Presumably it is itself a #define, so ALGO_FEATURE will be the same source text.
I would guess that both ALGO_FEATURE_A and ALGO_FEATURE_B are defined to 1, so your tests are equivalent to
#if (1 == 1)
EXPECT_TRUE(FALSE); // this line is always run, even if ALGO_FEATURE is not ALGO_FEATURE_B
#elif (1 == 1)
EXPECT_TRUE(TRUE); // this line is never reached even if it should be true
#endif
You can't distinguish between something #defined to be one or the other of those if they are the same value. If there is an #if around the definition of ALGO_FEATURE, then you can use that, or you could #define IS_ALGO_FEATURE_A, with the test
#if defined (IS_ALGO_FEATURE_B)
EXPECT_TRUE(FALSE);
#elif defined (IS_ALGO_FEATURE_A)
EXPECT_TRUE(TRUE);
#endif
The C preprocessor does verbatim substitutions.
For instance
#define A B
if (A == B)
generates the code
if (B == B)
whatever that means.
If your purpose is variant code generation, you could use a construct like
// Available versions
#define BLUE 1
#define GREEN 2
// Desired version
#define VERSION BLUE // Or GREEN
#if VERSION == BLUE
// Blue code
#else
// Green code
#endif
This translates to
#if 1 == 1
// Blue code
#else
// Green code
#endif
so just
// Blue code
Extra remark:
if (VERSION == BLUE)
{
// Blue code
}
else
{
// Green code
}
Would probably have the same effect on optimized code, by dead branch elimination. (I am not recommending such a practice.)
How to handle defines in C++ with pre processor instructions
A possibility is to use some other program to generate C++ code, or to generate test cases (or various test inputs).
Consider using GPP or GNU m4 to generate C++ code.
Perhaps you want to use GNU autoconf.
You certainly could use GNU make to build your program with partly generated C++ code.
Take inspiration from Qt. It does generate C++ code (in its moc) and is an open source framework.
Maybe consider using POCO.
#define ALGO_FEATURE ALGO_FEATURE_A
The ALGO_FEATURE_A might be provided elsewhere, e.g. if you compile with GCC invoked as gcc -Wall -DALGO_FEATURE_A
And your code could latter use preprocessor conditions like
#ifdef ALGO_FEATURE_A
/// some code
#endif
Read documentation of GNU cpp and of GCC.

Debug macro vs. Debug variable

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
}

sizeof operator in #define directives

I've been inspecting someone's code and I encountered this:
#else //If not in Debug mode
#define LOG_WARNING(str) do { (void)sizeof(str); } while(0)
#define LOG_INFO(str) do { (void)sizeof(str); } while(0)
// ... More #define directives
#endif
Apparently, do { (void)sizeof(str); } while(0) is carefully written so the directive can be completely ignored by the compiler.
How does this work?
The operand of sizeof is an unevaluated, so this ensures that there is no work to be done at run time. The macro just ignores a constant value; the compiler can see that it has no effect, so should generate no code from it.
The advantage over doing nothing at all is that the compiler still checks that the argument is a valid expression; you won't accidentally break the debug build when changing the code and only compiling for release.
The advantage over (void)str, mentioned in the comments, is that that would evaluate the expression, and the compiler might not be able to eliminate it, since it there might be side effects. For example:
extern std::string get_message(int code);
LOG_INFO(get_message(code)); // -> (void)get_message(code);
in a release build would call the function and ignore the result, impacting performance.

Macro to prevent code processing

So I've a piece of code, which will access a DLL namespace function if it's in Debug mode, and which I'd like to comment out if it's in Release.
#ifdef DEBUG
#define (DEBUG_CODE) abcd::
#else
#define (DEBUG_CODE) <Condition to skip processing>
if (some condition)
(DEBUG_CODE) func_name();
While I'd like the #else to define a comment, I suppose you can't do that because they're skipped by the compiler before any code processing, or preprocessing is performed..
If that is correct, then kindly tell me a way to skip the processing of (DEBUG_CODE) func_name();. There are a lot of places where it is used, and I don't wish to add if(DEBUG) everywhere.
EDIT
The namespace DLL has functions which do not return anything, as well as functions which are expected to return a value, and which might be assigned to an enum.
i.e.
abcd::func_name();
and
int rs = abcd::func_name_2();
and
enum XYZ{ var1 = 0; var2};
XYZ PQR = abcd::func_name3(); //This Enum will prevent me from defining some kind
// 0; as a `#define`
So..multiple scenarios..
Thanks for your help.
You can do this if you change DEBUG_CODE to
#ifdef DEBUG
# define DEBUG_CODE(code) abcd::code;
#else
# define DEBUG_CODE(code) ;
#endif
and then you would call it like this:
if(some_condition) DEBUG_CODE(func_name())
In debug mode this calls your function and in release mode no code is generated.
If you want to be able to assign the return values of these functions to variable or return from them (though I don't think it's a good idea, as I explain in the comments) I would make the macro take what to call in debug mode and what to use in release mode.
#ifdef DEBUG
# define IF_DEBUG_ELSE(debug_code, release_code) abcd::debug_code
#else
# define IF_DEBUG_ELSE(debug_code, release_code) release_code
#endif
This makes it clear at least when you call the macro what's happening.
This can be used like:
return IF_DEBUG_ELSE(check_result(), 0);//0 for success
if(IF_DEBUG_ELSE(check_condition(), true)){}
XYZ xyz = IF_DEBUG_ELSE(get_xyz(), First_XYZ);
and so on like that.

vs2010 C4353 why isn't this an error

I ran into this today in an if and after looking into it found that all these are all valid statements that generate the C4353 . My only guess is that this is the old way of doing noop in C. Why is this not an error. When would you use this to do anything useful.
int main()
{
nullptr();
0();
(1 == 2)();
return 0;
}
Using constant 0 as a function expression is an extension that is specific to Microsoft. They implemented this specifically because they saw a reason for it, which explains why it's wouldn't make sense to treat it as an error. But since it's non-standard, the compiler emits a warning.
You are correct that it is an alternative to using __noop().
All of these :
nullptr();
0();
(1 == 2)();
are no-op statements (meaning they don't do anything).
btw I hope you are not ignoring warnings. Most of the time it is a good practice to fix all warnings.
As explained in the C4353 warning page and in the __noop intrinsic documentation, the use of 0 as a function expression instructs the Microsoft C++ compiler to ignore calls to the function but still generate code that evaluates its arguments (for side effects).
The example given is a trace macro that gets #defined either to __noop or to a print function, depending on the value of the DEBUG preprocessor symbol:
#if DEBUG
#define PRINT printf_s
#else
#define PRINT __noop
#endif
int main() {
PRINT("\nhello\n");
}
The MSDN page for that warning has ample explanation and a motivating example:
// C4353.cpp
// compile with: /W1
void MyPrintf(void){};
#define X 0
#if X
#define DBPRINT MyPrint
#else
#define DBPRINT 0 // C4353 expected
#endif
int main(){
DBPRINT();
}
As you can see it is to support archaic macro usage.