跳转至内容

更多 C++ 惯用法/多语句宏

来自 Wikibooks,开放世界中的开放书籍

多语句宏

[编辑 | 编辑源代码]

编写多语句(多行)宏。

也称为

[编辑 | 编辑源代码]

有时将两个或多个语句组合到一个宏中并像函数调用一样调用它们会很有用。通常,内联函数应该是首选,但调试宏等几乎总是宏而不是函数调用。以一种天真的方式将多个语句组合到一个宏中可能会导致编译错误,这些错误乍一看并不明显。例如,

#define MACRO(X,Y) { statement1; statement2; }

如果在末尾附加分号,则在 if 语句中将失败。

if (cond)
   MACRO(10,20); // Compiler error here because of the semi-colon.
else
   statement3;

上述语句展开为

if (cond)
   { statement1; statement2; }; // Compiler error here because of the semi-colon.
else
   statement3;

导致编译错误。因此,人们想出了一个广泛使用用于多语句宏的惯用法,它基于 do-while 循环。

解决方案和示例代码

[编辑 | 编辑源代码]

这是一个多语句宏惯用法的示例。

#define MACRO(arg1, arg2) do {  \
  /* declarations, if any */    \
  statement1;                   \
  statement2;                   \
  /* ... */                     \
  } while(0)	/* (no trailing ; ) */

当调用者附加分号时,无论上下文如何,此扩展都成为单个语句。优化编译器通常会删除任何死测试,例如 while(0)。当宏用作函数调用的参数时,此惯用法没有用。此外,此惯用法允许 return 语句。

func(MACRO(10,20)); // Syntax error here.

已知用途

[编辑 | 编辑源代码]

自适应通信环境 (ACE) 中的 ACE_NEW_RETURN、ACE_NEW_NORETURN 宏。

#define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
      do { POINTER = new (ACE_nothrow) CONSTRUCTOR; \
      if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
    } while (0)
[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]
华夏公益教科书