2

我正在尝试做一些在概念上与此类似的事情,但似乎无法让它工作(最后显示错误)任何想法?

#include <stdio.h>

int main( int argc , char const *argv[] )
{
  int abc_def_ghi = 42;
  #define SUFFIX ghi
  #define VAR(prefix) prefix##_def_##SUFFIX
  printf( "%d\n" , VAR(abc) );
  return 0;
}

// untitled:8: error: ‘abc_def_SUFFIX’ undeclared (first use in this function)
4

3 回答 3

11

你只需要额外的间接:

#include <stdio.h>

int main( int argc , char const *argv[] )
{
  int abc_def_ghi = 42;
  #define SUFFIX ghi
  #define VAR3(prefix, suffix) prefix##_def_##suffix
  #define VAR2(prefix, suffix) VAR3(prefix, suffix)
  #define VAR(prefix) VAR2(prefix, SUFFIX)
  printf( "%d\n" , VAR(abc) );
  return 0;
}

尽管它看起来是多余的,但事实并非如此。

于 2009-11-20T01:06:00.980 回答
7

正确使用字符串化 ( #) 或标记粘贴 ( ##) 预处理运算符的常用习惯用法是使用第二级间接。(## 预处理器运算符的应用和要考虑的问题是什么?)。

#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)

#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)

然后:

int main( int argc , char const *argv[] )
{
  int abc_def_ghi = 42;
  #define SUFFIX ghi
  #define VAR(prefix) PASTE( prefix, PASTE( _def_, SUFFIX))
  printf( "%d\n" , VAR(abc) );
  return 0;
}

应该给你你正在寻找的结果。

基本上,发生的情况是#and##运算符的处理发生在宏替换之前。然后发生另一轮宏替换。因此,如果您希望宏与这些操作一起使用,您必须使用简单地进行替换的第一级 - 否则首先发生字符串化或粘贴,并且宏不再是宏 - 它们是第一轮字符串化/粘贴产生。

更直接地说——第一级宏允许替换宏参数,然后第二级宏替换进行字符串化/标记粘贴操作。

于 2009-11-20T08:27:47.207 回答
0

这适用于足够的间接级别。虽然另一个答案就足够了,但我想提供这段代码作为演示:

#define SUFFIX ghi

#define VAR1(prefix) prefix##_def_##SUFFIX
VAR1(abc)

#define VAR2_(prefix, sfx) prefix##_def_##sfx
#define VAR2(prefix) VAR2_(prefix,SUFFIX)
VAR2(abc)

#define VAR3_(prefix, sfx) prefix##_def_##sfx
#define VAR3x(prefix,sfx) VAR3_(prefix,sfx)
#define VAR3(prefix) VAR3x(prefix,SUFFIX)
VAR3(abc)

保存这是一个文本文件,xc,并且只对其进行预处理。

gcc -E x.c

观察和思考。我自己也不太明白。只需花两个小时尝试使用 stringify 来获取宏即可工作。有趣的是,有时需要双重间接。

于 2010-01-16T22:09:33.107 回答