尝试使用预处理器宏生成包含路径

时间:2015-09-01 23:29:06

标签: gcc include concatenation c-preprocessor stringify

所以我认为我想要做的事情在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定义的末尾取出/ out并运行它,你得到OUTPUTOFMACROHERE => "lua-5.3.1/srclua.h"没有任何错误..除了路径无效。我找不到一个地方把字符放在任何地方,以使其进入输出引用的字符串。我尝试将其添加到_path ## / ## _file中,或将其移至传递的值LUA_PATH(/lua.h)。这只是抱怨与它结合的内容(src或lua)作为无效的预处理器令牌。

我曾尝试使用预处理器的字符串进行连接,但#include "string" "string"似乎只是尝试将这两个字符串作为单独的路径包含在内。显然,无法打开文件夹,并且在搜索子文件夹时找不到确切的文件。这也是将一半变量(路径或文件)作为字符串添加到另一个扩展和字符串化值的结果。它也是简单地尝试在我的文件前面加上要扩展的路径#include LUASRC"lua.h"的结果(GCC文档说如果找不到&lt;或者#34;它会考虑宏扩展的值)< / p>

还有另一种策略让它在我错过的宏定义中喜欢/吗?很想知道。

我使用gcc版本4.8.2(Ubuntu 4.8.2-19ubuntu1)的价值

编辑:实际执行此操作的逻辑但更重要的原因不在下面标记的答案的链接中提供了不执行此操作的原因。然而,为了快速参考所有内容,这就是我的小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 个答案:

答案 0 :(得分:1)

不是“gcc认为这是一个错误”。它错误。 (“如果[连接]的结果不是有效的预处理标记,则行为未定义。”,C11§6.10.3.3/ 3)。

但这并不重要,因为你可以串通多个令牌;没有必要连接。你只需要注意空白。

有关示例,请参阅https://stackoverflow.com/a/32077478/1566221

相关问题