çpreprocessor产生通过串联和字符串化宏 [英] C Preprocessor generate macros by concatenation and stringification

查看:161
本文介绍了çpreprocessor产生通过串联和字符串化宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组目标的宏对此我要生成基于一个选择宏别名,就像这样:

选择宏:

 的#define I2C_MODULE 1

别名宏(概念形式):

 的#define I2C_MODULE_BASE I2C< I2C_MODULE&GT的价值; _base
#定义I2C_MODULE_NVIC INT_I2C< I2C_MODULE&GT的价值;

目标宏(从外部文件在我的掌握):

 的#define INT_I2C0 24
#定义INT_I2C1 53
...
#定义I2C0_BASE 0x40020000
#定义I2C1_BASE 0x40021000
...

我想有preprocessor产生别名宏 I2C_MODULE_BASE ,并根据 I2C_MODULE_NVIC
选择宏 I2C_MODULE ,但经过反复阅读的 Q1 P1 和许多其他引用我忘记了,我结束了硬编码它们的值。下面我展示我当前工作的定义,然后我上次失败的尝试在生成的宏:

什么工作:

 的#define I2C_MODULE 1
#定义I2C_MODULE_BASE I2C1_BASE
#定义I2C_MODULE_NVIC INT_I2C1

什么不工作:

 的#define I2C_MODULE 1
#定义STR_HELPER(X)#X
STR的#define(x)的STR_HELPER(X)/ *尝试1 * /
#定义I2C_MODULE_BASEI2CSTR(I2C_MODULE)_base
#定义I2C_MODULE_NVICINT_I2CSTR(I2C_MODULE)/ *尝试2 * /
#定义_I2C_MODULE_BASEI2CSTR(I2C_MODULE)_base
#定义_I2C_MODULE_NVICINT_I2CSTR(I2C_MODULE)
#定义I2C_MODULE_BASE _I2C_MODULE_BASE
#定义I2C_MODULE_NVIC _I2C_MODULE_NVIC

编辑:我扩大经接受的答案去我想要的地方,如下:

 的#define PASTE2(A,B)一## b
#定义PASTE3(A,B,C)一## b ##Ç#定义_I2C_MODULE_BASE(X)PASTE3(I2C,X,_base)
#定义_I2C_MODULE_NVIC(X)PASTE2(INT_I2C,X)#定义I2C_MODULE_BASE _I2C_MODULE_BASE(I2C_MODULE)
#定义I2C_MODULE_NVIC _I2C_MODULE_NVIC(I2C_MODULE)


解决方案

这似乎工作:

 的#define I2C_MODULE 1//别名宏(概念形式):
//#定义I2C_MODULE_BASE I2C< I2C_MODULE&GT的价值; _base
//#定义I2C_MODULE_NVIC INT_I2C< I2C_MODULE&GT的价值;//目标宏(从外部文件在我的掌握):#定义INT_I2C0 24
#定义INT_I2C1 53#定义I2C0_BASE 0x40020000
#定义I2C1_BASE 0x40021000#定义PASTE2(A,B)一## b
#定义PASTE3(A,B,C)一## b ##Ç#定义I2C_MODULE_BASE(X)PASTE3(I2C,X,_base)
#定义I2C_MODULE_NVIC(X)PASTE2(INT_I2C,X)EXTERN INT i2c_module_base = I2C_MODULE_BASE(I2C_MODULE);
EXTERN INT i2c_module_nvic = I2C_MODULE_NVIC(I2C_MODULE);的extern INT i2c_module_base_0 = I2C_MODULE_BASE(0);
的extern INT i2c_module_nvic_0 = I2C_MODULE_NVIC(0);的extern INT i2c_module_base_1 = I2C_MODULE_BASE(1);
的extern INT i2c_module_nvic_1 = I2C_MODULE_NVIC(1);

样输出(从 CPP

 #1xx.c
#1<内置>中
#1<命令行>中
#1xx.c
#21xx.c
EXTERN INT i2c_module_base = 0x40021000;
EXTERN INT i2c_module_nvic = 53;EXTERN INT i2c_module_base_0 = 0x40020000;
EXTERN INT i2c_module_nvic_0 = 24;EXTERN INT i2c_module_base_1 = 0x40021000;
EXTERN INT i2c_module_nvic_1 = 53;

据紧密依托我的回答çpreprocessor和令牌级联

有无疑是其他方式的 I2C_MODULE_BASE I2C_MODULE_NVIC 宏可以写,但关键点是:


  1. 使用 ## 标记粘贴运算符(不是字符串化操作符)。

  2. 使用宏两个级别(例如, I2C_MODULE_BASE PASTE3 )。

I have a set of target macros for which I want to generate aliases based on a choosing macro, like so:

Choosing macro:

#define I2C_MODULE 1

Alias macros (conceptual form):

#define I2C_MODULE_BASE I2C<Value of I2C_MODULE>_BASE
#define I2C_MODULE_NVIC INT_I2C<Value of I2C_MODULE>

Target macros (from an external file out of my control):

#define INT_I2C0   24 
#define INT_I2C1   53
...
#define I2C0_BASE  0x40020000
#define I2C1_BASE  0x40021000
...   

I wanted to have the preprocessor generate the alias macros I2C_MODULE_BASE and I2C_MODULE_NVIC based on the choosing macro I2C_MODULE, but after much reading Q1, P1 and many other references I lost track of, I ended up hard-coding their values. Below I show my current working definitions, and then my last failed attempts at generating the macros:

What works:

#define I2C_MODULE 1
#define I2C_MODULE_BASE I2C1_BASE
#define I2C_MODULE_NVIC INT_I2C1

what did not work:

#define I2C_MODULE 1
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

/* Attempt 1 */
#define I2C_MODULE_BASE "I2C" STR(I2C_MODULE) "_BASE"
#define I2C_MODULE_NVIC "INT_I2C" STR(I2C_MODULE)

/* Attempt 2 */
#define _I2C_MODULE_BASE "I2C" STR(I2C_MODULE) "_BASE"
#define _I2C_MODULE_NVIC "INT_I2C" STR(I2C_MODULE)
#define I2C_MODULE_BASE _I2C_MODULE_BASE
#define I2C_MODULE_NVIC _I2C_MODULE_NVIC

EDIT: I expanded upon the accepted answer to get to where I wanted, as follows:

#define PASTE2(a, b) a ## b
#define PASTE3(a, b, c) a ## b ## c

#define _I2C_MODULE_BASE(x) PASTE3(I2C, x, _BASE)
#define _I2C_MODULE_NVIC(x) PASTE2(INT_I2C, x)

#define I2C_MODULE_BASE _I2C_MODULE_BASE(I2C_MODULE)
#define I2C_MODULE_NVIC _I2C_MODULE_NVIC(I2C_MODULE)

解决方案

This seems to work:

#define I2C_MODULE 1

//Alias macros (conceptual form):
//#define I2C_MODULE_BASE I2C<Value of I2C_MODULE>_BASE
//#define I2C_MODULE_NVIC INT_I2C<Value of I2C_MODULE>

//Target macros (from an external file out of my control):

#define INT_I2C0   24 
#define INT_I2C1   53

#define I2C0_BASE  0x40020000
#define I2C1_BASE  0x40021000

#define PASTE2(a, b) a ## b
#define PASTE3(a, b, c) a ## b ## c

#define I2C_MODULE_BASE(x) PASTE3(I2C, x, _BASE)
#define I2C_MODULE_NVIC(x) PASTE2(INT_I2C, x)

extern int i2c_module_base = I2C_MODULE_BASE(I2C_MODULE);
extern int i2c_module_nvic = I2C_MODULE_NVIC(I2C_MODULE);

extern int i2c_module_base_0 = I2C_MODULE_BASE(0);
extern int i2c_module_nvic_0 = I2C_MODULE_NVIC(0);

extern int i2c_module_base_1 = I2C_MODULE_BASE(1);
extern int i2c_module_nvic_1 = I2C_MODULE_NVIC(1);

Sample output (from cpp):

# 1 "xx.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "xx.c"
# 21 "xx.c"
extern int i2c_module_base = 0x40021000;
extern int i2c_module_nvic = 53;

extern int i2c_module_base_0 = 0x40020000;
extern int i2c_module_nvic_0 = 24;

extern int i2c_module_base_1 = 0x40021000;
extern int i2c_module_nvic_1 = 53;

It is closely based on my answer to C preprocessor and token concatenation.

There are undoubtedly other ways that the I2C_MODULE_BASE and I2C_MODULE_NVIC macros could be written, but the key points are:

  1. Using the ## token pasting operator (not the # stringifying operator).
  2. Using two levels of macro (for example, I2C_MODULE_BASE and PASTE3).

这篇关于çpreprocessor产生通过串联和字符串化宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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