为什么我应该避免在C ++中的宏? [英] Why should I avoid macros in C++?
问题描述
我读过很多书,教程,我应该避免在c ++中的宏。好,但为什么?我不明白。它们非常有用,常用于C。
I have read in many books & tutorials that I should avoid macros in c++. Fine, but why? I don't get it. They are very useful and often used in C.
有人可以解释(非常)详细,为什么我应该在C ++中避免它们?
Could someone explain (very) detailed, why I should avoid them in C++?
推荐答案
宏不尊重范围界定规则,并且在语法级别而不是文本级别操作。
Macros don't respect scoping rules and operate at the textual level, as opposed to the syntax level. From this arise a number of pitfalls that can lead to strange, difficult to isolate bugs.
考虑下面这个着名的例子:
Consider the following well-known example:
#define max(a, b) ((a) < (b) ? (b) : (a))
⋮
int i = max(i++, j++);
在这种情况下,首选的备选方案是功能模板:
The preferred alternative in this case is a function template:
template <typename T>
T max(const T & a, const T & b) { return a < b ? b : a; }
这是另一种导致微妙问题的情况:
Here's another case that leads to subtle problems:
#define CHECK_ERROR(ret, msg) \
if (ret != STATUS_OK) { \
fprintf(stderr, "Error %d: %s\n", ret, msg); \
exit(1); \
}
⋮
if (ready)
CHECK_ERROR(try_send(packet), "Failed to send");
else
enqueue(packet);
您可能认为解决方案就像包装 CHECK_ERROR
{...}
,但这不会编译,因为;
else
。
You might think that the solution is as simple as wrapping the contents of CHECK_ERROR
in { … }
, but this won't compile due to the ;
before the else
.
为避免上述问题>附加到 CHECK_ERROR
的如果
而不是外部如果
),应该在 do ... while(false)
中包装这样的宏,如下所示:
To avoid the above problem (the else
attaching to CHECK_ERROR
's if
instead of the outer if
), one should wrap such macros in do … while (false)
as follows:
#define CHECK_ERROR(ret, msg) \
do { \
if (ret != STATUS_OK) { \
fprintf(stderr, "Error %d: %s\n", ret, msg); \
exit(1); \
} \
while (false)
关于宏的意义,但是确保整个块总是被视为单个语句,并且不会以令人惊讶的方式与如果
语句交互。
This has no effect on the meaning of the macro, but ensures that the entire block is always treated as a single statement and doesn't interact in surprising ways with if
statements.
长话短说,宏在许多层次都是危险的,因此只能作为最后手段使用。
Long story short, macros are hazardous at many levels and should thus be used only as a last resort.
这篇关于为什么我应该避免在C ++中的宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!