Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用编译器定义的宏连接_C++_C_C Preprocessor - Fatal编程技术网

C++ 使用编译器定义的宏连接

C++ 使用编译器定义的宏连接,c++,c,c-preprocessor,C++,C,C Preprocessor,这应该很简单,但我正在努力想办法。我有PROJECT\u NAME作为编译器(g++)-D定义,我想将它与其他一些文本连接起来,形成一个名称空间名称。我目前的做法是: #define VERSION_NAMESPACE PROJECT_NAME ## Versioning 对于我当前的项目,我希望VERSION\u NAMESPACE是Syren\u DLLVersioning。相反,我得到了一个编译器错误: error: 'PROJECT_NAMEVersioning' has not be

这应该很简单,但我正在努力想办法。我有
PROJECT\u NAME
作为编译器(
g++
-D
定义,我想将它与其他一些文本连接起来,形成一个名称空间名称。我目前的做法是:

#define VERSION_NAMESPACE PROJECT_NAME ## Versioning
对于我当前的项目,我希望
VERSION\u NAMESPACE
Syren\u DLLVersioning
。相反,我得到了一个编译器错误:

error: 'PROJECT_NAMEVersioning' has not been declared
但是根据
g++
调用,
PROJECT\u NAME
的定义是正确的:

ccache g++ ... -DPROJECT_NAME=Syren_DLL ...

为什么在连接发生之前,
PROJECT\u NAME
没有被替换?

宏名称出现在
#
操作符旁边时不会展开,因此需要更多的间接层:

#define P_VERSION2(foo)   foo ## Versioning
#define P_VERSION(foo)    P_VERSION2(foo)
#define VERSION_NAMESPACE P_VERSION(PROJECT_NAME)
因此,
PROJECT\u NAME
被展开为
p\u VERSION
的参数,然后连接到
p\u VERSION2

在第16.3.3节[cpp.concat]第3段中,对其进行了规定

对于类对象宏调用和类函数宏调用,在重新检查替换列表以查找更多要替换的宏名称之前,将删除替换列表中的
##
预处理标记的每个实例(而不是从参数中),并将前面的预处理标记与下面的预处理标记连接起来

在替换列表上执行宏替换之前,将连接与
##
预处理标记相邻的预处理标记。因此,
PROJECT\u NAME
必须通过另一个(类似函数的)宏来替换,并与
版本控制
连接

但在16.3.1[cpp.subst]第1段中,本标准规定了(由我补充强调)

在确定调用函数(如宏)的参数后,将进行参数替换。替换列表中的参数,除非前面有一个
#
#
预处理标记,或者后面有一个
#
预处理标记(请参见下文),否则在展开其中包含的所有宏后,将被相应的参数替换。在被替换之前,每个参数的预处理标记被完全宏替换,就好像它们构成了预处理文件的其余部分一样;没有其他预处理令牌可用

如果宏参数与
##
预处理令牌相邻,则不会进行进一步的宏扩展。因此,接收
PROJECT\u NAME
作为参数的函数类宏不能直接将其参数与
Versioning
连接起来,但要展开
PROJECT\u NAME
,它必须调用另一个函数类宏,最终进行连接


因此在上面,通过调用
ccache g++-DPROJECT\u NAME=Syren\u DLL…
PROJECT\u NAME
P\u VERSION(PROJECT\u NAME)
扩展时被替换为
Syren\u DLL
,从而导致
P\u VERSION2(Syren\u DLL)
连接
Syren\u DLL
VERSION
,我甚至不确定这是否严格合法(这可能是特定于编译器的行为)…你能在这方面找到标准吗?哎呀,我没有充分使用预处理器。原始版本缺少一层间接寻址。感谢你让我查找它。幸运的是,我放弃了并问了,我肯定不会猜到这一点。谢谢!