cstructoffsetof

Why is the offsetof macro necessary?


I am new to the C language and just learned about structs and pointers.

My question is related to the offsetof macro I recently saw. I know how it works and the logic behind that.

In the <stddef.h> file the definition is as follows:

#define offsetof(type,member) ((unsigned long) &(((type*)0)->member))

My question is, if I have a struct as shown below:

struct test {
    int field1:
    int field2:
};

struct test var;

Why cannot I directly get the address of field2 as:

char * p = (char *)&var;
char *addressofField2 = p + sizeof(int);

Rather than writing something like this

field2Offset = offsetof (struct test, field2);

and then adding offset value to var's starting address?

Is there any difference? Is using offsetof more efficient?


Solution

  • The C compiler will often add extra padding bits or bytes between members of a struct in order to improve efficiency and keep integers word-aligned (which in some architectures is required to avoid bus errors and in some architectures is required to avoid efficiency problems). For example, in many compilers, if you have this struct:

    struct ImLikelyPadded {
        int x;
        char y;
        int z;
    };
    

    you might find that sizeof(struct ImLikelyPadded) is 12, not 9, because the compiler will insert three extra padding bytes between the end of the one-byte char y and the word-sized int z. This is why offsetof is so useful - it lets you determine where things really are even factoring in padding bytes and is highly portable.