Работает ли #ifdef (или другие директивы препроцессора) для объявлений функций (для проверки существования функции)?

Почему следующий код не работает должным образом?

void foobar(int);

#ifndef foobar
  printf("foobar exists");
#endif

Он всегда печатает сообщение; очевидно, что он не может обнаружить существование функции как сущности. (Это проблема перегрузки?)

Почему #ifdef (или его варианты) не может обнаружить объявления функций? Декларации должны быть доступны при предварительной обработке, так что это должно работать, не так ли? Если нет, есть ли альтернатива или обходной путь?


person Synetech    schedule 04.06.2011    source источник
comment
В вопросе опечатка? Если у вас также нет #define foobar или -Dfoobar, я ожидаю, что это сообщение никогда не будет напечатано.   -  person William Pursell    schedule 04.06.2011
comment
Да, это должно было быть #ifndef (я забыл обновить эту строку при копировании тестового кода).   -  person Synetech    schedule 04.06.2011


Ответы (2)


Декларации должны быть доступны при предварительной обработке, так что это должно работать, не так ли?

Препроцессор работает до компиляции (отсюда и «пре»), поэтому в этот момент нет скомпилированных символов, только текст и расширение текста. Препроцессор и компилятор явно разделены и работают независимо друг от друга, за исключением того факта, что препроцессор модифицирует исходный код, который передается компилятору.

Типичный шаблон для выполнения чего-то подобного с препроцессором состоит в том, чтобы соединить объявление функции с использованием функции, используя ту же самую константу define:

#define FOO

#ifdef FOO
 void foo(int);
#endif

#ifdef FOO
   printf("foo exists");
#endif
person dkackman    schedule 04.06.2011
comment
Я знаю, что препроцессор работает до компиляции, но объявления функций уже присутствуют в тексте в этот момент (в данном случае двумя строками раньше). Я полагаю, проблема в том, что препроцессор не понимает объявления; только pre-proc директивы. Значит, нет практического/автоматического способа проверить существование функции? (Ручное создание pre-proc определения для каждой функции требует слишком много работы.) - person Synetech; 04.06.2011
comment
Ага. Препроцессор вообще не понимает ни C, ни C++, поэтому объявление функции представляет собой не более чем кусок текста. Какую конкретную проблему вы пытаетесь решить? Возможно, вам действительно нужен указатель на функцию или что-то еще. Это работает, когда во время выполнения вы хотите увидеть, экспортирует ли dll определенный метод, и использовать его, если это так. Но если вы действительно хотите сделать что-то подобное во время компиляции, это делается выше. - person dkackman; 04.06.2011

Препроцессор работает с токенами препроцессора, которые определены с помощью директив препроцессора. Препроцессор не работает с типами, объявленными в вашем коде (независимо от языка).

Вы должны использовать директиву препроцессора #define, чтобы объявить токен видимым для других проверок условий препроцессора.

#define FOO

#if FOO
// this code will compile
int x = 5;
#else
// this code won't
int x = 10;
#endif
person Jordan Parmer    schedule 04.06.2011
comment
Думаю, я немного избаловался, когда немного поработал на JavaScript, и вы могли делать такие вещи, как простая проверка существования функции/свойства. - person Synetech; 05.06.2011