使用c / c ++宏

时间:2015-07-02 18:38:02

标签: c++ c c-preprocessor

是否可以根据某些定义使用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

3 个答案:

答案 0 :(得分:2)

只能使用#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);
)

}

答案 1 :(得分:1)

不,使用预处理禁用有效代码段的唯一方法是#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可以是语法上正确的任何内容 - 您不必为每个测试创建函数,您可以将代码内联。

答案 2 :(得分:0)

无论如何,我会提到

的明显解决方案
#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一起使用。