宏可以接受类型吗?
Can macros accept types?
除非我理解有误,下面的宏
int i; // for loop
const char* ctype; // proprietary type string
void** pool = malloc(sizeof(void*) * (nexpected - 1));
size_t poolc = 0;
#define SET(type, fn) type* v = (pool[poolc++] = malloc(sizeof(type))); \
*v = (type) fn(L, i)
#define CHECK(chr, type, fn) case chr: \
SET(type, fn); \
break
switch (ctype[0]) {
CHECK('c', char, lua_tonumber);
}
应该扩展到
int i; // for loop
const char* ctype; // proprietary type string
void** pool = malloc(sizeof(void*) * (nexpected - 1));
size_t poolc = 0;
switch (ctype[0]) {
case 'c':
char* v = (pool[poolc++] = malloc(sizeof(char)));
*v = (char) lua_tonumber(L, i);
break;
}
但编译后,我得到:
src/lua/snip.m:185:16: error: expected expression
CHECK('c', char, lua_tonumber);
^
src/lua/snip.m:181:9: note: expanded from macro 'CHECK'
SET(type, fn); \
^
src/lua/snip.m:178:23: note: expanded from macro 'SET'
#define SET(type, fn) type* v = (pool[poolc++] = malloc(sizeof(type))); \
^
src/lua/snip.m:185:5: error: use of undeclared identifier 'v'
CHECK('c', char, lua_tonumber);
^
src/lua/snip.m:181:5: note: expanded from macro 'CHECK'
SET(type, fn); \
^
src/lua/snip.m:179:6: note: expanded from macro 'SET'
*v = (type) fn(L, i)
^
2 errors generated.
这是怎么回事?预处理器不是文字文本替换引擎吗?为什么要尝试计算表达式?
请记住,虽然这看起来像纯 C,但实际上是 C11 标准下的 clang Objective C(注意 .m
)。不确定这是否有任何区别。
我不知道如何在不扩展每个条目的代码的情况下继续。
您的理解是正确的!但是您 运行 陷入了 C 语言的怪癖。 A label, including a case
label, must be followed by an expression, not a variable declaration.
您可以通过在 case
之后插入空语句(例如 0;
)或将 case
主体括在一组大括号中来解决此问题。一种实用的方法是将 CHECK
重新定义为:
#define CHECK(chr, type, fn) \
case chr: { SET(type,fn); } break;
除非我理解有误,下面的宏
int i; // for loop
const char* ctype; // proprietary type string
void** pool = malloc(sizeof(void*) * (nexpected - 1));
size_t poolc = 0;
#define SET(type, fn) type* v = (pool[poolc++] = malloc(sizeof(type))); \
*v = (type) fn(L, i)
#define CHECK(chr, type, fn) case chr: \
SET(type, fn); \
break
switch (ctype[0]) {
CHECK('c', char, lua_tonumber);
}
应该扩展到
int i; // for loop
const char* ctype; // proprietary type string
void** pool = malloc(sizeof(void*) * (nexpected - 1));
size_t poolc = 0;
switch (ctype[0]) {
case 'c':
char* v = (pool[poolc++] = malloc(sizeof(char)));
*v = (char) lua_tonumber(L, i);
break;
}
但编译后,我得到:
src/lua/snip.m:185:16: error: expected expression
CHECK('c', char, lua_tonumber);
^
src/lua/snip.m:181:9: note: expanded from macro 'CHECK'
SET(type, fn); \
^
src/lua/snip.m:178:23: note: expanded from macro 'SET'
#define SET(type, fn) type* v = (pool[poolc++] = malloc(sizeof(type))); \
^
src/lua/snip.m:185:5: error: use of undeclared identifier 'v'
CHECK('c', char, lua_tonumber);
^
src/lua/snip.m:181:5: note: expanded from macro 'CHECK'
SET(type, fn); \
^
src/lua/snip.m:179:6: note: expanded from macro 'SET'
*v = (type) fn(L, i)
^
2 errors generated.
这是怎么回事?预处理器不是文字文本替换引擎吗?为什么要尝试计算表达式?
请记住,虽然这看起来像纯 C,但实际上是 C11 标准下的 clang Objective C(注意 .m
)。不确定这是否有任何区别。
我不知道如何在不扩展每个条目的代码的情况下继续。
您的理解是正确的!但是您 运行 陷入了 C 语言的怪癖。 A label, including a case
label, must be followed by an expression, not a variable declaration.
您可以通过在 case
之后插入空语句(例如 0;
)或将 case
主体括在一组大括号中来解决此问题。一种实用的方法是将 CHECK
重新定义为:
#define CHECK(chr, type, fn) \
case chr: { SET(type,fn); } break;