C语言中的宏条件语句

8
在C语言的宏函数中实现宏条件是否可能?类似于这样的内容:
#define fun(x)
#if x==0
    fun1;
#else
    fun2;
#endif

#define fun1 // do something here
#define fun2 // do something else here

换句话说,预处理器根据参数值决定使用哪个宏。
fun(0) // fun1 is "preprocessed"
fun(1) // fun2 is "preprocessed"

我知道这个例子不起作用,但我想知道是否有办法使其生效?

M.


1
预处理器在编译之前就“修改”了代码,因此在运行时肯定已经确定。 - alk
2
是的,我知道。但 x 不是一个变量,它的值在编译之前就已经确定了。 - Marko Gulin
BOOST_PP_IF(或IIF) - BLUEPIXY
我认为这是不可能的。C预处理器在功能上非常有限。我喜欢使用GNU m4,它非常强大。不幸的是,它的开发似乎陷入了困境,我不知道未来是否会有发布(如果有的话)。对于cpp,我只需像您所做的那样定义一个值x,但将条件指令放在宏外部。 - cadaniluk
1个回答

11
你不能在预处理器指令内使用预处理器条件语句。关于此问题的背景介绍和解决方法可以参考以下链接:如何在C预处理器中使用#if?C预处理器宏是否能包含预处理器指令? 虽然如此,你仍然可以使用:
#include <stdio.h>

#define CONCAT(i) fun ## i() /* For docs on this see here:
                                https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html */
#define fun(i) CONCAT(i)

void fun1(void)
{
  puts(__FUNCTION__);
}

void fun2(void)
{
  puts(__FUNCTION__);
}


int main(void)
{
  fun(1);
  fun(2);
}

这将导致:
...

int main(void)
{
  fun1();
  fun2();
}

传递给编译器并打印:
fun1
fun2

您可以通过以下方式进一步混淆您的代码:

... 

#define MYZERO 1
#define MYONE 2

int main(void)
{
  fun(MYZERO);
  fun(MYONE);
}

导致相同的代码传递给编译器。

1
我点赞并删除了我的回答,但对于其他人来说,解释为什么“#define”内部的“#if”不起作用会很有用。 - abligh
很好的解决方案,但是为什么你的标记粘贴宏被命名为“stringify”? ;) - Quentin
@Quentin:嗨,习惯和模式... :} 正在修复这个问题。 - alk
亲爱的alk,感谢您的回答。我有一个关于宏的问题。是否可能得到这样的结果 - 宏函数被称为macro_fun(7),输出为AD1。换句话说,我想评估7-6,并将结果作为标记连接起来,例如AD ## x-6。我知道这个例子不起作用,但我能否以某种方式使其起作用? - Marko Gulin
@Marko:我不知道预处理器是否执行任何算术运算,比如将3-2计算为1等。也许你想要了解函数指针,并在C语言中在运行时处理所有这些映射。 - alk
@abligh 我怀疑这是因为 #if 语句在宏定义时被评估,而不是在宏调用时被评估。 - HelloGoodbye

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