为什么在定义宏中使用括号会产生错误?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在定义宏中使用括号会产生错误?相关的知识,希望对你有一定的参考价值。
#define swap(a,b) a = a ^ b; b = a ^ b; a = a ^ b;
int main()
{
swap(a,b)
}
给出正确的答案。
#define swap(a,b) (a = a ^ b; b = a ^ b; a = a ^ b;)
int main()
{
swap(a,b)
}
出现编译错误:“expected')'before';'令牌”
#define swap(a,b) ({a = a ^ b; b = a ^ b; a = a ^ b;})
int main()
{
swap(a,b); //note the semicolon at the end, without that the compiler gives an error
}
工作良好。
现在我的困惑是为什么第二个不起作用?我认为它应该完美。其次,为什么我需要在第三个宏调用结束时加一个分号?
答案
如果你展开宏,它们中的三个看起来像这样:
a = a ^ b; b = a ^ b; a = a ^ b;
(a = a ^ b; b = a ^ b; a = a ^ b;)
({a = a ^ b; b = a ^ b; a = a ^ b;});
第一个很好。第二个是语法错误:您不能用括号括起多个语句。这不是一件事。第三个使用名为statement expressions的GCC扩展。您可以使用({ ... })
将一组语句包围起来,将其视为表达式。
请注意,在宏中具有多个语句的标准习惯用法是do { ... } while (0)
loop with no trailing semi-colon。
#define swap(a,b) do { a = a ^ b; b = a ^ b; a = a ^ b; } while (0)
另一答案
预处理器用字符串替换宏定义,然后编译生成的源代码。对于示例2,您得到的源代码将是:
int main()
{
(a = a ^ b; b = a ^ b; a = a ^ b;)
}
那是无效的C代码;这就是你的编译器抱怨的原因。这也应该回答你的第二个问题。
尝试使用gcc -E mycode.c
。 -E
告诉gcc在预处理器运行后停止编译过程。
以上是关于为什么在定义宏中使用括号会产生错误?的主要内容,如果未能解决你的问题,请参考以下文章