首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在宏中展开宏

在宏中展开宏
EN

Stack Overflow用户
提问于 2014-07-28 08:30:10
回答 2查看 2.6K关注 0票数 3

给定以函数调用方式访问编译器属性的下列宏,如spec(section(".mysection")) void foo(void);

代码语言:javascript
复制
#define spec(_H_) spec_##_H_
#define spec_section(_S_) attribute ((section (_S_)))

现在我想在其他宏中使用这些定义,比如spec(namespace(unmanaged)) int x;

代码语言:javascript
复制
#define spec_namespace(_H_) spec_namespace_##_H_
#define spec_namespace_unmanaged spec(section(".unmanaged"))

但是这根本没有扩展,唯一的方法是自己写扩展的spec()宏:

代码语言:javascript
复制
#define spec_namespace_unmanaged spec_section(".unmanaged")

知道这是怎么回事吗?gcc -E on spec(namespace(unmanaged))的结果是spec(namespace(unmanaged))

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-28 11:13:54

引用C99草案6.10.3.4恢复和进一步替换第2节(强调地雷):

如果在此替换列表扫描过程中找到要替换的宏的名称(不包括源文件的其他预处理令牌),则不会替换它。此外,如果任何嵌套替换遇到要替换的宏的名称,则不会替换。这些未被替换的宏名称预处理令牌不再可供进一步替换,即使它们稍后(重新)在否则会被替换的宏名称预处理令牌的上下文中进行检查。

从折叠宏定义:

代码语言:javascript
复制
#define spec(_H_) spec_##_H_
#define spec_namespace(_H_) spec_namespace_##_H_
#define spec_namespace_unmanaged spec(section(".unmanaged"))

显然,对spec宏进行了两次评估,因此没有进一步的替换,让我们一步一步地进行:

代码语言:javascript
复制
spec(namespace(unmanaged)) int x; → spec_namespace(unmanaged) int x;
spec_namespace(unmanaged) int x;  → spec_namespace_unmanaged int x;
spec_namespace_unmanaged int x;   → spec(section(".unmanaged")) int x;

您可以做的是将您的上一个宏定义修改为以下形式:

代码语言:javascript
复制
#define spec_namespace_unmanaged attribute ((namespace (".unmanaged")))

或者把它简化为:

代码语言:javascript
复制
#define spec(_H_) spec_##_H_
#define spec_section(_S_) attribute ((section (_S_)))
#define spec_namespace(_N_) attribute ((namespace (_N_)))

通过以下方式:

代码语言:javascript
复制
spec(namespace(".unmanaged")) int x;
票数 3
EN

Stack Overflow用户

发布于 2022-01-20 09:40:34

简单地说,如果没有在右侧(宏定义中)应用字符串化运算符#或级联运算符##,预处理程序只会在左侧展开嵌套宏(在另一个宏的参数中)。

强制嵌套宏展开的idiomatic way是使用助手宏:

代码语言:javascript
复制
#define macro_helper(x) macro(x) // gets x expanded

考虑下面的示例,它扩展了嵌套的__LINE__宏:

代码语言:javascript
复制
#include <iostream>

#define MACRO1(L)   "Line " #L         // MACRO1(__LINE__) -> "Line " "__LINE__")
#define MACRO2       MACRO1(__LINE__)  // MACRO2 -> MACRO1(__LINE__)

#define MACRO3(L)   "Line " #L         // MACRO3(13) -> "Line " "13")
#define MACRO4(L)   MACRO3(L)          // MACRO4(__LINE__) -> MACRO3(13)
#define MACRO5      MACRO4(__LINE__)   // MACRO5 -> MACRO4(__LINE__)

int main()
{
    std::cout << MACRO2 << std::endl;  // Output: "Line __LINE__"
    std::cout << MACRO5 << std::endl;  // Output: "Line 13"
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24991208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档