为什么这样0((键入*)0) - >成员用C? [英] Why this 0 in ((type*)0)->member in C?

查看:147
本文介绍了为什么这样0((键入*)0) - >成员用C?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

container_of( ) 在Linux内核中宏定义为:

 的#define container_of(PTR,类型,成员)({\\
        常量的typeof(((键入*)0) - >成员)* __mptr =(PTR); \\
        (类型*)((字符*)__ mptr - offsetof(类型,成员));})

为什么这样使用((类型*)0) - >成员,而不是(类型*) - GT;成员


解决方案

  

这是为什么((键入*)0) - >成员,而不是(类型*) - >成员


很简单,因为(类型*) - GT;成员将是无效的语法,从而的typeof 是不可能的。因此,它使用了 NULL 指针,反正它不会解除引用 - 它的使用只是让的typeof 可参考成员。


这是如何工作:


  • 的typeof 诀窍是用来声明该成员的类型的指针。该指针得到的是通过调用者传递指针初始化


  • 中结构从指针的地址减去该成员的偏移量:这会产生包含对象的地址



微妙的问题:为什么不摆脱的typeof 并只是做 PTR - offsetof 。我们是铸造到的char * 无论如何,对不对?在这种情况下,你可以通过任何的 PTR 和编译器不会说的事。所以整个的typeof 的东西是有(初级)的类型检查。

The container_of() macro in the Linux kernel is defined as:

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

Why does this use ((type*)0)->member, not (type*)->member?

解决方案

Why this is ((type*)0)->member, not (type*)->member

Simply because (type*)->member would be invalid syntax, thus typeof would be impossible. So it uses a NULL pointer, which it doesn't dereference anyway - it's used just so typeof can refer to the member.


How this works:

  • The typeof trick is used to declare a pointer of the type of the member. This pointer gets is initialized with the pointer passed by the caller

  • The offset of that member in the struct is subtracted from the address of the pointer: this yields the address of the containing object


Subtler issue: why not get rid of typeof and just do ptr - offsetof. We're casting it to char * anyway, right ? In that case you could pass anything as ptr and the compiler won't say a thing. So the whole typeof things is there for (rudimentary) type checking.

这篇关于为什么这样0((键入*)0) - >成员用C?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆