Home > Software engineering >  container_of() for pointers
container_of() for pointers

Time:11-26

I know what container_of() does, but I want to obtain a field that is a pointer within some struct like this:

struct A {
    int *ptr;
};

void some_func(int *ptr) {
    struct A *a = container_of(&ptr, struct A, ptr);
}

But it seems not working. This is compiled successfully, but looks like it produces wrong pointer:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

struct A {
    int *ptr;
};

void some_func(int *ptr)
{
    struct A *a = container_of(&ptr, struct A, ptr);
    if (a)
      pr_info("%d", *a->ptr);
    else
      pr_info("Ooops");
}

int __init m_init(void)
{
    int ptr = 10;
    struct A a = {.ptr = &ptr};

    some_func(&ptr);

    return 0;
}

void __exit m_exit(void)
{
}

module_init(m_init);
module_exit(m_exit);

MODULE_LICENSE("GPL");

If I do container_of(ptr, struct A, ptr); this isn't compiled:

error: static assertion failed: "pointer type mismatch in container_of()"

I guess this is because ptr is a pointer, not a usual int, so __same_type will return false, so make it a pointer.

can anybody help me to fix this?

CodePudding user response:

I will not work. The reason is that ptr in m_init is a local variable, so its address &ptr is meaningless for reconstruction of an address of the other local variable a.

However, you can replace:

some_func(&ptr);

with

some_func(&a.ptr);

But will require changing some_fun to take a pointer int* member of struct A. So the argument type must be int**.

void some_func(int **ptr)
{
    if (!ptr) {
      pr_info("Ooops");
    } else {
      struct A *a = container_of(ptr, struct A, ptr);
      pr_info("%d", *a->ptr);
    }
}
  • Related