Конкатенация строк для включения пути

Есть ли способ объединить 2 строковых литерала, чтобы сформировать путь включения?

Кодовый заглушка:

#define INCLUDE_DIR "/include"
#include INCLUDE_DIR "/dummy.h"

Рассматривая этот вопрос, ответы указывают в другом направлении (команда компилятора). Здесь упоминается , что это, по-видимому, невозможно, но мне интересно, была ли эта тема достаточно выкопана.

(У меня есть вариант использования, в котором это актуально, пожалуйста, сосредоточьте свои ответы/комментарии только на этот вопрос.)

Ответ 1

Кажется, это невозможно. Я сообщу здесь соответствующий раздел из Eric Postpischil answer (он, похоже, больше не работает).

Компилятор выполнит замену макроса на строке #include (за C 2011 [N1570] 6.10.2 4), но семантика не полностью определена и не может использоваться для конкатенации компонентов пути файла без дополнительных помощь от реализации С. Итак, обо всем этом вы можете do - простая подстановка, которая предоставляет полный путь, например:

#define MyPath "../../path/to/my/file.h"
#include MyPath

Ссылка на документацию. В частности, этот раздел не оставляет большой надежды на переносные решения:

Метод, с помощью которого последовательность предпроцессорных токенов между a < и a > пары токенов предварительной обработки или пару символов "объединяется в один токен предварительной обработки заголовка от реализации.


Для полноты, возможно, что-то можно попробовать с помощью fooobar.com/questions/184194/.... Я исследую, когда у меня есть момент...

Ответ 2

Я не уверен, что это именно то, что вы хотите, но в любом случае.

#define DECORATE(x)             <x>
#define MAKE_PATH(root, file)   DECORATE(root file)

#define SYS_DIR(file)           MAKE_PATH(sys/, file)
#define ARPA_DIR(file)          MAKE_PATH(arpa/, file)


#include SYS_DIR(types.h)
#include SYS_DIR(socket.h)
#include ARPA_DIR(inet.h)

Обратите внимание, что сгенерированные имена файлов содержат дополнительное пространство - <sys/ types.h>, поэтому оно не может быть решением для кросс-компилятора. Но, по крайней мере, для меня он работает на хосте Linux на GCC 4.8/4.9.

P.S. Было бы неплохо, если бы кто-то мог проверить этот фрагмент с другими компиляторами, например. MSVC.

Ответ 3

Просто избегайте пространства и конкатенации (##) и используйте < > он делает все проще:

#include <QtCore/QtGlobal>

#define QT_VERSION_PREFIX QT_VERSION_MAJOR.QT_VERSION_MINOR.QT_VERSION_PATCH

#define _CONCATE(a, c) <a/QT_VERSION_PREFIX/a/private/c>
#include _CONCATE(QtWidgets, qwidgettextcontrol_p.h)