gpt4 book ai didi

c - 禁止 C 预处理器在另一个中使用宏

转载 作者:行者123 更新时间:2023-12-01 23:08:45 25 4
gpt4 key购买 nike

我正在试验看看我可以滥用 C 预处理器到什么程度,我偶然发现了一个有趣的问题。

我有以下宏定义:

#define if(x)   if (x)
#define do {
#define elif(x) } else if (x) {
#define else } else {
#define done }

这应该允许我写:

if (i == 1)
do
...
elif (i == 2)
...
else
...
done

如果我只使用 ifelse 它工作得很好,除了 elif 的引入是有问题的,因为宏扩展为:

} } else { if (x) {

由于定义了 else

有什么方法可以让 elif 使用“原始”else 而无需预处理器拾取它?我想我需要尝试嵌套多个定义来欺骗预处理器直接粘贴单词而不解析它,但我不确定如何实现这一点。

任何想法,或者这在 GCC 中是不可能的吗?

编辑:

本质上,这可以归结为以下问题:

#define A B
#define B C

对于给定的两个定义 AB,我怎样才能让 A 仍然解析为文字词 B 而不是通过第二个定义并以 C 结束?

最佳答案

更新

我想我设法解决了它。我利用了它:

if(x) {
...
}

相同
for(; x ;) {
...
break:
}

我们需要的是保存x的结果。我们不能重用它,因为 x 可能是一个有副作用的表达式。所以:

int b;

for(; b = (x);) {

break;
}

现在,我们可以检查 b 以查看上面的 for 循环是否被执行。使用 for 循环完成的完整 if-elif-else 模式如下所示:

for(;b = (x);) { // if
...
break;
}

for(; !b ? b=(x==1) : 0;) { // elif
...
break;
}

for(; !b ;) { // else
...
break;
}

有了它,我们可以像这样包装它,但要注意。但是,如果您在循环内执行 if(x) break,这将无法正常工作。见下文。

int b; // Store truth value of last if or elif

#define if(x) for(;b = !!(x);)
#define do {
#define elif(x) break; } for(; !b ? b=!!(x) : 0;) {
#define else break; } for(;!b;) {
#define done break; }

演示:https://onlinegdb.com/Zq6Y7vm5Q

没有 break 语句的替代方法:

int b; // Store truth value of last if or elif

#define if(x) for(int c=1 ; c && (b = !!(x)); c=0)
#define do {
#define elif(x) } for(int c=1; c && (!b ? b=!!(x) : 0); c=0) {
#define else } for(int c=1; c && !b; c=0) {
#define done }

但是请注意,如果您在其中有一个 break 语句,那么这两者都可能会失败:

for(...) {
if(x)
do
break;
done
}

因为这会扩展到:

for(...) {
for(int c=1 ; c && (b = !!(x)); c=0)
{
break;
}
}

注意:

这应该是显而易见的,但是如果您决定使用此代码(不),则使用比 bc 更好的名称以避免冲突。

旧的解决方法

不完全符合您的要求,但您已经承认您基本上只是在滥用预处理器。 :)

但一个简单的解决方法是使用 else 的同义词。

#define if(x)      if (x)
#define do {
#define elif(x) } else if (x) {
#define otherwise } else {
#define done }

演示:https://onlinegdb.com/Cp-gYpOvm

它适用于零个、一个或多个 elif 实例,无论有多少个 elif,它都可以使用或不使用其他方式。

关于c - 禁止 C 预处理器在另一个中使用宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70296869/

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