member"的替代方法-6ren"> member"的替代方法-我在代码中使用了宏container_of()。 然而,它的定义在算术中使用了NULL指针((type *)0),这会带来错误 pointer of type 'void *' used in ari-6ren">
gpt4 book ai didi

c - 在container_of()中使用 "((type *)0)->member"的替代方法

转载 作者:行者123 更新时间:2023-11-30 15:22:11 29 4
gpt4 key购买 nike

我在代码中使用了宏container_of()

然而,它的定义在算术中使用了NULL指针((type *)0),这会带来错误

pointer of type 'void *' used in arithmetic

除了使用 ((type *)0)->member 或不使用 NULLcontainer_of() 之外,还有其他替代方法吗>.

代码中引发错误的行是这样的:

struct net_if_rx *rx = container_of(fq, struct net_if_rx, fq);

真正的代码相当大。我将放置具有上述行的函数片段:

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;
}

我有这个container_of定义:

#ifndef container_of
#define container_of(ptr, type, member) \
((type *) \
( ((char *)(ptr)) \
- ((char *)(&((type*)0)->member)) ))

#endif

最佳答案

container_of 的预期实现是:

#define container_of(ptr, type, member) ({               \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) ); \
})

请注意,我们在此代码中使用了多个 gcc 扩展:Statement expressions以及空取消引用。

如果我们想编写严格一致的代码,我们可以删除第一条语句,它仅用于为程序员提供类型安全:

#define container_of(ptr, type, member) \
((type *)( (char *)(ptr) - offsetof(type, member) ))

这还有一个额外的好处,就是可以消除您收到的警告。

关于c - 在container_of()中使用 "((type *)0)->member"的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29304942/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com