Linux内核container_of宏和C90中的通用容器
是否可以实现 container_of 纯C90 中的宏?我不确定如何做到这一点,因为内核实现取决于 GCC Hacks,例如 typeof
运算符。
我这样问是因为我想在 C90 中实现一个类似于内核的通用容器 链接列表。我正在考虑的实际容器是一个排序集,类似于您可以从 增强多重索引。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在
container_of()
的内核定义中使用typeof
仅用于编译时类型检查 - 它确保传递的ptr
是实际上是一个指向与member
相同类型的指针。可以将其修改为完全 ANSI C,但需要进行类型检查:(offsetof()
位于
中)The use of
typeof
in the kernel definition ofcontainer_of()
is just for compile-time type-checking - it ensures that the passedptr
is really a pointer to the same type asmember
. It can be modified to be entirely ANSI C at the cost of this type-checking:(
offsetof()
is in<stddef.h>
)是的。
诀窍是替换复合表达式和用于类型检查的
typeof
。可以通过将(ptr)
的求值替换为:条件运算符始终返回第一个操作数,因为其选择操作数为 1。另一个操作数不求值,因此由于
NULL
解引用而没有 UB。此外,?:
的操作数类型必须兼容,强制编译器进行类型检查。最终的宏是:
这个宏甚至比原来的
container_of
更好。C89 变体可以在文件范围内使用或用于静态变量的初始化,而 Linux 则不能。
Yes.
The trick is replacing compound expression and
typeof
used for type checking. It can be done by replacing evaluation of(ptr)
with:A conditional operator always returns the first operand because its selection operand is 1. The other operand is not evaluated, therefore there is no UB due to
NULL
dereferencing. Moreover, the types of operands of?:
have to be compatible forcing type checking from a compiler.The final macro is:
This macro is even better than the original
container_of
.The C89 variant can be used at file scope or for initialization of static variables, while the Linux one cannot.