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);
}
發(fā)現(xiàn)redisAeReadEvent的三個變量 el, fd, mask 的使用上很特別: 函數(shù)體中均用void做了強制轉(zhuǎn)換, 但是其他地方?jīng)]有使用的. 就個人常識而言, 這種強制轉(zhuǎn)換沒有任何實現(xiàn)層面的意義, 為何redis的作者要如此為之.
百思不解, 于是決定將((void)el); ((void)fd); ((void)mask); 這段代碼刪了試試會發(fā)生什么:
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 三個變量沒有使用過.
恍然大悟: 原來做'多此一舉'的強制轉(zhuǎn)換是為了消除編譯器警告, 告訴編譯器這些變量我用過了, 你就別給我發(fā)警告了.
通常redis中用UNUSED宏來處理不使用的變量:
/*server.h: Anti-warning macro... */
#define UNUSED(V) ((void) V)
總結(jié):
在c語言編程中類似的處理技巧還是很普遍的, 特別是在一些接口編程中, 函數(shù)簽名是定義好的, 具體實現(xiàn)中可能有些變量用不上, 可以采用這種人為將無用變量強制轉(zhuǎn)換為void的方式, 消除編譯器警告.