Beautiful Code [44]
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
This macro deserves some explanation, for those not up on their pointer arithmetic in the C language. To take an example, the previous struct usb_interface could convert a pointer to the struct device member of the structure back to the original pointer through:
int probe(struct device *d) {
struct usb_interface *intf;
intf = container_of(d, struct usb_interface, dev);
...
}
where d is a pointer to a struct device.
Expanding the container_of macro just shown creates the following code:
Code View: Scroll / Show All
intf = ({
const typeof( ((struct usb_interface *)0)->dev) *__mptr = d;
(struct usb_interface *)( (char *)__mptr - offsetof(struct usb_interface, dev));
});
To understand this, remember that dev is a member of the struct usb_interface structure. The first line of the macro sets up a pointer that points to the struct device passed to the code. The second line of the macro finds the real location in memory of the struct usb_ interface that we want to access.
So, with the type of the dev structure known, the macro can be reduced to:
Code View: Scroll / Show All
intf = ({
const struct device *__mptr = d;
(struct usb_interface *)( (char *)__mptr - offsetof(struct usb_interface, dev));
});
Based on the definition of the struct usb_interface recently shown, the dev variable is probably placed 16 bytes into the structure on a 32-bit processor. This is automatically calculated by the compiler with the offsetof macro. Replacing this information in the macro now yields:
intf = ({
const struct device *__mptr = d;
(struct usb_interface *)( (char *)__mptr - 16));
});
The container_of macro has now been reduced to simple pointer arithmetic, subtracting 16 from the original pointer to get to the desired struct usb_interface pointer. The compiler does this quickly at runtime.
With this very simple method, the Linux kernel allows normal C structures to be inherited and manipulated in very powerful ways. Well, very powerful as long as you know exactly what you are doing.
If you notice, there is no runtime type checking to ensure that the pointer that was originally passed as a struct device really was of the struct usb_interface type. Traditionally, most systems that do this kind of pointer manipulation also have a field in the base structure that defines the type of the pointer being manipulated, to catch sloppy programming errors. It also allows for code to be written to dynamically determine the type of the pointer and do different things with it based on the type.
The Linux kernel developers made the decision to do none of this checking or type definition. These types of checks can catch basic programming errors at the initial time of development, but allow programmers to create hacks that can have much more subtle problems later on that can't be easily caught.
The lack of runtime checking forces the developers who are manipulating these pointers to be absolutely sure they know exactly what type of pointer they are manipulating and passing around the system. Sure, at moments, a developer really wishes that there would be some way to determine what type of struct device he is staring at, but the feeling eventually passes when the problem is properly debugged.
Is this lack of type checking good enough to be called "beautiful code"? After working with it for over five years, yes, I think it is. It keeps easy hacks from springing up within the kernel and forces everyone to be very exact in their logic, never falling back on any checks for types