C++ 禁用部分代码的简单方法

C++ 禁用部分代码的简单方法,c++,c,C++,C,这不是一个解决特定问题的典型问题,而是一个大脑练习,但我想知道是否有人有解决方案 在开发中,我们经常需要禁用或切换代码的某些部分来检查不同的方法。为此,我们使用注释或定义,但我最喜欢的是: //* [code here] //*/ 现在,只要删除第一个斜杠,代码就会被注释掉 问题是:有没有办法实现类似的if-else代码切换?我试图找到它,但我总是有一些问题,无法找到一个有效的解决办法 也许你知道类似的技巧吗?使用一些预处理器逻辑来帮助你: #if 0 ...disabled code her

这不是一个解决特定问题的典型问题,而是一个大脑练习,但我想知道是否有人有解决方案

在开发中,我们经常需要禁用或切换代码的某些部分来检查不同的方法。为此,我们使用注释或定义,但我最喜欢的是:

//*
[code here]
//*/
现在,只要删除第一个斜杠,代码就会被注释掉

问题是:有没有办法实现类似的if-else代码切换?我试图找到它,但我总是有一些问题,无法找到一个有效的解决办法


也许你知道类似的技巧吗?

使用一些预处理器逻辑来帮助你:

#if 0
...disabled code here
#endif
#if 0
    //code goes here
#endif

享受

以下逻辑应包含最简单的方法

if(isMode1)
{
    //Code for mode1
}
else
{
    //Code for other modes
}

虽然我认为正确的方法是使用

将代码包装成
。#如果0
起作用,但仍然需要编辑代码以启用/禁用它。这并不比只使用注释块好多少

请注意,还可以使用定义的预处理器常量:

#ifdef ENABLE_TESTS
// code that you want to run ONLY during tests 
#endif
现在,在构建代码时,您可以在构建过程(IDE/makefile/build script/command-line)中有选择地定义/取消定义此常量,而无需编辑代码:

$ gcc -DENABLE_TESTS source.c

我添加这个答案是为了平衡所有早期的
#if 0
答案,但这个来自已接受答案的结构是特定问题的最佳答案:
/**/foo();/*/bar()/**/。请谨慎使用此类注释技巧,如果您在编译时进行检查,可以使用Gigi的答案,这将有条件地不编译代码部分。请注意,预处理器不知道变量、sizeof或编译器处理的其他事情(因此使用类似
4==sizeof(int)
的方法将无法运行)

如果您想编译一些不应该运行的调试代码,可以使用常规条件语句,如

bool debugging = false;

// banana banana banana

if (debugging)
{
    // do a bunch of stuff here
}

然后,您可以使用调试器访问跳过的部分,方法是将
调试
指定为true。

预处理器(如果else也起作用)

#如果1
// ... 如果1,则启用
#否则
// ... 如果0,则启用
#恩迪夫

宏就是这样做的

#define COMPILE 

#ifdef COMPILE

//code to comment begins
cout<<"ha ha ha"<<endl;
//code to comment ends 

#endif
#定义编译
#ifdef编译
//开始注释的代码

cout我不确定我是否应该发布这篇文章,因为我认为这不是什么“好代码”,但我承认我使用了以下技术作为一种快速的方式,以便在我刚签出某个东西时能够在两个小代码段之间快速切换:

// in the following , foo() is active:
/**/ foo(); /*/ bar(); /**/
现在只需删除前面的一个星号:

// now bar() is active:
/*/ foo(); /*/ bar(); /**/
当然,这永远不应该让它通过“只是检查东西”阶段

这将执行
foo()
。将
1
更改为
0
以执行
bar()


与涉及预处理器指令或注释的建议不同,这两个可能的分支都是编译的,因此您可以充分利用编译器的语法检查。

好吧,如果需要在完成前禁用一次或两次的代码,我更喜欢使用IDE提供的热键对代码进行注释,然后再进行注释。是的,我需要首先选择代码块,但我不希望每次需要禁用部分代码时都包含一个调试变量/预处理器指令/if语句。大多数时候都是这样

另一方面,如果我需要在两个代码块之间反复切换
,以找到正确的东西,那么我使用
If(0)
/
If(1)
来禁用/启用代码块

[code block 1]
后来


有时我会使用下面的技巧在两个懒惰的评论之间切换

//* <-- remove the first slash
[code block 1]
/*/
[code block 2]
//*/

在我的代码中,我喜欢在main.cpp文件中执行以下操作:

#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
您看到的头文件都包含自己的
main()
。根据第一个
#define
中定义的内容,程序中只有一个main()函数。如果完全省略该语句,则默认为您看到编写的规范main()函数


这使得为我的程序编写只关注一两个组件的测试变得很容易。最好的一点是,测试头与我的代码被整齐地隔离,因此没有测试代码被错误地留在(甚至链接到)中。

有时也需要同步地打开/关闭分散在程序中的代码块

受此启发,我制作了如下内容:

void doNothing(){}
#define DO_IF(flag, code) flag ? code : doNothing();
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;
}
例如,可按如下方式使用:

DO_IF(collectStats, recordStats());
DO_IF(collectStats, store(pullStat()));
一个更好的例子:

#define DO_IF(flag,code) if( flag ) { code; }

有时,我使用这种方法只是为了不让无限序列的if-endif定义使代码过度膨胀

debug.hpp

#ifdef _DEBUG
    #define IF_DEBUG(x) if(x)
#else
    #define IF_DEBUG(x) if(false)
#endif
#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 ...);
}
示例.cpp

#ifdef _DEBUG
    #define IF_DEBUG(x) if(x)
#else
    #define IF_DEBUG(x) if(false)
#endif
#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 ...);
}
这并不总是有效的,因为编译器可能会警告您在禁用的代码块中使用了未使用的变量。但至少可读性更好,可以抑制未使用的变量警告,例如:

void doNothing(){}
#define DO_IF(flag, code) flag ? code : doNothing();
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;
}

这并不总是一个好主意,但至少有助于重新组织代码。

使用注释会有问题,因为注释不能嵌套。如果你在被禁用的代码中有注释,那就行不通了。但是当你在原型制作过程中使用它时,你不会使用太多的注释。啊,不,那么,但是另一方面,在现实世界中,本应只是原型的代码往往会以一种过于频繁的方式潜入实际的代码中。这个名称听起来有点令人困惑。我希望使用
-DDISABLE\u TEST
编译可以禁用测试代码。在这里,它使它成为可能。@ArjunShankar是的,这让人困惑是的,这更好。这是一个有用的答案+1.java中有没有像这样整洁的东西?@LightyearBuzz java中没有预处理器,没有。但是java确实有一个类似的
-D
命令行开关,允许您在命令行上传递
系统
属性值。你会后悔的