С предварительной обработки - PullRequest
0 голосов
/ 14 ноября 2011

Почему некоторые строки заменяются, а другие не заменяются на #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 ]

3 голосов
/ 14 ноября 2011

Поскольку препроцессор работает на основе токенов, а X_x считается одним токеном, следовательно, #define игнорирует его.Если вам нужно X_x, чтобы стать REPLACEDx(), используйте sed или любой другой regexer для предварительной обработки кода.

Поскольку макросы глупы, самоанализ аргументов невозможен, поэтому вы не можете сделать `#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
0 голосов
/ 15 ноября 2011

Спасибо, это именно то, что я хотел. Я немного отредактировал ваше решение следующим образом:

#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);

}
...