Reputation: 331
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
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
Reputation: 2950
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
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);
((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*)
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
.((struct cheese_msgbuf*)0)->name
sizeof
operator: sizeof(((struct cheese_msgbuf*)0)->name)
. It will be resolved as 20Upvotes: 3