尝试使用预处理器宏生成包含路径
Attempt to use preprocessor macros to generate include paths
所以我认为我正在尝试做的事情在 GCC 中是不可能的,因为宏扩展必须产生预处理器令牌。这在 MSVC++ 中工作正常,但我找不到可比较的
所以我认为这在 GCC 中是不可能的(在 VC++ 中工作正常),因为宏扩展必须是预处理器标记并且被认为是标记之间的分隔符。
我正在尝试 link 特定版本的库,在这个例子中是 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)
}
运行ning 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)
编辑:实际执行此操作的逻辑,但更重要的是不执行此操作的原因在下面标记的答案的 link 中提供。然而,为了快速参考所有事情,这就是我的小 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)
}
不是"gcc thinks it is an error"。 是一个错误。 ("If the result [of the concatenation] is not a valid preprocessing token, the behavior is undefined.",C11 §6.10.3.3/3)。
但这并不重要,因为您可以对多个标记进行字符串化;没有必要串联。你只需要注意空格。
有关示例,请参阅 。
所以我认为我正在尝试做的事情在 GCC 中是不可能的,因为宏扩展必须产生预处理器令牌。这在 MSVC++ 中工作正常,但我找不到可比较的
所以我认为这在 GCC 中是不可能的(在 VC++ 中工作正常),因为宏扩展必须是预处理器标记并且被认为是标记之间的分隔符。
我正在尝试 link 特定版本的库,在这个例子中是 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)
}
运行ning 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)
编辑:实际执行此操作的逻辑,但更重要的是不执行此操作的原因在下面标记的答案的 link 中提供。然而,为了快速参考所有事情,这就是我的小 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)
}
不是"gcc thinks it is an error"。 是一个错误。 ("If the result [of the concatenation] is not a valid preprocessing token, the behavior is undefined.",C11 §6.10.3.3/3)。
但这并不重要,因为您可以对多个标记进行字符串化;没有必要串联。你只需要注意空格。
有关示例,请参阅