Использование #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) и представляет для него красивую оболочку.