使用编译器定义宏级联 [英] Macro concatenation using compiler define

查看:78
本文介绍了使用编译器定义宏级联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这应该是简单的,但我在努力弄明白。我有 PROJECT_NAME 作为一个编译器( G ++ -D 定义,我想与其他一些文字来连接它形成一个命名空间名称。我目前的做法是这样的:

This should be simple, but I'm struggling to figure it out. I have PROJECT_NAME as a compiler (g++) -D define, and I want to concatenate it with some other text to form a namespace name. My current approach is this:

#define VERSION_NAMESPACE PROJECT_NAME ## Versioning

对于我目前的项目,我希望 VERSION_NAMESPACE Syren_DLLVersioning 。相反,我得到一个编译错误:

For my current project, I expect VERSION_NAMESPACE to be Syren_DLLVersioning. Instead I get a compiler error:

error: 'PROJECT_NAMEVersioning' has not been declared

但根据 G ++ 调用 PROJECT_NAME 正在正确定义:

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

为什么 PROJECT_NAME 不被拼接发生之前更换?

Why is PROJECT_NAME not being replaced before the concatenation takes place?

推荐答案

当它出现旁边的 ## 运营商,所以你需要更多的宏名不扩大间接层:

A macro name is not expanded when it appears next to the ## operator, so you need more layers of indirection:

#define P_VERSION2(foo)   foo ## Versioning
#define P_VERSION(foo)    P_VERSION2(foo)
#define VERSION_NAMESPACE P_VERSION(PROJECT_NAME)

PROJECT_NAME 被扩展为 P_VERSION 的参数,然后再连接到在 P_VERSION2

so that PROJECT_NAME is expanded as the argument of P_VERSION and then concatenated in P_VERSION2.

在第16.3.3节[cpp.concat]第3款,它被指定

In section 16.3.3 [cpp.concat], paragraph 3, it is specified

对于这两种对象类和函数宏调用,之前重新审视更多的宏名来替换替换列表,的每个实例 ## preprocessing令牌替换列表中(而不是从一个参数)将被删除,preceding preprocessing令牌的值与以下preprocessing令牌。

For both object-like and function-like macro invocations, before the replacement list is reexamined for more macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token.

这相邻的 ## preprocessing令牌被连接的的宏观置换的置换完成preprocessing令牌名单。因此, PROJECT_NAME 必须通过其他(功能类似)宏通过了将其替换,以版本连接在一起。

that preprocessing tokens adjacent to a ## preprocessing token are concatenated before macro-replacement is done on the replacement list. Therefore, PROJECT_NAME must be passed through another (function-like) macro for it to be replaced and concatenated with Versioning.

但在16.3.1 [cpp.subst]第1款,该标准规定(重点由我加的)

But in 16.3.1 [cpp.subst], paragraph 1, the standard specifies (emphasis added by me)

一个函数宏的调用的参数已经确定后,参数替换发生。在替换列表中的参数,除非$ P $由pceded一个 ## preprocessing令牌或后跟一个 ## preprocessing令牌(见下图),由相应的参数后更换其中所含的所有宏已经扩大。之前被取代,每个参数的preprocessing令牌是完全宏,如果他们形成了preprocessing文件的其余部分更换;没有其他的preprocessing令牌是可用的。

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

这是宏观参数不受到进一步的宏扩展,如果相邻的 ## preprocessing令牌。因此,接收函数宏 PROJECT_NAME 作为参数,不得直接串联它的参数与版本,但扩大 PROJECT_NAME 它必须调用另一个函数宏终于做串联。

that macro parameters are not subject to further macro-expansion if adjacent to a ## preprocessing token. Therefore, the function-like macro that receives PROJECT_NAME as argument must not directly concatenate its argument with Versioning, but to expand PROJECT_NAME it must call another function-like macro that finally does the concatenation.

所以在上面,与调用的ccache g ++的... -DPROJECT_NAME = Syren_DLL ... PROJECT_NAME 被替换为 Syren_DLL P_VERSION(PROJECT_NAME)被扩展,从而 P_VERSION2(Syren_DLL )然后导致的串联 Syren_DLL 版本

So in the above, with the invocation ccache g++ ... -DPROJECT_NAME=Syren_DLL ..., PROJECT_NAME is replaced with Syren_DLL when P_VERSION(PROJECT_NAME) is expanded, resulting in P_VERSION2(Syren_DLL) which then leads to the concatenation of Syren_DLL and Versioning.

这篇关于使用编译器定义宏级联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆