When I was browsing the Linux kernel, I found a container_of macro which is defined as follows:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
I understand what does container_of do, but what I do not understand is the last sentence, which is
(type *)( (char *)__mptr - offsetof(type,member) );})
If we use the macro as follows:
container_of(dev, struct wifi_device, dev);
The corresponding part of the last sentence would be:
(struct wifi_device *)( (char *)__mptr - offset(struct wifi_device, dev);
which looks like doing nothing.
Could anybody please fill the void here?
Your usage example container_of(dev, struct wifi_device, dev); might be a bit misleading as you are mixing two namespaces there.
While the first dev in your example refers to the name of pointer the second dev refers to the name of a structure member.
Most probably this mix up is provoking all that headache. In fact the member parameter in your quote refers to the name given to that member in the container structure.
Taking this container for example:
struct container {
int some_other_data;
int this_data;
}
And a pointer int *my_ptr to the this_data member you'd use the macro to get a pointer to struct container *my_container by using:
struct container *my_container;
my_container = container_of(my_ptr, struct container, this_data);
Taking the offset of this_data to the beginning of the struct into account is essential to getting the correct pointer location.
Effectively you just have to subtract the offset of the member this_data from your pointer my_ptr to get the correct location.
That's exactly what the last line of the macro does.
The last sentence cast:
(type *)(...)
a pointer to a given type. The pointer is calculated as offset from a given pointer dev:
( (char *)__mptr - offsetof(type,member) )
When you use the cointainer_of macro, you want to retrieve the structure that contains the pointer of a given field. For example:
struct numbers {
int one;
int two;
int three;
} n;
int *ptr = &n.two;
struct numbers *n_ptr;
n_ptr = container_of(ptr, struct numbers, two);
You have a pointer that points in the middle of a structure (and you know that is a pointer to the filed two [the field name in the structure]), but you want to retrieve the entire structure (numbers). So, you calculate the offset of the filed two in the structure:
offsetof(type,member)
and subtract this offset from the given pointer. The result is the pointer to the start of the structure. Finally, you cast this pointer to the structure type to have a valid variable.
conatainer_of() macro in Linux Kernel -
When it comes to managing several data structures in code, you'll almost always need to embed one structure into another and retrieve them at any moment without being asked questions about memory offsets or boundaries. Let's say you have a struct person, as defined here:
struct person {
int age;
int salary;
char *name;
} p;
By only having a pointer on age or salary, you can retrieve the whole structure wrapping (containing) that pointer. As the name says, the container_of macro is used to find the container of the given field of a structure. The macro is defined in include/linux/kernel.h and looks like the following:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
Don't be afraid of the pointers; just see them as follows:
container_of(pointer, container_type, container_field);
Here are the elements of the preceding code fragment:
pointer: This is the pointer to the field in the structure
container_type: This is the type of structure wrapping (containing) the pointer
container_field: This is the name of the field to which
pointer points inside the structure
Let's consider the following container:
struct person {
int age;
int salary;
char *name;
};
Now, let's consider one of its instances, along with a pointer to the age member:
struct person somebody;
[...]
int *age_ptr = &somebody.age;
Along with a pointer to the name member (age_ptr),you can use the container_of macro in order to get a pointer to the whole structure (container) that wraps this member by using the following:
struct person *the_person;
the_person = container_of(age_ptr, struct person, age);
container_of takes the offset of age at the beginning of the struct into account to get the correct pointer location. If you subtract the offset of the field age from the pointer age_ptr, you will get the correct location. This is what the macro's last line does:
(type *)( (char *)__mptr - offsetof(type,member) );
Applying this to a real example, gives the following:
struct family {
struct person *father;
struct person *mother;
int number_of_sons;
int family_id;
} f;
/*
* Fill and initialise f somewhere */ [...]
/*
* pointer to a field of the structure
* (could be any (non-pointer) member in the structure)
*/
int *fam_id_ptr = &f.family_id;
struct family *fam_ptr;
/* now let us retrieve back its family */
fam_ptr = container_of(fam_id_ptr, struct family, family_id);
The container_of macro is mainly used in generic containers in the kernel.
That's all about container_of macro in kernel.
It is an utilisation of a gcc extension, the statements expressions. If you see the macro as something returning a value, then the last line would be :
return (struct wifi_device *)( (char *)__mptr - offset(struct wifi_device, dev);
See the linked page for an explanation of compound statements. Here is an example :
int main(int argc, char**argv)
{
int b;
b = 5;
b = ({int a;
a = b*b;
a;});
printf("b %d\n", b);
}
The output is
b 25
Very useful link for understanding container_of macro in linux kernel.
https://linux-concepts.blogspot.com/2018/01/understanding-containerof-macro-in.html
A little real context says clearer, below use red-black tree as example, which is the
way that I understand container_of.
as Documentation/rbtree.txt states, in linux kernel code, it's not rb_node contain data
entry, rather
Data nodes in an rbtree tree are structures containing a struct
rb_node member.
struct vm_area_struct (in file include/linux/mm_types.h:284) is such a structure,
in the same
file, there is a macro rb_entry which is defined as
#define rb_entry(ptr, type, member) container_of(ptr, type, member)
clearly, rb_entry is same as container_of.
at mm/mmap.c:299 inside function definition browse_rb, there is a usage of rb_entry:
static int browse_rb(struct mm_struct *mm)
{
/* two line code not matter */
struct rb_node *nd, *pn = NULL; /*nd, first arg, i.e. ptr. */
unsigned long prev = 0, pend = 0;
for (nd = rb_first(root); nd; nd = rb_next(nd)) {
struct vm_area_struct *vma;
vma = rb_entry(nd, struct vm_area_struct, vm_rb);
/* -- usage of rb_entry (equivalent to container_of) */
/* more code not matter here */
now it is clear, in container_of(ptr, type, member),
type is the container struct, here struct vm_area_struct
member is name of a member of type instance, here vm_rb, which is of type rb_node,
ptr is a pointer pointing member of an type instance, here rb_node *nd.
what container_of do is, as in this example,
given address of obj.member (here obj.vm_rb), return the
address of obj.
since a struct is a block of contiguous memory, address of obj.vm_rb minus
offset between the struct and member will be the container's address.
include/linux/kernel.h:858 -- definition of container_of
include/linux/rbtree.h:51 -- definition of rb_entry
mm/mmap.c:299 -- usage of rb_entry
include/linux/mm_types.h:284 -- struct vm_area_struct
Documentation/rbtree.txt: -- Documentation of red-black tree
include/linux/rbtree.h:36 -- definition of struct rb_node
P.S.
Above files are in current develop version, i.e, 4.13.0-rc7.
file:k mean kth line in file.
Most Simplest Implementation of Container _of macro is below , It reduces all complex checking of type and works
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
ptr will give address of member and just subtract offset difference and you will
get start address.
Example usage
struct sample {
int mem1;
char mem2;
int mem3;
};
int main(void)
{
struct sample sample1;
printf("Address of Structure sample1 (Normal Method) = %p\n", &sample1);
printf("Address of Structure sample1 (container_of Method) = %p\n",
container_of(&sample1.mem3, struct sample, mem3));
return 0;
}
I am reading Linux Device Drivers Development from John Madieu and one para says
The container_of macro won't work for char * or array members. It
means the first member of container_of must not be a pointer to
another pointer to char nor to array in the structure.
This is the definition of container_of :
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
So if I have
struct person {
int age;
int salary;
char *name;
} me;
and I have char ** my_name = &(me.name);, why can't I do the following :
struct person * me = container_of(my_name,struct person,name);
This is due to ISO C rules on pointer initialisations, which break the initialisation of __mptr for this case.
Here's a stripped-back example:
int main()
{
char ar[5] = {0};
const char (*ptr)[5] = &ar;
}
// warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
(live demo)
There is a discussion about this problem on a prior SO question. Note that C++ has no such limitation; the const may be added freely.
A kernel dev discussion suggested replacing __mptr with another way to perform the type check inside container_of, so you may find that this already no longer affects you.
I want to implement container_of macro/function from scratch like that is available in linux kernel to get the address of parent structure from the member of the parent structure.
e.g. if the parent structure is
struct parent{
int id;
struct list_head list; };
and i have the address of the list_head element inside the structure.
So i want to get the address of struct parent so that i can access id of the parent.
I have only three known information
1. Type of parent structure
2. Type of struct list_head
3. identifire/name of the list_head variable.
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
Thaks i any body can explain.
Firstly your question is not appropriate. From my understanding you want to understand the working of the macro, not implement it.
Moving on,
Linked lists used in the linux kernel are nicely explained in Linux Kernel Linked List Explained
In the linux kernel the list is contained in the list node.
Example:
struct list_head { /* Kernel list structure */
struct list_head *next, *prev;
}
struct my_list {
int to;
struct list_head list; /* list is contained in the node */
int from;
}
So we iterate the linked list using the list_head variable. The tricky part is that we use the list variable to get the node structure ( in which it is contained )
See Q. 2.14 and 2.15 in MIT FAQ. The question explains how we can retrieve pointer to the CONTAINING structure if we have the offset of a variable in the struct.
So in layman terms, we could say,
struct s address = <address of struct variable> - <offset of that variable in the struct>
Coming to the macro, consider this definition of the macro. (simplistic implementation, i found in drivers/gpu/drm/nouveau/include/nvif/list.h )
#define container_of(ptr, type, member) \
(type *)((char *)(ptr) - (char *) &((type *)0)->member)
So think of the left operand as the structure VARIABLE ( this is the list_head variable usually). Now coming to the right operator. To get the OFFSET of that variable ( say list_head variable ) in the containing strict ( say struct my_list ), we create a zeroed struct ( i.e., a temp struct with the address 0x0 ) so the addresses of any variables in the struct corresponds to the offset of that variable.
Now the last part to understand is why cast to char *. Well this basic pointer arithmetic. char * addtion would increment the values by 1 at a time ( char* points to a char of 1 byte ).
((char*)0) + 1 -> 0x1
Had it been int * addition of 1 to the pointer would increment the offset by 4 , as int * points to a int of size 4( on my computer).
((int*)0) + 1 -> 0x4
Hope that helped .. :)
I am trying to port a library written in Java into C programming language. For Java interface, I intend to use a struct of function-pointers to replace, for instance:
// Java code
public interface ActionsFunction {
Set<Action> actions(Object s);
}
/* C code */
typedef struct ActionsFunction {
List* (*actions)(void* s);
void (*clear_actions)(struct List **list); /* Since C doesn't have garbage collector */
} ActionsFunction;
My question is: whether it is a suitable solution or not, and how can I simulate a generic interface such as:
public interface List <E> {
void add(E x);
Iterator<E> iterator();
}
UPDATE:
I also have to face with another problem: implementing generic abstract data structure like List, Queue, Stack, etc since the C standard library lacks of those implementation. My approach is client code should pass the pointer of its data accompanying with its size, thus allowing library to hold that one without specifying its type. One more time, it just my idea. I need your advices for the design as well as implementing technique.
My initial porting code can be found at:
https://github.com/PhamPhiLong/AIMA
generic abstract data structure can be found in utility sub folder.
Here's a very brief example using macros to accomplish something like this. This can get hairy pretty quick, but if done correctly, you can maintain complete static type safety.
#include <stdlib.h>
#include <stdio.h>
#define list_type(type) struct __list_##type
/* A generic list node that keeps 'type' by value. */
#define define_list_val(type) \
list_type(type) { \
list_type(type) *next; \
type value; \
}
#define list_add(plist, node) \
do \
{ \
typeof(plist) p; \
for (p = plist; *p != NULL; p = &(*p)->next) ; \
*p = node; \
node->next = NULL; \
} while(0)
#define list_foreach(plist, p) \
for (p = *plist; p != NULL; p = p->next)
define_list_val(int) *g_list_ints;
define_list_val(float) *g_list_floats;
int main(void)
{
list_type(int) *node;
node = malloc(sizeof(*node));
node->value = 42;
list_add(&g_list_ints, node);
node = malloc(sizeof(*node));
node->value = 66;
list_add(&g_list_ints, node);
list_foreach(&g_list_ints, node) {
printf("Node: %d\n", node->value);
}
return 0;
}
There are a few common ways to do generic-ish programming in C. I would expect to use one or more of the following methods in trying to accomplish the task you've described.
MACROS: One is to use macros. In this example, MAX looks like a function, but operate on anything that can be compared with the ">" operator:
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int i;
float f;
unsigned char b;
f = MAX(7.4, 2.5)
i = MAX(3, 4)
b = MAX(10, 20)
VOID *: Another method is to use void * pointers for representing generic data, and then pass function pointers into your algorithms to operate on the data. Look up the <stdlib.h> function qsort for a classic example of this technique.
UNIONS: Yet another, though probably seen less often, technique is to use unions to hold data of multiple different types. This makes your algorithms that operate on the data kinda ugly though and might not save much coding:
enum { VAR_DOUBLE, VAR_INT, VAR_STRING }
/* Declare a generic container struct for any type of data you want to operate on */
struct VarType
{
int type;
union data
{
double d;
int i;
char * sptr;
};
}
int main(){
VarType x;
x.data.d = 1.75;
x.type = VAR_DOUBLE;
/* call some function that sorts out what to do based on value of x.type */
my_function( x );
}
CLEVER CASTING & POINTER MATH It's a pretty common idiom to see data structures with functions that operate on a specific kind of struct and then require that the struct by included in your struct to do anything useful.
The easy way to do this, is the force the struct that allows insertion into the data structure to be the first member of your derived type. Then you can seamless cast back & forth between the two. The more versatile way is to use 'offsetof'. Here's a simple example.
For example:
/* Simple types */
struct listNode { struct listNode * next; struct listNode * prev };
struct list { struct listNode dummy; }
/* Functions that operate on those types */
int append( struct list * theList, struct listNode * theNode );
listNode * first( struct list *theList );
/* To use, you must do something like this: */
/* Define your own type that includes a list node */
typedef struct {
int x;
double y;
char name[16];
struct listNode node;
} MyCoolType;
int main() {
struct list myList;
MyCoolType coolObject;
MyCoolType * ptr;
/* Add the 'coolObject's 'listNode' member to the list */
appendList( &myList, &coolObject.node );
/* Use ugly casting & pointer math to get back you your original type
You may want to google 'offsetof' here. */
ptr = (MyCoolType *) ( (char*) first( &myList )
- offsetof(MyCoolType,node);
}
The libev documentation has some more good examples of this last technique:
http://search.cpan.org/dist/EV/libev/ev.pod#COMMON_OR_USEFUL_IDIOMS_(OR_BOTH)
The typical C99 way to extending stuct is something like
struct Base {
int x;
/* ... */
};
struct Derived {
struct Base base_part;
int y;
/* ... */
};
Then we may cast instance of struct Derived * to struct Base * and then access x.
I want to access base elements of struct Derived * obj; directly, for example obj->x and obj->y. C11 provide extended structs, but as explained here we can use this feature only with anonymous definitions. Then how about to write
#define BASE_BODY { \
int x; \
}
struct Base BASE_BODY;
struct Derived {
struct BASE_BODY;
int y;
};
Then I may access Base members same as it's part of Derived without any casts or intermediate members. I can cast Derived pointer to Base pointer if need do.
Is this acceptable? Are there any pitfalls?
There are pitfalls.
Consider:
#define BASE_BODY { \
double a; \
short b; \
}
struct Base BASE_BODY;
struct Derived {
struct BASE_BODY;
short c;
};
On some implementation it could be that sizeof(Base) == sizeof(Derived), but:
struct Base {
double a;
// Padding here
short b;
}
struct Derived {
double a;
short b;
short c;
};
There is no guarantee that at the beginning of the struct memory layout is the same. Therefore you cannot pass this kind of Derived * to function expecting Base *, and expect it to work.
And even if padding would not mess up the layout, there is a still potential problem with trap presenstation:
If again sizeof(Base) == sizeof(Derived), but c ends up to a area which is covered by the padding at the end of Base. Passing pointer of this struct to function which expects Base* and modifies it, might affect padding bits too (padding has unspecified value), thus possibly corrupting c and maybe even creating trap presentation.