Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A friend of mine's showed me this in a code he used for programming an educational operating system. If you have a pointer to a member of a struct, with the macro container_of you can retrieve a pointer to the enclosing struct.

  /* Return the offset of 'member' relative to the beginning of a struct type */
  #define offsetof(type, member)  ((size_t) (&((type*)0)->member))
  
  #define container_of(ptr, type, member) \
   ((type *)((char *)(ptr) - offsetof(type, member)))


No need to define offsetof, it’s part of <stddef.h>

Still interesting to see the trick behind it tho.


It’s added to the standard because macro version has undefined behavior. (yet it still works on any compiler without a problem)


I was about to ask if it was legal to dereference a null pointer and then take the address of it... I presume it is not, but I'm surprised compilers don't complain at compilation time.


Dereferencing a null pointer and then immediately "undoing" it by taking its address is actually legal, I believe. I think the undefined behavior here is the member access instead of the magic sequence &* which is supposed to cancel out.


It is used in production os like linux kernel, mostly in intrusive data structures.


wow that is cool, do you have any pointers (no pun intended) for usage of this technique in practical terms?


This is used by the Ganesha project (userspace NFS server). Look for the symbol "container_of" and usages of it in https://github.com/nfs-ganesha/nfs-ganesha/ (disclaimer: I'm a minor contributor).

The way it's used is that Ganesha supports defining of alternate filesystem backends and serving them as NFS shares. Handles to objects (e.g. files) would exist as pointers which live inside the struct of the backend's handle struct. i.e.:

  struct my_file_data {
    struct ganesha_file_data {
      // generic data
    };

    // data specific to my module
  };
The "my" module would take pointers to ganesha_file_data when the NFS core code calls it. The "my" module then uses container_of to convert ganesha_file_data ptr to my_file_data ptr.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: