我在代码中使用宏container_of()
。
然而,它的定义在算术中使用了NULL
指针((type *)0)
,这会带来错误
pointer of type 'void *' used in arithmetic
使用不((type *)0)->member
的{{1}}或container_of()
是否还有其他选择。
代码中引发错误的行是:
NULL
真正的代码非常大。我将放置具有以上行的函数的片段:
struct net_if_rx *rx = container_of(fq, struct net_if_rx, fq);
我对container_of定义有这个:
static enum qman_cb_dqrr_result cb_rx(struct qman_portal *qm __always_unused,
struct qman_fq *fq,
const struct qm_dqrr_entry *dqrr)
{
struct ether_header *prot_eth;
const struct qm_fd *fd = &dqrr->fd;
struct net_if_rx *rx = container_of(fq, struct net_if_rx, fq);
BUG_ON(fd->format != qm_fd_contig);
prot_eth = __dma_mem_ptov(qm_fd_addr(fd));
prot_eth = prot_eth + fd->offset;
/* Broadcasts and non-IP packets are not reflected. */
if (likely(!(prot_eth->ether_dhost[0] & 0x01) &&
(prot_eth->ether_type == ETHERTYPE_IP))) {
struct iphdr *iphdr = (typeof(iphdr))(prot_eth + 1);
__be32 tmp;
/* switch ipv4 src/dst addresses */
tmp = iphdr->daddr;
iphdr->daddr = iphdr->saddr;
iphdr->saddr = tmp;
/* switch ethernet src/dest MAC addresses */
ether_header_swap(prot_eth);
/* transmit */
send_frame(rx->tx_fqid, fd);
} else
/* drop */
drop_frame(fd);
return qman_cb_dqrr_consume;
}
答案 0 :(得分:1)
container_of
的预期实施是:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) ); \
})
请注意,我们在此代码中使用了多个gcc扩展名:Statement expressions以及null取消引用。
如果我们想编写严格符合规范的代码,我们可以删除第一个语句,它只用于为程序员提供类型安全性:
#define container_of(ptr, type, member) \
((type *)( (char *)(ptr) - offsetof(type, member) ))
这可以让你安静地发出警告。