C预处理

时间:2011-11-14 16:23:43

标签: gcc c-preprocessor

为什么某些字符串被替换而其他字符串未被#define替换?

$ cat test.c
#define X_ REPLACED
int main() {
  X_x();
  X_();
  return 0;
} 

$ gcc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"

int main() {
  X_x();
  REPLACED();
  return 0;
}

上方X_();已被替换,但X_x();未被替换。规则是什么?尽管进行了长时间的调查,但我无法在任何地方找到任何相关信息。

我正在考虑的原因是:我想链接到FFT库(FFTW),其常规名称以fftwf_,fftw_,fftwl_或fftwq_开头,具体取决于是使用单精度,双精度,长双精度还是二次精度

(gcc版本:4.4.3)

2 个答案:

答案 0 :(得分:3)

因为预处理器在逐个令牌的基础上工作,并且X_x计为一个令牌,因此#define会忽略它。如果您需要X_x成为REPLACEDx(),请使用sed或任何其他正则表达式来预处理代码。

因为宏很笨,所以参数内省是不可能的,所以你不能真正做到`#define fft_func(mytype) 如果您想在没有正则表达式的情况下执行此操作,请使用

#define CONCAT2(x, y) x##y
#define CONCAT(x, y) CONCAT2(x, y)
#define FFTW_FUNC(fft_type, fft_func) CONCAT(CONCAT(CONCAT(fftw, fft_type), _), fft_func)

int main() {
// ...
FFTW_FUNC(type, func)(args);
// ...
}

对于fft类型:

#define FFTWT_FLOAT f
#define FFTWT_DOUBLE
#define FFTWT_LONG_DOUBLE l
#define FFTWT_QUAD_PRECISION q

答案 1 :(得分:0)

谢谢你,这正是我想要的。我已经编辑了一下你的解决方案如下:

#ifdef single
  #define myType fftwf_
#else
  #ifdef double
    #define myType fftw_
  #endif
#endif

#define CONCAT(x, y) x##y
#define FFTW_FUNC(fft_type, fft_func) CONCAT(fft_type, fft_func)

int main() {
  //
  FFTW_FUNC(myType, func)(args);
  //                                                   
}

以上给出:

$ gcc -E -Ddouble test.c; gcc -E -Dsingle test.c
# 1 "test.c"
# 1 "<built-in>"    
# 1 "<command-line>"
# 1 "test.c"
# 12 "test.c"
int main() {

  fftw_func(args);

}
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
# 12 "test.c"
int main() {

  fftwf_func(args);

}