表达式的用途(var,var)

时间:2018-01-02 08:22:54

标签: c

我遇到过这个表达 ((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)

1 个答案:

答案 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。它现在正在使用,所以没有警告。第二个表达式求值为常量,并且是整个带括号的表达式的值。