C ++中的多语句宏

时间:2009-12-02 00:27:26

标签: c++ macros

在C ++ 中,是否可以在嵌套if语句中创建多语句宏,如下所示?我已经尝试了一段时间了,我得到了第二个if语句无法看到' symbol '的范围问题。也许我需要进一步了解宏。

#define MATCH_SYMBOL( symbol, token)
     if(something == symbol){
          if( symbol == '-'){
          }else if (symbol != '-'){
          }
     other steps;
     }

7 个答案:

答案 0 :(得分:11)

对于多行宏,你需要在最后一行的末尾添加一个\字符,告诉宏处理器继续解析下一行的宏,如下所示:

#define MATCH_SYMBOL( symbol, token) \
     if(something == symbol){        \
          if( symbol == '-'){        \
          }else if (symbol != '-'){  \
          }                          \
     other steps;                    \
     }

现在,它正试图将其解释为1行宏,然后将一些实际代码解释为文件顶部,这不是您想要的:

#define MATCH_SYMBOL( symbol, token)

// and then... wrongly thinking this is separate...

 if(something == symbol){ // symbol was never defined, because the macro was never used here!
      if( symbol == '-'){
      }else if (symbol != '-'){
      }
 other steps;
 }

答案 1 :(得分:8)

如果你正在使用C ++,你应该完全避免使用宏。它们不是类型安全的,它们不是名称空间感知的,它们很难调试,只是它们非常混乱。

如果您需要与类型无关的功能,请使用模板:

template <typename T>
bool match_symbol(T symbol, T token) {
    if(something == symbol){
        if( symbol == '-'){
        }else if (symbol != '-'){
        }
    ...

或参数可以是不同的类型:

template <typename T, typename V>
bool match_symbol(T symbol, V token) {
    if(something == symbol){
        if( symbol == '-'){
        }else if (symbol != '-'){
        }
    ...

答案 2 :(得分:4)

请注意,此处的部分答案存在问题。

例如,对于正常语句,您可以这样做:

if (foo)
   function();
else
   otherstuff();

如果您在此处遵循了一些建议,但如果使用宏替换function,则可能会扩展为:

if (foo)
   if (something) { /* ... */ }
   else           { /* ... */ }; // <-- note evil semicolon!
else
   otherstuff();

因此,人们为避免这种情况而采取的常见(丑陋)黑客行为是:

#define MATCH_SYMBOL(symbol, token)    \
    do                                 \
    {                                  \
       if(something == symbol)         \
       {                               \
          if( symbol == '-')           \
          {                            \
          }                            \
          else if (symbol != '-')      \
          {                            \
          }                            \
          other steps;                 \
       }                               \
    }                                  \
    while (0) // no semicolon here

这样,“语句”MATCH_SYMBOL(a, b)可以像正常语句一样以分号结尾。你还可以在多个陈述中使用大括号。

如果你认为没有人疯狂地使用这种技术,那就再想一想。例如,它在Linux内核中很常见。

答案 3 :(得分:1)

你需要在宏的所有行的末尾加上反斜杠(\),但最后一行。

答案 4 :(得分:1)

C ++的方式:

inline void MATCH_SYMBOL(const Symbol& symbol, const Token& token) {
    /* ... */
    if (something == symbol) {

        if ('-' == symbol) {
        /* ... */
        }
        else if ('-' != symbol) {
        /* ... */
        }
    }
    /* ...other steps... */
}

答案 5 :(得分:0)

另外,看看是否可以用函数替换宏。

?
MATCH_SYMBOL(Sym const & symbol, Tok const & token)
{
    ...
}

答案 6 :(得分:0)

还可以定义宏功能并实现功能而不是

#define MATCH_SYMBOL( symbol, token) match_symbol(symbol,token)