【问题标题】:Replacing the container_of macro used in linux kernel替换linux内核中使用的container_of宏
【发布时间】:2019-02-11 07:51:14
【问题描述】:

在尝试从源代码 linux kernel Definition of container_of 理解 container_of() 的功能时,我发现宏定义中的以下行看起来什么都不做。 p>

const typeof( ((type *)0)->member ) *__mptr = (ptr); \

所以,我写了一个没有上述行的简单C程序,并尝试比较获得的结果。 基本上,我试图了解新的实现 my_contianer_of()container_of() 有何不同? 当两个实现都给出相同的结果时。

#include <stdio.h>
#include <stddef.h>

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

#define my_container_of(ptr, type, member) ({ \
        (char *)ptr - offsetof(type, member);})

struct container {
    int *i;
    char c;
    float f;
};

void foo(char *cptr)
{
    printf("foo  : %p\n", my_container_of(cptr, struct container, c));
}

int main(int argc, char *argv[])
{
    struct container tc;

    printf("&tc  : %p\n", &tc);
    printf("cof  : %p\n", container_of(&tc.c, struct container, c));
    printf("mycof: %p\n", my_container_of(&tc.c, struct container, c));

    foo(&tc.c);

    return 0;
}

以下是上述 c 程序的示例输出。

&tc  : 0x7ffca543e0c0
cof  : 0x7ffca543e0c0
mycof: 0x7ffca543e0c0
foo  : 0x7ffca543e0c0

请不要将此问题标记为与任何其他问题或此 Understanding container_of macro in the linux kernel 重复,因为这些问题没有为我的查询提供所需的答案。

【问题讨论】:

  • 可能存在简化版无法处理的极端情况。或者这只是消除编译器隐式类型转换警告的问题。

标签: c linux


【解决方案1】:

您的实现不是类型安全的。它不能确保您传递的指针与成员的类型相同,这可能会导致错误。所以,例如:

my_container_of(&tc.f, struct container, c)

会编译得很好。内核版本至少会发出关于不兼容指针类型的警告。或者完全导致编译停止,具体取决于您的 GCC 标志。

当然,内核版本并不能防止所有错误(例如,如果fc 属于同一类型)。但这是它可以捕捉的,而且应该捕捉到的。

【讨论】:

    猜你喜欢
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    相关资源
    最近更新 更多