/* * Copyright (C) gtc. */ #ifndef _GTC_QUEUE_H_INCLUDED_ #define _GTC_QUEUE_H_INCLUDED_ #include "gtc_core.h" typedef struct gtc_queue_s gtc_queue_t; struct gtc_queue_s { gtc_queue_t *prev; gtc_queue_t *next; }; #define gtc_queue_init(q) \ (q)->prev = q; \ (q)->next = q #define gtc_queue_empty(h) \ (h == (h)->prev) #define gtc_queue_push(h, x) \ (x)->next = (h)->next; \ (x)->next->prev = x; \ (x)->prev = h; \ (h)->next = x #define gtc_queue_tail(h) \ (h)->prev #define gtc_queue_remove(x) \ (x)->next->prev = (x)->prev; \ (x)->prev->next = (x)->next #define gtc_queue_pop(h) \ gtc_queue_remove(h->prev) #define gtc_queue_data(q, type, link) \ (type *) ((u_char *) q - offsetof(type, link)) #endif /* _GTC_QUEUE_H_INCLUDED_ */
上述是一个队列的实现,这个队列实现是有问题的,问题在于 gtc_queue_pop 这个宏定义。
宏定义本质上是一种替换,gtc_queue_pop 中调用了 gtc_queue_remove ,这里的传参有讲究,
gtc_queue_remove 的入参是 h->prev,当执行 gtc_queue_remove 中 (x)->next->prev = (x)->prev; 语句时
会导致 h->prev 的指向发生了变化,导致下面的执行出现异常,宏不同于函数,它的简单替换可能会带来一些奇怪的问题
特此做好记录。