Использование #define для включения другого файла в С++/C
Я хочу определить макрос, который включает в себя другой заголовочный файл:
#define MY_MACRO (text) #include "__FILE__##_inline.inl"
Итак, когда препроцессор анализирует файл person.h, MY_MACRO (blahblah) расширяется до
#include "person.h.inline.inl"
какие-либо подсказки о том, как это сделать?
Ответы
Ответ 1
Невозможно использовать #define
для создания других предпроцессорных директив, если вы дважды не выполняете препроцессор.
Но в вашем случае даже запуск препроцессора дважды не поможет, потому что #include
должна быть одной строкой формы "..."
или <...>
.
Ответ 2
Вы не можете использовать __FILE__
, потому что это уже указано, а #include
не поддерживает конкатенацию строк. Но вы можете использовать макросы после #include
:
#define STRINGIZE_AUX(a) #a
#define STRINGIZE(a) STRINGIZE_AUX(a)
#define CAT_AUX(a, b) a##b
#define CAT(a, b) CAT_AUX(a, b)
#define MY_MACRO(file, name) STRINGIZE(CAT(file, CAT(name, _inline.inl)))
#include MY_MACRO(aaaa, qqq)
Для предотвращения глобального загрязнения пространства имен вы должны использовать эквивалентные макросы Boost.Preprocessor вместо CAT
и STRINGIZE
.
Ответ 3
Вы не можете писать другие предпроцессорные директивы с использованием препроцессора. Однако я считаю, что вы можете определить только имя файла:
#define MY_MACRO(name) "__FILE__##name_inline.inl"
#include MY_MACRO(name)
Препроцессор работает несколько раз, пока не будет никаких дополнительных подстановок, которые он может сделать, поэтому он должен сначала развернуть имя, а затем # включить ссылочный файл.
EDIT: я просто попробовал, и препроцессор не может обрабатывать такие кавычки.
#define MY_MACRO(x) <__FILE__##x_inline.inl>
#include MY_MACRO(foo)
работает нормально, но < > может быть не так, как вы хотели.
EDIT2: Как указано в комментариях, __FILE__
не распространяется правильно, что делает это, вероятно, не тем, что вы хотите в конце концов. К сожалению.
Ответ 4
#if 0 /*Windows*/
#define MKDIR_ENABLER <direct.h>
#define MY_MKDIR(x,y) _mkdir((x))
#else /*Linux*/
#define MKDIR_ENABLER <sys/stat.h>
#define MY_MKDIR(x,y) mkdir((x),(y))
#endif
#include MKDIR_ENABLER
int main(void)
{
MY_MKDIR("more_bla",0644);
return 0;
}
Этот код включает соответствующий заголовочный файл для mkdir (поскольку он отличается от UNIX и Windows) и представляет для него красивую оболочку.