Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the C offsetof macro work? [duplicate]

Tags:

c

macros

offset

Possible Duplicate:
Why does this C code work?
How do you use offsetof() on a struct?

I read about this offsetof macro on the Internet, but it doesn't explain what it is used for.

#define offsetof(a,b) ((int)(&(((a*)(0))->b)))

What is it trying to do and what is the advantage of using it?

like image 706
Samuel Liew Avatar asked Oct 26 '11 01:10

Samuel Liew


People also ask

How does offsetof work?

The offsetof() macro is an ANSI -required macro that should be found in stddef. h. Simply put, the offsetof() macro returns the number of bytes of offset before a particular element of a struct or union. The declaration of the macro varies from vendor to vendor and depends upon the processor architecture.

What is offsetof is it a keyword function or macro what does it do?

The offsetof macro returns the offset in bytes of memberName from the beginning of the structure specified by structName as a value of type size_t. You can specify types with the struct keyword. offsetof is not a function and cannot be described using a C prototype.


1 Answers

R.. is correct in his answer to the second part of your question: this code is not advised when using a modern C compiler.

But to answer the first part of your question, what this is actually doing is:

(
  (int)(         // 4.
    &( (         // 3.
      (a*)(0)    // 1.
     )->b )      // 2.
  )
)

Working from the inside out, this is ...

  1. Casting the value zero to the struct pointer type a*
  2. Getting the struct field b of this (illegally placed) struct object
  3. Getting the address of this b field
  4. Casting the address to an int

Conceptually this is placing a struct object at memory address zero and then finding out at what the address of a particular field is. This could allow you to figure out the offsets in memory of each field in a struct so you could write your own serializers and deserializers to convert structs to and from byte arrays.

Of course if you would actually dereference a zero pointer your program would crash, but actually everything happens in the compiler and no actual zero pointer is dereferenced at runtime.

In most of the original systems that C ran on the size of an int was 32 bits and was the same as a pointer, so this actually worked.

like image 135
Eamonn O'Brien-Strain Avatar answered Nov 16 '22 00:11

Eamonn O'Brien-Strain