The simiar code also appeared here: list_entry in Linux
But my question is that why cast it to unsigned long
? Because according to C99 6.3.2.3, the behavior is undefined or implementation defined to cast a pointer to interger
6.3.2.3: 6. Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
So why previous kernel cast a pointer to unsigned long ? Is it a bug?
The code:
#include <stdio.h>
struct foobar{
unsigned int foo;
}tmp;
printf("\taddress and offset of tmp->foo= %p\n",
(struct foobar *)(((char *)&tmp.foo)
- ((unsigned long)&((struct foobar *)0)->foo)));
I use gcc and a x86_64 machine , and I know the code from this tutorial