gpt4 book ai didi

c++ - 为什么在宏中使用明显无意义的 do-while 和 if-else 语句?

转载 作者:太空狗 更新时间:2023-10-29 23:20:07 36 4
gpt4 key购买 nike

在许多 C/C++ 宏中,我看到宏的代码包裹在看似毫无意义的 do while 循环中。以下是示例。

#define FOO(X) do { f(X); g(X); } while (0)
#define FOO(X) if (1) { f(X); g(X); } else

我看不到 do while 正在做什么。为什么不写这个没有它?

#define FOO(X) f(X); g(X)

最佳答案

do ... whileif ... else 是为了让一个宏后的分号总是意味着同样的事情。比方说你有类似你的第二个宏的东西。

#define BAR(X) f(x); g(x)

现在,如果您要在 if ... else 语句中使用 BAR(X);,其中 if 语句的主体未包含在大括号中,你会得到一个糟糕的惊喜。

if (corge)
BAR(corge);
else
gralt();

上面的代码会展开成

if (corge)
f(corge); g(corge);
else
gralt();

这在语法上是不正确的,因为 else 不再与 if 相关联。在宏中用大括号括起来没有帮助,因为大括号后的分号在语法上是不正确的。

if (corge)
{f(corge); g(corge);};
else
gralt();

有两种方法可以解决这个问题。第一种是使用逗号在宏中对语句进行排序,同时又不剥夺它像表达式一样工作的能力。

#define BAR(X) f(X), g(X)

上面版本的 bar BAR 将上面的代码扩展成下面的代码,这在语法上是正确的。

if (corge)
f(corge), g(corge);
else
gralt();

如果不是 f(X) 而不是您有更复杂的代码体需要放在它自己的 block 中,例如声明局部变量,这将不起作用。在最一般的情况下,解决方案是使用类似 do ... while 的方法来使宏成为一个带有分号的单个语句而不会混淆。

#define BAR(X) do { \
int i = f(X); \
if (i > 4) g(i); \
} while (0)

你不必使用 do ... while,你也可以用 if ... else 做一些事情,尽管 when if ... elseif ... else 内部扩展它导致“dangling else ”,这可能会使现有的悬而未决的 else 问题更难找到,如以下代码。

if (corge)
if (1) { f(corge); g(corge); } else;
else
gralt();

重点是在悬空分号是错误的上下文中用完分号。当然,此时可以(而且可能应该)争论将 BAR 声明为实际函数而不是宏会更好。

总而言之,do ... while 可以解决 C 预处理器的缺点。当那些 C 风格指南告诉您放弃 C 预处理器时,这就是他们担心的事情。

关于c++ - 为什么在宏中使用明显无意义的 do-while 和 if-else 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3752166/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com