Подтвердить что ты не робот

Можно ли разделить длинную директиву #include на две строки?

Мне хотелось бы разделить директиву #include на две строки, чтобы мой код мог соответствовать 80 символам в строке, несмотря на необходимость очень длинного пути include.

Помимо расширения пути поиска компилятора, как я могу это сделать? Есть ли способ разделить мою длинную строку пути на две строки?

"# define" расширение макроса, по-видимому, происходит после #include расширения, поэтому они не работают:

#define BIGPATH "..."
#include BIGPATH ## "/foo.c"
#include "BIGPATH/foo.c"
#include BIGPATH"/foo.c"

Я также пробовал

#include "foo" ##
         "bar"

и

#include "foo" \
         "bar"

Безрезультатно. Возможно, что я хочу, невозможно? Помогите мне, stackoverflow kenobi, вы - моя единственная надежда.

ANSWER: опираясь на предложенный ниже ответ, вот что на самом деле сработало для меня:

#define STRINGIFY(x) #x
#define PATH(path) STRINGIFY(/my/very/long/path)
#include PATH(foo.h)
#undef PATH
#undef STRINGIFY
4b9b3361

Ответ 1

Мне не нравится идея этого, я просто хотел упомянуть об этой возможности. Лучше всего пойти так, как упомянул Даниэль Фишер. Это решение немного изворотливое и не будет работать при любых обстоятельствах, но это скомпилировано здесь:

#define PATH(FILE) </path/to/FILE>
#include PATH(file.h)

И просто для обозначения некоторых очевидных ограничений:

  • путь поиска из них не является "локальным"
  • ФАЙЛ не должен содержать "," (скорее неконтакт)
  • определение PATH может по-прежнему превышать 80 символов

Не стесняйтесь добавлять в этот список.

Изменить
Просто для лучшей удобочитаемости я опубликую решение из комментария Jonathans ниже в стиле моего примера:

#define STRINGIFY(x) #x 
#define PATH(FILE) STRINGIFY(/path/to/FILE) 
#include PATH(foo.h)

Эта версия смягчает "проблему локальности" версии #include <>, поскольку она сопоставляется с #include ""

Ответ 2

Это компилируется для меня (я основываю это на том, как я вспоминаю работу Boost.PP):

#define a() <vec\
tor>

#include a()

int main() {
  std::vector<int> x;
}

Просто измените <vector> на свой полный путь - я не думаю, что вы можете объединить строки так, как вам нужно, в #include.

Ответ 3

Используйте другой заголовочный файл с коротким именем для хранения файлов заголовков с длинными именами. Таким образом, все заголовки, которые превышают минимум 80 символов, не в вас хорошо отформатированный код.

//short_name.h
#include "really_really_long_include_name.h"

//code
#include "short_name.h"

Ответ 4

Все директивы предварительной обработки завершаются токеном новой строки. Директива include имеет одну из следующих форм:

# include < h-char-sequence> new-line
# include " q-char-sequence" new-line
# include pp-tokens new-line

Ваш последний пример приведет к выполнению эквивалента #include "foo" "bar", потому что, несмотря на то, что после выполнения директивы произойдет удаление экранированной новой строки, последует конкатенация строк. Это соответствует окончательной действующей форме директивы include.

Однако, что происходит с этой формой, это то, что будут заменены любые имена макросов, следующие за include. У вас нет макросов. Если результирующая директива не соответствует ни одной из двух нормальных форм, поведение undefined.

Если директива, полученная после всех замен, не соответствует одной из двух предыдущих форм, поведение undefined

В стандарте есть конкретная заметка о случае, когда имеется несколько строковых литералов:

Обратите внимание, что смежные строковые литералы не объединены в один строковый литерал (см. фазы перевода в 2.2); таким образом, расширение, которое приводит к двум строковым литералам, является недопустимой директивой.

Итак, почему этот пример не работает. Тем не менее, это означает, что мы можем полагаться на расширение макроса, чтобы создать допустимое имя файла. Например:

#define LONG_PATH(file) <foo/bar/baz/file>
#include LONG_PATH(file.h)

Или:

#define STRINGIZE(x) #x
#define LONG_PATH(file) STRINGIZE(foo/bar/baz/file)
#include LONG_PATH(file.h)

Ответ 5

Нет, вы не можете, препроцессор требует, чтобы include filename являлся единственным токеном предварительной обработки. Вам нужно либо исправить используемый путь поиска, либо использовать требование 80 символов в строке.