禁用部分代码的简单方法

Simple ways to disable parts of code

本文关键字:简单 方法 代码 用部      更新时间:2023-10-16

这不是解决特定问题的典型问题,而是大脑锻炼,但我想知道是否有人有解决方案。

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

//*
[code here]
//*/

现在,当您只删除第一个斜杠时,代码将被注释掉。

问题:有没有办法实现类似的if-else代码切换?我试图找到它,但我总是遇到一些问题,找不到可行的解决方案。

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

#if 0包装代码可以解决问题,但您仍然需要编辑代码以启用/禁用它。这并不比仅使用注释块好多少。

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

#ifdef ENABLE_TESTS
// code that you want to run ONLY during tests 
#endif

现在,在构建代码时,您可以在构建过程中有选择地定义/取消定义此常量 - IDE/makefile/build script/命令行 - 而无需编辑代码:

$ gcc -DENABLE_TESTS source.c

我添加了这个答案来平衡所有早期#if 0答案,但这种来自公认答案的结构是特定问题的最佳答案:/**/ foo(); /*/ bar(); /**/ 。请谨慎使用此类评论技巧。

#if 0
...disabled code here
#endif

我不确定我是否应该发布这个,因为它不是我认为是"好代码"的东西,但我承认使用以下技术作为一种快速肮脏的方法,以便在我刚刚检查某些内容时能够在两个小代码片段之间快速切换:

// in the following , foo() is active:
/**/ foo(); /*/ bar(); /**/

现在只需删除前面的星号之一:

// now bar() is active:
/*/ foo(); /*/ bar(); /**/

当然,这永远不应该超过"只是检查一下"阶段......

预处理器if-else也可以工作

#if 1
  // ... enabled if 1
#else
  // ... enabled if 0
#endif

在这里使用一些预处理器逻辑来帮助您:

#if 0
    //code goes here
#endif

享受

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

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

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

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

[code block 1]

if (0)
{
    [code block 1]
}
else
{
    [code block 2]
}

如果你在编译时进行检查,你可以使用 Gigi 的答案,它有条件地不编译代码部分。 请注意,预处理器不知道变量、大小或编译器处理的其他事情(因此使用类似 4 == sizeof(int) 的东西不会飞(

如果你想编译一些

不应该运行的调试代码,你可以使用常规的条件语句,比如

bool debugging = false;
// banana banana banana
if (debugging)
{
    // do a bunch of stuff here
}

然后,可以使用调试器通过将debugging分配给 true 来访问跳过的部分。

是做到这一点的方法。

#define COMPILE 
#ifdef COMPILE
//code to comment begins
cout<<"ha ha ha"<<endl;
//code to comment ends 
#endif

要禁用代码,只需注释掉编译行 #define

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

受到格雷厄姆早期帖子的启发,我做了这样的事情:

void doNothing(){}
#define DO_IF(flag, code) flag ? code : doNothing();

例如,这可以按如下方式使用:

DO_IF(collectStats, recordStats());
DO_IF(collectStats, store(pullStat()));

一个更好的:

#define DO_IF(flag,code) if( flag ) { code; }
1 ? foo() : bar();

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

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

有时我使用这种方法来避免通过无限序列的 if-endif 定义使代码过度膨胀。

调试.hpp

#ifdef _DEBUG
    #define IF_DEBUG(x) if(x)
#else
    #define IF_DEBUG(x) if(false)
#endif

示例.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 ...);
}

这并不总是有效的,因为编译器可能会警告您在此类禁用的代码块中使用了未使用的变量。但至少它的可读性更好,并且可以抑制未使用的变量警告,例如:

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;
}

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

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

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

虽然我认为正确的方法是使用预处理器指令

在我的代码中,我喜欢在我的主文件中执行此操作.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()。 程序中只有一个 main(( 函数,基于第一个#define中定义的内容。 如果完全省略该语句,则默认为您看到编写的规范 main(( 函数。

这使得为我的程序编写测试变得容易,这些测试本身只关注一个或两个组件。 最好的部分是测试标头与我的代码整齐地隔离,因此不会错误地留下(甚至链接(测试代码。