Paul
Paul

Reputation: 331

How to calculate the size of a data member in a structure?

I am unable to understand how the size_1 variable calculates the size of the data member name. Could someone explain (((struct cheese_msgbuf*)0)->name); what this line means and does?

#include<stdio.h>
struct cheese_msgbuf {
    long mtype;
    char name[20];
};

int main() {
    /* calculate the size of the data to send: */
    struct cheese_msgbuf mbuf;
    int size;
    int size_1;

    size = sizeof(mbuf.name);
    printf("Using just sizeof operator: %d\n", size);

    /* Or, without a declared variable: */
    size_1 = sizeof(((struct cheese_msgbuf*)0)->name);
    printf("Using pointer: %d\n", size_1);
}

Upvotes: 2

Views: 484

Answers (3)

Eric Postpischil
Eric Postpischil

Reputation: 224546

If you had a pointer p that pointed to struct cheese_msgbuf, you could get the size of the name member with sizeof p->name.

This code does not have such a pointer, so it constructs one by casting 0 to the type struct cheese_msgbuf *. The result is a null pointer.

In code that is executed, it would be improper to evaluate p->name when p is a null pointer. In many C implementations, it would generate an exception, and it is not defined by the C standard.

However, the sizeof operator does not evaluate its operand in this situation. It is a compile-time operation that produces the size of the operand based on its type, not upon any actual evaluation of the operand. Since the nominal type of the expression ((struct cheese_msgbuf *) 0)->name is char [20], the expression sizeof ((struct cheese_msgbuf *) 0)->name produces 20.

(If the operand of sizeof is a variable length array, the operand is evaluated. Otherwise, the operand is not evaluated.)

Upvotes: 3

AdamF
AdamF

Reputation: 2950

Casting the NULL pointer

you can look at this code snippet (from your code above):

/* Or, without a declared variable: */
size_1 = sizeof(((struct cheese_msgbuf*)0)->name);
printf("Using pointer: %d\n", size_1);

This trick is known in c programming as casting the NULL ptr. we can look at null poiters like: (void*)0 and in the same way we can cast them to our own defined types like your struct cheese_msgbuf type.

compiler helps you to get the sizeof struct cheese_msgbuf data member name, like below:

struct cheese_msgbuf* compiler_temp_pointer = ((struct cheese_msgbuf*)0);
size_t size = sizeof(compiler_temp_pointer->name);

hope that this clear things for you

Upvotes: 2

Roberto Caboni
Roberto Caboni

Reputation: 7490

As you probably know, sizeof is an operator that returns the size of a specific C symbol. It either requires a variable name or a type; if the variable name is an array name, it returns the size in bytes of the whole array.

But there's not a "direct" way to get the size of a structure field, so here it is the trick you found (I have to say that your code is quite self explanatory):

/* Or, without a declared variable: */
size_1 = sizeof(((struct cheese_msgbuf*)0)->name);
  1. We build a pointer to the structure in which our field is defined: ((struct cheese_msgbuf*)0). We just cast the address 0; we don't need it to be a valid address, we just need to tell the compiler to interpret it as a pointer to (struct cheese_msgbuf*)
  2. We access the field we need: the char array name. We do it just accessing the field in the same way we access it when we have a "real" variable, such as var->name.
    In this case we just access ((struct cheese_msgbuf*)0)->name
  3. We pass it to the sizeof operator: sizeof(((struct cheese_msgbuf*)0)->name). It will be resolved as 20

Upvotes: 3

Related Questions