C++宏用于有条件地编译代码?

4
我希望你能根据宏条件编译代码。基本上,我有一个宏看起来像这样(从真实版本简化):
#if DEBUG
    #define START_BLOCK( x ) if(DebugVar(#x) \
        { char debugBuf[8192];
    #define END_BLOCK( ) printf("%s\n", debugBuf); }
#else
    #define START_BLOCK( x ) (void)0;
    #define END_BLOCK( ) (void)0;
#endif

问题在于如果定义了DEBUG,您可以执行以下操作:
START_BLOCK( test )
     char str[] = "Test is defined";
     strcpy(debugBuf, str);
END_BLOCK( )

START_BLOCK( foo )
    char str[] = "Foo is defined";
    strcpy(debugBuf, str);
END_BLOCK( )

每个块都在其自己的作用域内,所以一切正常。然而,如果未定义DEBUG,那么您将在第二个块中重新定义str。(好吧,您还会得到debugBuf未定义,但这只是简化示例的副作用。)

我想做的是让# else成为以下内容:

#else
    #define START_BLOCK( x ) #if 0
    #define END_BLOCK( ) #endif
#endif

或者其他不需要在开始/结束块之间编译任何内容的方法。我尝试了上面的方法,也尝试了类似以下的方法:

#else
    #define NULLMACRO( ... ) (void)0
    #define START_BLOCK( x ) NULLMACRO(
    #define END_BLOCK( ) )
#endif

没有任何运气。

有没有办法让它工作?我刚想到的一个想法是,我可以滥用优化编译器并使用:

#else
    #define START_BLOCK( x ) if(0){
    #define END_BLOCK( ) }
#endif

并且相信它将完全编译出该块。是否还有其他解决方案?

2个回答

5

所以你想要有自己作用域的条件块?

这里有一个非常易读的解决方案,它依赖于编译器进行优化:

#define DEBUG 1

if (DEBUG) {
    // ...
}

这里有一个只使用预处理器的示例:

#define DEBUG 1

#ifdef DEBUG
    #define IFDEBUG(x) {x}
#else
    #define IFDEBUG(x)
#endif

IFDEBUG(
    // ...
)

或者手动执行:
#define DEBUG 1

#ifdef DEBUG
{
    // ...
}
#endif

我最初实际上使用的是你中间那个选项,问题在于gcc和Visual Studio如何处理带有0或1个参数的可变参数,在我的简化示例中没有涉及到,真遗憾。 - Doug-W
@Doug-W: 谁在谈论可变参数? - orlp
如果你的表达式包含任何逗号,那么你的中间方法就不起作用了。而且一个冗长的代码块通常会包含逗号。解决这个问题的一种方法是使用可变参数(它将包括所有内容,包括逗号),但可变参数在处理低参数计数的情况下效果不佳。 - AHelps

1

会:

#if DEBUG
    #define START_BLOCK( x ) if(DebugVar(#x) \
        { char debugBuf[8192];
    #define END_BLOCK( ) printf("%s\n", debugBuf); }
#else
    #define START_BLOCK( x ) {
    #define END_BLOCK( ) }
#endif

do?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接