宏扩展和字符串化:如何使用另一个宏字符串化宏名称(不是它的值)? [英] Macro expansion and stringification: How to get the macro name (not its value) stringified using another macro?

查看:22
本文介绍了宏扩展和字符串化:如何使用另一个宏字符串化宏名称(不是它的值)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于兴趣:

#define _ACD 5, 5, 5, 30

#define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 

#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS }

仅使用 DEFAULT_NETWORK_TOKEN_KEY_CLASS 宏,如何在 const unsigned char [] 中获取 _ACD 字符串化.

Using DEFAULT_NETWORK_TOKEN_KEY_CLASS macro only, how to get _ACD stringified in a const unsigned char [].

const uint8 startMsg[] = ?? DEFAULT_NETWORK_TOKEN_KEY_CLASS ;

只会产生 _ACD.

在此处获取 _ACD 的正确宏扩展是什么.在 如何将具有数组的宏字符串化为#define a_macro {5,7,7,97}?

What will be the correct macro expansion for getting _ACD here. In context of How to stringify macro having array as #define a_macro {5,7,7,97}?

推荐答案

(关于在没有充分理由的情况下不滥用 C 预处理器的标准免责声明适用于此.)

(The standard disclaimer about not abusing the C preprocessor without a really good reason applies here.)

当然可以做你想做的事.您需要一个 STRINGIFY 宏和一些宏间接性.

It's certainly possible to do what you want to do. You need a STRINGIFY macro and a bit of macro indirection.

通常,STRINGIFY 定义为一级间接,以允许 C 预处理器在参数进行字符串化之前扩展其参数.一种实现是:

Typically, STRINGIFY is defined with one level of indirection, to allow the C preprocessor to expand its arguments before they undergo stringification. One implementation is:

/* The # operator converts symbol 'v' into a string */
#define STRINGIFY0(v) #v
#define STRINGIFY(v) STRINGIFY0(v)

但是,您会发现这还不够:

However, you'll find that this isn't enough:

#define _ACD 5, 5, 5, 30
#define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS }

#define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)
const char startMsg[] = START_MSG;

这里,STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS) 扩展为 STRINGIFY0(5,5,5,30),C 预处理器抱怨你给了 STRINGIFY0 参数太多.

Here, STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS) expands to STRINGIFY0(5,5,5,30), and the C preprocessor complains that you've given STRINGIFY0 too many arguments.

解决方案是延迟 _ACD 的扩展,使其仅在您需要时扩展为 5,5,5,30.为此,请将其定义为类似函数的宏:

The solution is to delay the expansion of _ACD so it only expands to 5,5,5,30 when you want it to. To do this, define it as a function-like macro:

#define _ACD() 5, 5, 5, 30

这样,_ACD 只会在你调用"它时展开:_ACD().DEFAULT_NETWORK_TOKEN_KEY_CLASS 现在将扩展为 _ACD,您必须通过调用"它来进一步扩展它:DEFAULT_NETWORK_TOKEN_KEY_CLASS().

This way, _ACD will only be expanded when you "call" it: _ACD(). DEFAULT_NETWORK_TOKEN_KEY_CLASS will now expand to _ACD, and you have to expand it further by "calling" it: DEFAULT_NETWORK_TOKEN_KEY_CLASS().

以下代码说明了解决方案:

The following code illustrates the solution:

#include <stdio.h>

#define STRINGIFY0(v) #v
#define STRINGIFY(v) STRINGIFY0(v)

#define _ACD() 5, 5, 5, 30
#define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS() }

#define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)

const char startMsg[] = START_MSG;

int main(int argc, char** argv)
{
  printf("%s
",startMsg);
  return 0;
}

这篇关于宏扩展和字符串化:如何使用另一个宏字符串化宏名称(不是它的值)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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