TIR: 为何将不使用的变量强制转换为void

Thinking In Redis


阅读redis源码时看到如下代码:

static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
    ((void)el); ((void)fd); ((void)mask);

    redisAeEvents *e = (redisAeEvents*)privdata;
    redisAsyncHandleRead(e->context);
}

发现redisAeReadEvent的三个变量 el, fd, mask 的使用上很特别: 函数体中均用void做了强制转换, 但是其他地方没有使用的. 就个人常识而言, 这种强制转换没有任何实现层面的意义, 为何redis的作者要如此为之.

百思不解, 于是决定将((void)el); ((void)fd); ((void)mask); 这段代码删了试试会发生什么:

src git:(dev) ✗ make
    CC release.o
    CC sentinel.o

sentinel.c:271:43: warning: unused parameter 'el' [-Wunused-parameter]
static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
                                          ^
sentinel.c:271:51: warning: unused parameter 'fd' [-Wunused-parameter]
static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
                                                  ^
sentinel.c:271:75: warning: unused parameter 'mask' [-Wunused-parameter]
static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {

编译器给出了警告, 说 el, fd, mask 三个变量没有使用过.
恍然大悟: 原来做'多此一举'的强制转换是为了消除编译器警告, 告诉编译器这些变量我用过了, 你就别给我发警告了.

通常redis中用UNUSED宏来处理不使用的变量:

/*server.h: Anti-warning macro... */
#define UNUSED(V) ((void) V)

总结:
在c语言编程中类似的处理技巧还是很普遍的, 特别是在一些接口编程中, 函数签名是定义好的, 具体实现中可能有些变量用不上, 可以采用这种人为将无用变量强制转换为void的方式, 消除编译器警告.

你可能感兴趣的:(TIR: 为何将不使用的变量强制转换为void)