8

我有两个功能:

void foo0(int bar);
void foo1(int bar);

我无法创建一个宏,该宏QUX将基于另一个宏扩展为这些函数名称BAZ。我尝试了以下方法:

#define BAZ 0
#define QUX(x) foo##BAZ(x)

但它不起作用,因为生成的函数是fooBAZ(). 我怎样才能让它生成foo0()

4

5 回答 5

10
#define CAT_I(a,b) a##b
#define CAT(a,b) CAT_I(a, b)
#define QUX(x) CAT(foo, BAZ) ## (x)
于 2013-07-17T12:49:05.230 回答
7
#include <stdio.h>

#define ONE 1
#define ZERO 0

#define GLUE_HELPER(x, y) x##y
#define GLUE(x, y) GLUE_HELPER(x, y)

int foo0(int x)
{
    printf("\n foo0...%d\n", x);
}

int foo1(int x)
{
    printf("\n foo1...%d\n",x);
}

int main()
{
   //Calling Function
   GLUE(foo,ZERO)(5);    
   GLUE(foo,ONE)(10);    
   return 0;
}

将按预期工作。您必须在二级宏扩展中进行字符串连接。

于 2013-07-17T12:45:34.953 回答
2

要么有一个中间宏,再次评估

#define QUX_0(A) foo ## A
#define QUX_1(A) QUX_0(A)
#define QUX(x) QUX_1(BAZ)(x)

或者甚至更简单

#define fooBAZ foo0

顺便说一句:您的第二个##应该在符合标准的编译器上出错。也不要放在;宏定义的末尾,它会咬你。

于 2013-07-17T12:18:41.890 回答
1

这是我在网上阅读后提出的一个解决方案。基本上,为了让数字显示在签名中,您需要对参数进行字符串化。如果您对参数进行字符串化,则预扫描不会完成,这会导致您的 fooBAZ 函数定义(它没有完全展开)

如果您使用另一个宏中介,它将完成扩展。

这是一个链接,进一步解释了预扫描及其未完成的时间。

// Testing.cpp : Defines the entry point for the console application.
//
#include <stdio.h>

#define BAZ 0

#define QUXdef(x) QUX(x)
#define QUX(x) foo##x()

#define QUXimp(x) DEF(x)
#define DEF(x) foo##x()


//Function Def
void QUXdef(BAZ);

int main(int argc, char* argv[])
{
    foo0();
}

void QUXimp(BAZ)
{
    printf("Hello world\n");
}

注意:我包含了另一组用于实现该功能的宏。你没有要求这个,但我认为如果定义和实现函数是你的目标,它会更“完整”。QUXdef 和 QUX 满足您的特定需求。

编辑1:

  • 我从解决方案中删除了 C++ 风格的代码。Jens Gustedt 引起了我的注意,考虑到它被标记为 C(我没有完整阅读的错),这是一个有效的批评。
  • 我还删除了 ; 形成宏本身。它现在由用户提供,而不是更具可读性。这也是 Jens Gustedt 的有效批评
  • 我从宏扩展中取出了 void。相反,我让用户定义返回类型。对我来说,这似乎也允许更多的可读性。
  • 我删除了 stdafx 语句,考虑到这是针对 C 代码的,而纯 C 程序员不太可能使用 Visual Studio。就目前而言,它应该能够被复制并粘贴到一个文件中,然后由 GCC 或其他一些更流行的 C 编译器编译。

否则,这个答案是可靠的,如果你查看我提供的链接,它解释了需要一个中间宏来获得 Asker 正在寻找的正确扩展。

于 2013-07-17T12:52:39.730 回答
0

如果只有两种可能:

#if BAZ == 0
#define QUX(X) foo0(x)
#else
#define QUX(X) foo1(x)
#endif
于 2013-07-17T12:26:54.427 回答