C 预处理器:串联算术

问题描述 投票:0回答:3

如何让预处理器进行串联运算?

我尝试过:

#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);

可以吗?

gcc concatenation c-preprocessor
3个回答
4
投票

如果

ch
介于 0 到 240 之间,您可以使用 boost 预处理器库
中的 
BOOST_PP_ADD 来实现:

#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(这定义了空函数,而不是声明它们以获得一些可见的汇编输出)。


3
投票

不。 这是不可能的。

C 预处理器仅执行文本替换。 预处理器唯一进行计算的地方类似于

#if 10 + 20 == 30
,但该行不执行任何替换。


0
投票

针对您的具体情况有一个解决方法:在名称中使用十六进制数字。

更改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。
© www.soinside.com 2019 - 2024. All rights reserved.