2015-09-01 1 views
1

Так что я думаю, что то, что я пытаюсь сделать, просто невозможно в GCC из-за расширения макросов, которое должно привести к токену препроцессора. Это хорошо работает в MSVC++ для того, что стоит, но я не могу найти сопоставимыеПопытка использовать макросы препроцессора для генерации включенных путей

Так что я думаю, что это невозможно в GCC (отлично работает в VC++) из-за расширения макросов, которые должны быть токенами препроцессора и что считается разделителем между токенами.

Я пытаюсь связать в конкретной версии библиотеки, в этом примере это Lua 5.3.1. У меня есть файлы, извлеченные в исходную папку, чтобы их можно было найти в подпапке «lua-5.3.1 \ src», и я хотел бы написать макрос, который я могу использовать для префикса файлов заголовков с этим путем. Что-то простое, как LUA_PATH(_file), которое расширилось бы до "lua-5.3.1/src/_file". Обычно я просто использовал флаги компилятора, чтобы предоставить другую подпапку для поиска, но из-за того, как работают проекты, над которыми я работаю, это именно то, что я не могу сделать, и что я пытаюсь найти другим способом чтобы поддерживать включенные дорожки повсюду.

Вот маленький файл я написал (что не компилировать, но я могу запустить его через CPP, чтобы увидеть, что это дает мне)

#define LUASRC lua-5.3.1/src/ 
#define STRINGIFY(_s) #_s 
#define ADDLUAPATH(_path, _file) STRINGIFY(_path ## _file) 
#define EVALUATOR(_path, _file) ADDLUAPATH(_path,_file) 
#define LUA_PATH(_file) EVALUATOR(LUASRC,_file) 

void main (void) 
{ 
     OUTPUTOFMACROHERE => LUA_PATH(lua.h) 
} 

Это дает мне следующий вывод из работы CPP на файл

$ cpp temp.c 
# 1 "temp.c" 
# 1 "<command-line>" 
# 1 "/usr/include/stdc-predef.h" 1 3 4 
# 1 "<command-line>" 2 
# 1 "temp.c" 
void main (void) 
{ 
temp.c:1:29: error: pasting "/" and "lua" does not give a valid preprocessing token 
#define LUASRC lua-5.3.1/src/ 
          ^
temp.c:3:44: note: in definition of macro 'ADDLUAPATH' 
#define ADDLUAPATH(_path, _file) STRINGIFY(_path ## _file) 
              ^
temp.c:5:25: note: in expansion of macro 'EVALUATOR' 
#define LUA_PATH(_file) EVALUATOR(LUASRC,_file) 
         ^
temp.c:5:35: note: in expansion of macro 'LUASRC' 
#define LUA_PATH(_file) EVALUATOR(LUASRC,_file) 
           ^
temp.c:9:23: note: in expansion of macro 'LUA_PATH' 
    OUTPUTOFMACROHERE => LUA_PATH(lua.h) 
        ^
OUTPUTOFMACROHERE => "lua-5.3.1/src/lua.h" 
} 

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

Проблема - символ/в конце пути. Если вы берете/в конце определения LUASRC и запускаете его, вы получаете OUTPUTOFMACROHERE => "lua-5.3.1/srclua.h" без каких-либо ошибок .. за исключением того, что путь недействителен. Я не могу найти место, чтобы помещать персонажа в любом месте, чтобы вставить его в строку с указанными выводами. Я попытался добавить его самостоятельно, как _path ##/## _file, или переместив его на значение, прошедшее как LUA_PATH(/lua.h). Это просто жалуется на то, что с ним сочетается (src или lua) как недействительный токен препроцессора.

Я попытался использовать строки для препроцессора для конкатенации, но #include "string" "string" просто пытается включить обе эти строки в виде отдельных путей. Очевидно, что папка не может быть открыта, и точный файл не может быть найден без поиска вложенных папок. Это также было результатом того, что половина переменных (путь или файл) будет строкой, которая будет добавлена ​​к другому расширенному и строковому значению. Это также является результатом простого префикса моих файлов с расширением пути #include LUASRC"lua.h" (документация GCC говорит, что если он не находит < или «он считает значение для расширения макросов»)

Есть ли еще одна стратегия для получить его любить/в макроопределения, что мне не хватает любви знать

за то, что его ценность я использую GCC версии 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

EDIT?.: Логика, чтобы на самом деле это сделать, но более важно, причины, по которым это не делается, указаны в ссылке ответа, отмеченного ниже. Для быстрой справки всех вещей, однако, это то, что мой маленький temp.c Файл был похож на

#define LUASRC lua-5.3.1/src/ 
#define EXPAND(_a)    _a 
#define STRINGIFY(_s)   #_s 
#define EVALUATOR(_args)  STRINGIFY(_args) 
#define LUA_PATH(_file)   EVALUATOR(EXPAND(LUASRC)EXPAND(_file)) 

void main (void) 
{ 
     OUTPUTOFMACROHERE => LUA_PATH(lua.h) 
} 

ответ

1

Это не значит, что «gcc считает, что это ошибка». Номер есть ошибка.(«Если результат [конкатенации] не является допустимым токеном предварительной обработки, поведение не определено»., C11 § 6.10.3.3/3).

Но это не имеет значения, потому что вы можете выровнять более одного токена; нет необходимости конкатенации. Вам просто нужно следить за пробелами.

См. Например, https://stackoverflow.com/a/32077478/1566221.

+0

Спасибо за ответ, и я заглянул в другой пример. На самом деле это не одна из многих вкладок SO, которые я открывал, хотя и помогал в этом. И я понимаю, что компилятор следит за письмом за характеристики того, что он должен делать, и по собственной нотации документации, очищающей то, что он использовал, чтобы это сделать. Мне просто кажется странным, что то, что может быть определено как действительный токен в этом случае, если остальная часть расширения макроса продолжается, вместо этого останавливается и остается недействительной и, следовательно, неопределенной. – James