There is this macro offsetof in C/C++ which allows you to get the address offset of a member in a POD structure. For an example from the C FAQ:
struct foo {
int a;
int b;
};
struct foo;
/* Set the b member of foo indirectly */
*(int *)((char *)foo + offsetof(b)) = 0xDEADBEEF;
Now this just seems evil to me and I can’t see many legit uses of this macro.
One legit example I have seen is it’s use in the container_of macro in the Linux Kernel for getting the address of an embedded structures parent object:
/* get the address of the cmos device struct in which the cdev
structure which inode points to is embedded */
struct cmos_dev *cmos_devp =
container_of(inode->i_cdev, struct cmos_dev, cdev);
What other legit uses are there for this macro? When should you not use this macro?
EDIT So far this answer to a different SO question is the best one I’ve seen so far.
Well … In C, it’s very useful for any place where you need code to describe a data structure. I’ve used it e.g. to do run-time-generated GUI:s for setting options.
This worked like this: a command that needs options defines a local structure holding its options, and then describes that structure to the code that generates the GUI, using
offsetofto indicate where fields are. Using offsets rather than absolute addresses allows the GUI code to work with any instance of the struct, not just one.This is bit hard to sketch quickly in an example (I tried), but since comments indicate an example is in order, I’ll try again.
Assume we have a self-contained module, called a “command”, that implements some action in the application. This command has a bunch of options that control its general behaviour, which should be exposed to the user through a graphical user interface. For the purposes of this example, assume the application is a file manager, and the command could be e.g. “Copy”.
The idea is that the copy code lives in one C file, and the GUI code in another, and the GUI code does not need to be hard-coded to “support” the copy command’s options. Instead, we define the options in the copy file, like so:
Then, the copy command registers its configuration settings with the GUI module:
Then, let’s say the user asks to set the copy command’s options. We can then first copy the current options, to support cancelling, and ask the GUI module for a dialog holding controls, built at run-time, suitable for editing this command’s options:
Of course, this code assumes the settings to be pure value-types, so we can copy the struct using simple struct assignment. If we also supported dynamic strings, we’d need a function to do the copying. For configuration data though, any string would probably best be expressed as a statically-sized
chararray in the struct, which would be fine.Note how the fact that the GUI module only knows where each value lives expressed as an offset allows us to provide the dialog function with a temporary on-stack copy. Had we instead set up the GUI module with direct pointers to each field, this would not be possible which would be far less flexible.