强制编译器忽略程序中的某些行
假设我有10,000行C ++代码。 此代码的200行用于testing目的(例如,检查程序并显示错误消息)。
有没有办法在C + +忽略或考虑代码的一些行(可能与预处理关键字)?
简短的回答:
 使用macros和#ifdef检查。 例如: 
 #ifdef MY_CONTROL_MACRO ... #endif 
 如果您已经定义了MY_CONTROL_MACROmacros,则仅编译该范围内的代码。 
更多东西:
- 
要定义这样一个macros,你可以 -  将#define MY_CONTROL_MACRO添加到您的代码中。 要么,
-  对于VS,将MY_CONTROL_MACRO添加到Project > Properties > C/C++ > Preprocessor > Preprocessor Definitions。 要么,
-  对于GCC,请使用选项-DMY_CONTROL_MACRO编译您的代码。
 
-  将
- 
你可以在这里查看更多信息。 这个块被称为条件组。 当且仅当MACRO被定义时,受控文本将被包括在预处理器的输出中。 如果MACRO被定义,条件成功,否则失败。 条件内的受控文本可以包含预处理指令。 只有条件成功时才执行。 您可以在其他条件组内嵌套条件组,但它们必须完全嵌套。 换句话说,“#endif”总是匹配最接近的#ifdef(或#ifndef或#if)。 另外,您不能在一个文件中启动一个条件组,并在另一个文件中结束它。 
- 
你也可以使用先进的 ifdef-else-endif风格:#ifdef MY_CONTROL_MACRO ... // this part will be valid if MY_CONTROL_MACRO is defined #else ... // this part will be valid if MY_CONTROL_MACRO is NOT defined #endif
使用“#ifdef …#endif”环绕代码,然后使用编译器选项设置标志:
 #ifdef MYTEST_ONLY_FUNCTIONALITY_ENABLED ... #endif 
然后您可以使用编译器选项来包含此代码。 例如,在GCC中:
 -DMYTEST_ONLY_FUNCTIONALITY_ENABLED 
虽然,说实话,我认为这种方法在大型项目中通常不是很好维护,如果可能的话,简单地把纯粹的testing代码移动到一个完全独立的库(没有这个条件逻辑)代码到您的testing二进制文件而不是您的非testing二进制文件。 这也避免了必须在debugging和非debugging模式下编译每个其他库。
 这是#ifdefdevise目的 
你把
 #ifdef TESTS ... test code ... #endif 
然后您可以传递给编译器选项来决定是否要将testing部分编译进去。 例如,用g ++就是了
 g++ -DTESTS ... 
 使用现有的约定,并使用NDEBUGmacros。 所有常见的编译器都将这个macros定义为发布版本,而不是将其定义为debugging版本。 
 macros原本是为了控制assert(3)的输出而定义的,并且在POSIX标准中至less从C89开始定义。 
 请注意,您必须使用#ifndef来反转testing。 
一个例子:
 #ifndef NDEBUG /* Debugging code */ std::cerr << "So far we have seen " << unicorns << " unicorns" << std::endl; #endif 
  PS使用gcc / g++ ,您可以通过在命令行中添加-g来执行debugging版本。 
使用预处理器后卫无疑是最灵活和最常见的方法。 但是,如果可能的话,我build议使用if语句。 例如,而不是
 void example(int a){ int some_local; ... #ifdef _DEBUG std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl; #endif .... } 
假设ENABLE_DEBUG定义为0或非零,我会使用
 void example(int a){ int some_local; ... if(ENABLE_DEBUG) std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl; ... } 
由于ENABLE_DEBUG是一个常量,当ENABLE_DEBUG为0时,编译器将不会为它所保护的语句生成任何代码。 那么,为什么用这个方法代替#ifdef呢?
- 如果在整个代码中有很多独立的debugging语句,那么读起来会更容易一些
- 更重要的是,即使没有生成代码,代码也总是处理语法错误。 如果debugging代码不经常启用,这可能非常有用。 如果variables发生变化(例如,在上面的例子中,如果参数a被重命名),那么进行更改的人将知道他们也必须更新debugging语句。 如果使用了#ifdefs,那么它可以隐藏bit rot,直到有人需要启用debugging代码,然后他们必须去尝试修复代码,这些代码可能不是很明显。
显然这种方法只适用于方法/函数体内的debugging语句。
 围绕你的testing代码#ifdef DEBUG 。 
 #if DEBUG .... #endif 
 要走的路是使用预处理器指令,将define传递给编译器或从头文件“config.h”中获取: 
 #if defined(DEBUG) // or #ifdef DEBUG // Debug code #endif 
为了避免在源码中到处使用:
 #if defined(DEBUG) My_Debug_function(some_variable) #endif 
你可以在标题中做
 #if !defined(DEBUG) // or #ifndef DEBUG # define My_Debug_function(some_variable) do { static_cast<void>(some_variable); } while (false) /* Do nothing */ #endif 
 所以几乎正常使用My_Debug_function 。 
使用预处理器#define和#if
取决于你的编译器,你应该有一些默认可用的variables,即NDEBUG(用于非debugging)或DEBUG
你可以自己在代码中定义一个variables
 #define MY_VARIABLE 
并使用它如下
 #ifdef MY_VARIABLE //code that compiles only if MY_VARIABLE is defined printf("test output here"); #else //code that compiles only if MY_VARIABLE is NOT defined printf("MY_VARIABLE is not defined"); #endif 
在线search更多信息
 #define, #if, #ifdef, #ifndef