这不是解决特定问题的典型问题,而是一种大脑锻炼,但我想知道是否有人有解决方案。
在开发中,我们经常需要禁用或切换部分代码来检查不同的方法。为此,我们使用 comments 或#defines
,但我最喜欢的是:
//*
[code here]
//*/
现在,当您仅删除第一个斜杠时,代码将被注释掉。
问题:有没有办法实现类似的 if-else代码切换?我试图找到它,但我总是遇到一些问题并且找不到有效的解决方案。
也许你知道任何类似的技巧?
用包装代码可以解决#if 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(); /**/
。请谨慎使用此类评论技巧。
#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 的答案,这将有条件地不编译代码段。请注意,预处理器不了解变量、sizeof 或编译器处理的其他内容(因此使用类似的东西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 compile line
有时也需要同步打开/关闭分散在程序中的代码块。
受格雷厄姆早先的这篇文章的启发,我做了这样的事情:
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
a0
来执行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
}
虽然我认为正确的方法是使用PreProcessor Directives
在我的代码中,我喜欢在 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()
. 根据第一个定义的内容,程序中只有一个 main() 函数#define
。如果该语句被完全省略,它默认为您看到的规范 main() 函数。
这使得为我的程序编写只关注一两个组件的测试变得很容易。最好的部分是测试标头与我的代码完全隔离,因此不会错误地留下(甚至链接)测试代码。