Re: question about linked list implementation in kernel.h

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I just made a small example (with comments) to play around with :-)
Let me know if you feel something is wrong in my explanations (I'm still learning as well!)
Hope it helps!

On Sat, Sep 11, 2010 at 6:03 PM, Bond <jamesbond.2k.g@xxxxxxxxx> wrote:
I read
I was going through include/linux/kernel.h
encountered following code

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

in above code I am not clear with (type *)0
how is it working any link?



--
/manohar
#include <stdio.h>
#include <stdlib.h>

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

/*
 * The first line gets the type of the member inside the structure. It does
 * this by casting a NULL pointer to the structure type and using the GCC
 * typeof() extension.
 *
 * The second line evaluates to a value of the address of the containing 
 * structure. This is done using the value of the member pointer and 
 * subtracting the offset of the member from its own address.
 * 
 * eg. if a member is at address 10 and is at an offset of 4 bytes into 
 * the struture, the containing structure's pointer is at address (10 - 4) = 6
 */
#define container_of(ptr, type, member) ({          \
	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
	(type *)( (char *)__mptr - offsetof(type,member) );})


struct test {
	int a;
};

/* 
 * Given the pointer to a member inside a structure, retreive its containing 
 * structure pointer
 */
void test_func(int *ptr)
{
	/* You can see the output of this macro using: "gcc -E cont.c" */
	struct test *container = container_of(ptr, struct test, a);
	printf("Retreived pointer: %x\n", (unsigned int)container);
	printf("Value: %d\n", container->a);
}

int main()
{
	struct test *t = malloc(sizeof(struct test));
	t->a = 5;
	printf("Structure pointer: %x\n", (unsigned int)t);
	printf("Value: %d\n", t->a);
	test_func(&t->a);
	free(t);

	
	/* 
	 * This is how a block is evaluated to a value (explains how the macro 
	 * works. See output from "gcc -E cont.c". 
	 */
	int val = ({5 + 5;});
	printf("Block value: %d\n", val);
}

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux