C编程:预处理器,宏作为标记

Jos*_*eek 2 c macros token stringification c-preprocessor

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

#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)
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 10

你只需要额外的间接:

#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;
}
Run Code Online (Sandbox Code Playgroud)

即使它看起来多余,但事实并非如此.


Mic*_*urr 7

正确使用stringizing(#)或token pasting(##)预处理运算符的常用习惯是使用第二级间接.(##预处理器运算符和陷阱的应用有哪些应用?).

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

#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)
Run Code Online (Sandbox Code Playgroud)

然后:

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;
}
Run Code Online (Sandbox Code Playgroud)

应该给你你想要的结果.

基本上,发生的是在宏替换之前处理###运算符.然后发生另一轮宏观替换.因此,如果你想要将宏与这些操作一起使用,你必须使用简单替换的第一级 - 否则首先发生字符串化或粘贴,而宏不再是宏 - 它们就是第一轮的字符串化/粘贴产生.

更直接地说 - 第一级宏允许替换宏参数,然后第二级宏替换执行stringify/token-pasting操作.