我正在尝试使用结构字段的偏移填充数组,我正在尝试执行以下操作
#define EXPAND_(X) X
#define TYPE_ARG_N(_0, _1, _2, N, ...) N
#define TYPE_OFFSET_1(S, _0) { sizeof(S), { offsetof(S, _0) } }
#define TYPE_OFFSET_2(S, _0, _1) { sizeof(S), { offsetof(S, _0), offsetof(S, _1) } }
#define TYPE_OFFSET_3(S, _0, _1, _2) { sizeof(S), { offsetof(S, _0), offsetof(S, _1), offsetof(S, _2) } }
#define TYPE_OFFSET_LIST() TYPE_OFFSET_3, TYPE_OFFSET_2, TYPE_OFFSET_1
#define TYPE_OFFSET_N_(...) EXPAND_(TYPE_ARG_N(__VA_ARGS__))
#define TYPE_OFFSET_ARGS(...) EXPAND_(__VA_ARGS__)
#define TYPE_OFFSET_SELECT(...) TYPE_OFFSET_N_(__VA_ARGS__, TYPE_OFFSET_LIST())
#define TYPE_OFFSET(S, ...) TYPE_OFFSET_SELECT(__VA_ARGS__)(S, TYPE_OFFSET_ARGS(__VA_ARGS__))
typedef struct {
size_t size;
size_t* offsets;
} tTable;
tTable t = TYPE_OFFSET(tTable, size, offsets);
MSVC2017失败并出现以下情况:
error C4003: not enough actual parameters for macro 'TYPE_OFFSET_2'
error C2065: 'offsets': undeclared identifier
error C2102: '&' requires l-value
有关如何修复这些宏的想法吗?
答案 0 :(得分:0)
对于这样的调试,请尝试使用/EP
标志通过 预处理器运行。使用您的代码执行此操作会显示以下输出:
typedef struct {
size_t size;
size_t* offsets;
} tTable;
tTable t = fxma.h(17) : warning C4003: not enough actual parameters for macro 'TYPE_OFFSET_2'
{ sizeof(tTable), { offsetof(tTable, size, offsets), offsetof(tTable, ) } };
这里的问题是,微软的预处理器有一个单一宏参数的概念,其中包含逗号。当通过扩展另一个宏产生逗号时会发生这种情况。
特别是,TYPE_OFFSET
与TYPE_OFFSET_2
,但 (tTable, size, offset)
一起调用size, offset
(是TYPE_OFFSET_ARGS(__VA_ARGS__)
的扩展)isn&实际上有两个不同的论点......它只有1. TYPE_OFFSET_2
然后才得到两个论点;换句话说:
S
是tTable1
_0
是size, offset
_1
缺失(你可以在扩展中看到这一点; offsetof(tTable, size, offsets)
)。
修复是添加间接级别。将此版本的TYPE_OFFSET
替换为:
#define TYPE_OFFSET_CALL(X, Y) X Y
#define TYPE_OFFSET(S, ...) TYPE_OFFSET_CALL(TYPE_OFFSET_SELECT(__VA_ARGS__),(S, TYPE_OFFSET_ARGS(__VA_ARGS__)))