c预处理器:串联算术
c preprocessor: arithmetic in concatenation
如何让预处理器在串联中进行算术运算?
我试过:
#define DECL_FUNCT3(ch1, ch2) \
void funct_ ## ch1 ## _and_ ## ch2 ## _(void);
#define DECL_FUNCT2(ch1, ch2) DECL_FUNCT3(ch1, ch2)
#define DECL_FUNCT1(ch1, ch2) DECL_FUNCT2(ch1, ch2)
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, ch+16)
DECL_FUNCT(0)
DECL_FUNCT(1)
我想得到:
void funct_0_and_16_(void);
void funct_1_and_17_(void);
但我得到:
$ gcc -E test.c
[...]
void funct_0_and_0+16_(void);
void funct_1_and_1+16_(void);
可以吗?
没有。不可能。
C 预处理器只执行文本替换。预处理器计算的唯一地方是 #if 10 + 20 == 30
,但该行不执行任何替换。
针对您的具体情况有一个解决方法:在名称中使用十六进制数字。
更改 2 个宏:
#define DECL_FUNCT3(ch1, ch2) \
void funct_0 ## ch1 ## h_and_1 ## ch2 ## h_(void);
...
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, ch)
你得到:
void funct_00h_and_10h_(void);
void funct_01h_and_11h_(void);
有一些限制:
- 两个数的差必须是 16。
- 它仅适用于数字 00h..0fh 和 10h..1fh。
如果 ch
介于 0 和 240 之间,您可以使用 BOOST_PP_ADD
from the boost preprocessor library:
#include <boost/preprocessor/arithmetic/add.hpp>
#define DECL_FUNCT3(ch1, ch2) \
void funct_ ## ch1 ## _and_ ## ch2 ## _(void);
#define DECL_FUNCT2(ch1, ch2) DECL_FUNCT3(ch1, ch2)
#define DECL_FUNCT1(ch1, ch2) DECL_FUNCT2(ch1, ch2)
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, BOOST_PP_ADD(ch,16))
DECL_FUNCT(0)
DECL_FUNCT(240)
Godbolt 演示(使用 C++,但也适用于 C):
https://godbolt.org/z/2edrua(这定义了空函数,而不是声明它们以获得一些可见的程序集输出)。
如何让预处理器在串联中进行算术运算?
我试过:
#define DECL_FUNCT3(ch1, ch2) \
void funct_ ## ch1 ## _and_ ## ch2 ## _(void);
#define DECL_FUNCT2(ch1, ch2) DECL_FUNCT3(ch1, ch2)
#define DECL_FUNCT1(ch1, ch2) DECL_FUNCT2(ch1, ch2)
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, ch+16)
DECL_FUNCT(0)
DECL_FUNCT(1)
我想得到:
void funct_0_and_16_(void);
void funct_1_and_17_(void);
但我得到:
$ gcc -E test.c
[...]
void funct_0_and_0+16_(void);
void funct_1_and_1+16_(void);
可以吗?
没有。不可能。
C 预处理器只执行文本替换。预处理器计算的唯一地方是 #if 10 + 20 == 30
,但该行不执行任何替换。
针对您的具体情况有一个解决方法:在名称中使用十六进制数字。
更改 2 个宏:
#define DECL_FUNCT3(ch1, ch2) \
void funct_0 ## ch1 ## h_and_1 ## ch2 ## h_(void);
...
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, ch)
你得到:
void funct_00h_and_10h_(void);
void funct_01h_and_11h_(void);
有一些限制:
- 两个数的差必须是 16。
- 它仅适用于数字 00h..0fh 和 10h..1fh。
如果 ch
介于 0 和 240 之间,您可以使用 BOOST_PP_ADD
from the boost preprocessor library:
#include <boost/preprocessor/arithmetic/add.hpp>
#define DECL_FUNCT3(ch1, ch2) \
void funct_ ## ch1 ## _and_ ## ch2 ## _(void);
#define DECL_FUNCT2(ch1, ch2) DECL_FUNCT3(ch1, ch2)
#define DECL_FUNCT1(ch1, ch2) DECL_FUNCT2(ch1, ch2)
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, BOOST_PP_ADD(ch,16))
DECL_FUNCT(0)
DECL_FUNCT(240)
Godbolt 演示(使用 C++,但也适用于 C):
https://godbolt.org/z/2edrua(这定义了空函数,而不是声明它们以获得一些可见的程序集输出)。