我遇到过这个表达式
((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)
最佳答案
这些宏的存在是为了允许相同的代码以两种配置进行编译。如果未定义控制宏 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
变为未使用。现代编译器发出有关 unsed 变量的警告。我们不能让我们的代码在库的有效配置中编译成一堆警告。那是糟糕的库设计。
因此,我们使用了一种更智能的定义,而不是天真的“无操作”定义。自 comma operator evaluates each operand and discards all but the last ,我们可以利用它。当按照您的说明定义宏时,ers_entry_size(some_o)
将扩展为
((void)(some_o), (size_t)0)
提供给逗号运算符的第一个表达式计算并丢弃 some_o
。它现在正在使用,所以没有警告。第二个表达式的计算结果为常量,是整个括号表达式的值。
关于c - 表达式的目的 (var, var),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48057709/