0

I have been looking tor sources, and i found a macro which is defined like so :

#define STRUCT_OFFSET(tp, member) \
   ((off_t) (((char*)&((tp*)0)->member)-(char*)0))

I looked up the off_t and it is just typedef for long, so it is the basic length of the pointer variable in the end. But what with this conversion? ((char*)&((tp*)0)

What does this even suppose to mean, why is there a zero? Also how does this part even works out (char*)0 , casting a zero (NULL) to the pointer to (NULL)? Suppose it if i do without a macro, i cant just do someting like int offset = &MyStruct::some_member; Is this possible to do without macro?

Vlad
  • 369
  • 4
  • 16
  • 3
    Don't use that macro, use the compiler-supplied `offsetof()`. – EOF Aug 09 '16 at 11:33
  • @EOF i curious, what does this part suppose to achieve `-(char*)0)` substracting a zero pointer? – Vlad Aug 09 '16 at 11:39
  • It achieves undefined behavior. – EOF Aug 09 '16 at 11:40
  • 1
    @yasofiz - Yes it is using null pointers and is illegal to use (undefined behavior). *However*, for a specific compiler it might be implementation defined and actually work. That's why it just *might* be used in the `offsetof` macro of the compiler's standard library. – Bo Persson Aug 09 '16 at 11:42
  • @BoPersson let me check if i understood, so on some compilers this code will take the structure, and the virtual address in program at offset 0. On some compilers the structure is getting mapped to that address, and the `&((tp*)0)->member);` will get the offset of a member, from the base zero address, withoud dereferencing the member itself? – Vlad Aug 09 '16 at 11:46
  • 1
    @yasofiz: On conforming implementations, the code may take the value of elephant, subtract the kitchen sink, format the harddisks and return a volleyball. – EOF Aug 09 '16 at 11:50
  • @EOF yes right... Was just strange to me too see something like that for first time. This macro is used to allocate a space for structure, i was thinking, why they don't just use `sizeof`.. – Vlad Aug 09 '16 at 11:54
  • Well, `offsetof` is obviously the wrong operator to allocate space for anything. I suspect you may not learn much of value from whatever code used this. – EOF Aug 09 '16 at 11:58
  • 1
    @yasofiz - Some code in the standard library might **not** be conforming to the language standard. It can be so, because it is only required to work with its companion compiler. The guys writing the library can make a deal with the compiler team to make it work. Sometimes this results in a magic function `__builtin_offsetof()`, sometimes a guarantee that `&*pointer` will result in `pointer` even for NULL. [`offsetof`](http://en.cppreference.com/w/cpp/types/offsetof) in particular is tricky, because it cannot be written "properly". It needs some support from the compiler. – Bo Persson Aug 09 '16 at 11:58
  • @BoPersson: `&*(char*)NULL` is well-defined. `&((char*)NULL)->foo` is not. – EOF Aug 09 '16 at 12:06

0 Answers0