如何在C++宏参数中使用括号?

3

我需要在宏的实际参数中使用括号,但是括号似乎会改变分隔宏参数的逗号的行为。

我让预处理器将其输出转储到文本文件中,以便查看其生成的内容。
然后我进行了基本测试以确认此行为。

#define MACRO_TEST_1( X , Y ) X && Y

MACRO_TEST_1 ( A , B )
// Desired result: A && B
// Actual result:  A && B

MACRO_TEST_1 ( ( C , D ) )
// Desired result: ( C && D )
// Actual result:  ( C , D ) &&
// Warning: "not enough actual parameters for macro 'MACRO_TEST_1'"

似乎将左括号添加到第一个参数中,将右括号添加到第二个参数中,会导致预处理器将逗号视为第一个参数的一部分,并因此假定我根本没有提供第二个参数。这一点可以从警告以及预处理器输出中在 && 后面什么也没有显示来证明。
那么我的问题是,如何告诉预处理器逗号分隔参数,即使这些参数中有括号?
我尝试转义括号或逗号,但这没有任何区别。(相同的结果,只是在预处理器输出中插入了转义字符。)

你真的需要用宏来完成这个吗?为什么? - Frank Puffer
@FrankPuffer 我不会详细说明。这是一个奇怪的情况,正在使用旧代码 - 可能是暂时的。我想可能有一些不太常见的技巧可以用来加入括号,这就是我目前需要的。 - Giffyguy
2
@FrankPuffer 函数不会有同样的问题吗?func(1, 2)是两个参数,而func((1, 2))只是一个参数。 - Barmar
我不明白为什么你在调用时加了额外的括号。括号的整个意义就是将事物分组。当你用括号包裹一个函数或宏参数时,它就成为一个单独的参数。 - Barmar
@Barmar 我明白。我的想法是,既然我们正在谈论预处理器,那么通常不会有类似这样的规则的解决方法吗?过去我并不知道预处理器会强加限制,使得某些结果无法实现...对我来说,这似乎很奇怪。 - Giffyguy
预处理器非常简单,它不提供任何机制来在字符级别上操作参数。它只提供简单的替换。没有办法去除额外的括号。 - Barmar
2个回答

3

我技术上找到了一种解决方案,虽然很丑陋。
你必须为括号字符定义符号。

#define OP (
#define CP )

#define MACRO_TEST_1( X , Y ) X && Y

MACRO_TEST_1 ( A , B )
// Desired result: A && B
// Actual result:  A && B

MACRO_TEST_1 ( OP C , D CP )
// Desired result: ( C && D )
// Actual result:  ( C && D )

2
所以我的问题是,如何告诉预处理器逗号分隔参数,即使参数中有括号?我认为,在这样的宏实现中,没有办法。从gcc.gnu.org可以看出,要调用带参数的宏,您需要写宏名称,后跟用逗号分隔的实际参数列表,其中每个参数中的括号必须平衡;括号内部的逗号不会结束该参数。您不能完全省略参数;如果一个宏需要两个参数,则其参数列表的顶层必须恰好有一个逗号。

谢谢。这听起来像是一个情况,其中转义字符应该能够合理地改变括号字符的含义。遗憾的是,这并不是事实 - 如果可以转义括号,宏可能会更加广泛/灵活。 - Giffyguy
1
@Giffyguy 无论如何,宏只是C语言的一个遗留问题,在许多情况下不足够灵活,所以...我们只能接受现实 :) - Edgar Rokjān

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接