使用 c/c++ 宏禁用多行语句

Disable multiline statements with c/c++ macro

是否可以根据某些定义使用 c/c++ 预处理器禁用代码块,而不用 #ifdef #endif 检测代码?

 // if ENABLE_TEST_SONAR is not defined, test code will be eliminated by preprocessor
 TEST_BEGIN(SONAR)
   uint8_t sonar_range = get_sonar_measurement(i);
   TEST_ASSERT(sonar_range < 300)
   TEST_ASSERT(sonar_range > 100)
 TEST_END

功能等同于以下内容:

#ifdef TEST_SONAR
    serial_print("test_case sonar:\r\n");
    uint8_t sonar_range = get_sonar_measurement(i);
    serial_print("  test sonar_range < 300:%d\r\n", sonar_range < 300);
    serial_print("  test sonar_range > 100:%d\r\n", sonar_range > 100);
#endif TEST_SONAR

不,使用预处理有效禁用部分代码的唯一方法是#ifdef #endif。理论上,您可以使用 #if identifier,但最好坚持检查变量是否已定义。

另一种选择(可能)是使用预处理宏:

编辑:

也许使用普通函数 #ifdef 可能会更好?

function test_function() {
  /* Do whatever test */
}
#define TESTING_IDENTIFIER
#define TEST( i, f ) if ((i)) do { f } while (0)

然后,对于每个测试,您定义一个唯一标识符并通过首先提供标识符然后提供函数(带括号)来调用它。

TEST( TESTING_IDENTIFIER, test_function() );

最后,f 可以是语法正确的任何东西 -- 您不必为每个测试都创建一个函数,您可以将代码内联。

只能使用 #ifdef#if 禁用多行,但可以使用宏禁用单行。注意多行可以用\

组合
#ifdef DOIT
#define MYMACRO(x) \
 some code \
 more code \
 even more \
#else
#define MYMACRO(x)
#endif

然后当您调用 MYMACRO 时,根据是否定义了 DOIT

,将包含或不包含该代码

这是最接近的,经常用于调试代码

编辑:一时兴起,我尝试了以下方法,它似乎有效(在 MSVC++ 和 g++ 中):

#define DOIT
#ifdef DOIT
#define MYMACRO(x) x
#else
#define MYMACRO(x)
#endif

void foo(int, int, int)
{
}

int main(int, char **)
{
    int x = 7;
MYMACRO(
if (x) 
return 27; 
for (int i = 0; i < 10; ++i) 
    foo(1, 2, 3);
)

}

无论如何我都会提到一个明显的解决方案

#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }

...
TEST_SONAR
code
TEST_SONAR_END

代码仍然会被编译,不会被完全删除,但一些聪明的编译器可能会优化它。

UPD:刚刚测试

#include <iostream>
using namespace std;

//#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }

int main() {
TEST_SONAR
cout << "abc" << endl;
TEST_SONAR_END
}

生成完全相同的二进制文件,其中 cout 行被注释掉和未被注释掉,所以代码确实被剥离了。将 g++ 4.9.2 与 -O2.

一起使用