Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

Как собрать include из define

#c++ #c #препроцессор


Как из 

#define filename myfilename
#define path ../driver/


перейти к

#include INCLUDE_DRIVER;


которое после препроцессинга перейдет в

#include "../driver/myfilename.h"


Я потратил уже немало времени, на различные комбинации ##, но так и не пришел к тому
что нужно. Я бы продолжил эксперементы, если бы был хорошо виден результат. 
    


Ответы

Ответ 1



#define path ../driver/ А кавычки кто ставить будет? http://codepad.org/vi8lh5nI Там два дефайна определяют путь в условии. Разобрался. Вот работающая последовательность шагов: http://codepad.org/rGostnci http://codepad.org/wCx3Of1Y http://codepad.org/VpQ3O1AJ Итоговый вариант кода: #define STD std #define IOH io.h #define STR(x) #x #define JOIN(x,y) STR(x##y) #define INC(x,y) JOIN(x,y) #include INC(STD,IOH) int main(void) { return !printf("YES"); } Почему так? Объединение "таких" "строк" делается потом. Include не должен содержать такого. Поэтому разворачивание аргумента в строку (единственного аргумента) должно быть сделано на последнем шаге. Это делает STR. Для передачи аргументов в STR их надо объединить - это делает JOIN. Поскольку include передаёт то, что само по себе define, если сразу вызвать JOIN, то объединятся имена дефайнов, а не значения. Добавляем ещё один уровень, чтобы они развернулись - это INC. Собственно всё, оно работает. А теперь меняем std и io.h на данные ТС, запускаем в gcc и получаем кучу ругани Проверил: http://codepad.org/WY0TkYMS Line 0: error: pasting "/" and "myfilename" does not give a valid preprocessing token Line 27: error: ../driver/myfilename: No such file or directory Возможно, с этим можно сделать что-то при помощи ключей компиляции. Потому что есть какая-то мутная ошибка про слеш, но дальше в 27й строке делается попытка подключить файл с правильно сформированным именем (естественно, на codepad'e его нет). К сожалению, я не знаток ключей компиляции gcc. Возможно, кто-то сможет подсказать, как исправить эту проблему. Как насчёт использования фиктивного каталога, из которого потом поднимемся вверх?http://codepad.org/OCpT6U2BСпасибо avp за идею. #define filename _/../myfilename #define path ../driver/_ #define STR(x) #x #define JOIN(x,y) STR(x##y) #define INC(x,y) JOIN(x,y) #include INC(path,filename) int main(void) { return !printf("YES"); }

Ответ 2



Похоже, в gcc это не решается (по крайней мере корректно). Мне удалось "сделать" только подавив всю диагностику через > gcc -E c1.c /tmp/t.c 2>/dev/null; gcc /tmp/t.c. / Вообще в документации по поводу конкатенации пишут: However, two tokens that don't together form a valid token cannot be pasted together. For example, you cannot concatenate x with + in either order. If you try, the preprocessor issues a warning and emits the two tokens. Whether it puts white space between the tokens is undefined. – avp 25 май в 13:26

Комментариев нет:

Отправить комментарий