我遇到过这个表达
((void)(obj), (size_t)0)
这个表达式(看起来像是一个函数签名)的目的是什么?
It's part of a list of macros I found:
#define ers_alloc(obj,type) ((void)(obj), (type *)aMalloc(sizeof(type)))
#define ers_free(obj,entry) ((void)(obj), aFree(entry))
#define ers_entry_size(obj) ((void)(obj), (size_t)0)
#define ers_destroy(obj) ((void)(obj), (void)0)
#define ers_chunk_size(obj,size) ((void)(obj), (void)(size), (size_t)0)
答案 0 :(得分:4)
这些宏的存在允许相同的代码在两种配置中进行编译。如果未定义控制宏DISABLE_ERS
,则ers_entry_size(some_o)
将扩展为:
((some_o)->entry_size(some_o))
代码中使用了ers_entry_size(some_o)
。但即使我们定义DISABLE_ERS
,相同的代码也必须成功构建。这些宏可以在理论上被定义为
#define ers_alloc(obj,type) ((type *)aMalloc(sizeof(type)))
#define ers_free(obj,entry) (aFree(entry))
#define ers_entry_size(obj) ((size_t)0)
#define ers_destroy(obj) (void)0)
#define ers_chunk_size(obj,size) ((size_t)0)
但是如果ers_entry_size(some_o)
是唯一的方式特定函数使用some_o
怎么办?如果宏扩展为((size_t)0)
,则现在some_o
将变为未使用状态。现代编译器会发出有关未变量的警告。我们的代码无法在库的有效配置中编译成一堆警告。这是一个糟糕的图书馆设计。
因此,而不是天真的" no-op"定义,使用更聪明的。自comma operator evaluates each operand and discards all but the last以来,我们可以利用它。按照您的说明定义宏时,ers_entry_size(some_o)
将扩展为
((void)(some_o), (size_t)0)
提供给逗号运算符的第一个表达式评估并丢弃some_o
。它现在正在使用,所以没有警告。第二个表达式求值为常量,并且是整个带括号的表达式的值。