在摆弄了一些预处理器之后,结果证明它比我想象的要容易。目标是只为源数组输入一次数据,同时避免单独定义每个条目。这可以通过将数组的内容定义为预处理器宏来实现:
#define FOO 1.0, 2.0, 3.0
static const double foo[] = { FOO };
static const double bar[] = { ARR_EL(0,FOO)*ARR_EL(0,FOO), \
3.0*ARR_EL(1,FOO), ARR_EL(2,FOO)+4.0 };
/* Whatever else */
其中辅助宏如下:
/* ARR_EL(n,...) returns nth element of the array */
#define ARR_EL(n,...) ARR_EL0(ARR_BEGIN(n,__VA_ARGS__))
#define ARR_EL0(...) ARR_ELX(__VA_ARGS__)
#define ARR_ELX(e0,...) (e0)
/* ARR_BEGIN(n,...) returns subarray starting with nth element */
#define ARR_BEGIN(n,...) ARR_BEGIN##n(__VA_ARGS__)
#define ARR_BEGIN0(...) __VA_ARGS__ /* Why is this even here? */
#define ARR_BEGIN1(...) ARR_BEGINX(__VA_ARGS__)
#define ARR_BEGINX(e0,...) __VA_ARGS__
#define ARR_BEGIN2(...) ARR_BEGIN1(ARR_BEGIN1(__VA_ARGS__))
#define ARR_BEGIN3(...) ARR_BEGIN2(ARR_BEGIN1(__VA_ARGS__))
#define ARR_BEGIN4(...) ARR_BEGIN3(ARR_BEGIN1(__VA_ARGS__))
/* Extendible in the obvious way */
在 gcc (cpp 4.1.1) 和 tcc 中测试,但我相信这应该都是标准的 C99。
ARR_ELX
如果没有andARR_BEGINX
宏提供的额外步骤,预处理器有时会将FOO
其视为单个参数。