为什么在定义宏中使用括号会出错?
Why using a parenthesis in define macro gives error?
#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 ';' token"
#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 在预处理器有 运行.
后停止编译过程
#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 ';' token"
#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 在预处理器有 运行.