[英]Macro to refer to struct member, homegrown complex type to standard C99 complex conversion
[英]C99 Macro Expansion for Struct Member Access
是否可以在宏中进行无效检查和访问?
例如:
#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");
调用它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
的可能性。 例如:创建结构本身出错时的情况。
您的问题是,尽管永远不会采用第一个分支,但NULL
不是执行->error_level
的正确类型。
您可以通过为其指定正确的类型来避免这种情况。 我会使用局部变量而不是强制类型转换来执行此操作,因此您将捕获宏的错误用例。 只需添加
yourType* myStr = mystruct;
current = myStr->error_level;
你应该没事的
是否可以在宏中进行无效检查和访问?
不,预处理程序正在执行简单的文本替换。 它不支持宏定义内的条件。
当您将宏与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" );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.