是否可以在宏中进行无效检查和访问?
例如:
#define LOG(mystruct, severity, format, ...) ({ \
severity_t current = ERROR; \
if (mystruct) { \
current = mystruct->error_level; \
} \
if (severity >= current) { \
... //handle logging
} \
})
如果我用LOG(NULL, DEBUG, "test %s", "one");
打电话给我,我会收到错误:
error: member reference base type 'void' is not a structure or union
note: expanded from macro 'LOG'
current = mystruct->error_level;
mystruct定义为:
typedef struct mystruct_t {
severity_t error_level;
}
我想允许使用NULL mystruct
。例如:创建结构本身时出错的情况。
答案 0 :(得分:3)
您的问题是,虽然第一个分支永远不会被采用,但NULL
没有正确的类型来执行->error_level
。
你可以通过给它正确的类型来避免这种情况。我会使用局部变量,而不是强制转换,因此您可以捕获宏的错误用例。只需添加
yourType* myStr = mystruct;
current = myStr->error_level;
你应该没事。
答案 1 :(得分:0)
是否可以在宏中进行无效检查和访问?
不,预处理器正在进行简单的文本替换。它不支持宏定义中的条件。
当您使用LOG(NULL, DEBUG, "test %s", "one");
的宏时,第四行会扩展为
current = NULL->error_level;
由于NULL
通常定义为#define NULL ((void *)0)
,因此会进一步扩展为
current = ((void *)0)->error_level;
这就是为什么你得到关于void
不是结构或联合的消息。
要解决此问题,请不要将NULL
传递给宏,将包含NULL
的指针传递给宏,例如
mystruct_t *ptr = malloc(...);
if ( !ptr )
LOG( ptr, DEBUG, "no memory" );