Reputation: 795
Please explain the OP for below code snippet :
int *a="";
char *b=NULL;
float *c='\0' ;
printf(" %d",sizeof(a[1])); // prints 4
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4
Compiler interprets a[1] as *(a+1) , so a has some address , now it steps 4 bytes ahead , then it will have some garbage value there so how is the OP 4 bytes , even if I do a[0] , still it prints 4 , although it is an empty string , so how come its size is 4 bytes ?
Here we are finding out the size of the variable the pointer is pointing to , so if I say size of a[1] , it means size of *(a+1), Now a has the address of a string constant which is an empty string , after I do +1 to that address it moves 4 bytes ahead , now its at some new address , now how do we know the size of this value , it can be an integer , a character or a float , anything , so how to reach to a conclusion for this ?
Upvotes: 2
Views: 84
Reputation: 310980
The sizeof operator does not evaluate its operand except one case.
From the C Standard (6.5.3.4 The sizeof and alignof operators)
2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
In this code snippet
int *a="";
char *b=NULL;
float *c='\0' ;
printf(" %d",sizeof(a[1])); // prints 4
printf(" %d",sizeof(b[1])); // prints 1
printf(" %d",sizeof(c[1])); // prints 4
the type of the expression a[1]
is int
, the type of the expression b[1]
is char
and the type of the expression c[1]
is float
.
So the printf
calls output correspondingly 4
, 1
, 4
.
However the format specifiers in the calls are specified incorrectly. Instead of "%d"
there must be "%zu"
because the type of the value returned by the sizeof
operator is size_t
.
From the same section of the C Standard
5 The value of the result of both operators is implementation-defined, and its type (an unsigned integer type) is size_t, defined in
<stddef.h>
(and other headers).
Upvotes: 4
Reputation: 33864
sizeof
operator happens at compilation (except for VLA's). It is looking at the type of an expression, not the actual data so even something like this will work:
sizeof(((float *)NULL)[1])
and give you the size of a float. Which on your system is 4 bytes.
Even though this looks super bad, it is all well defined, since no dereference ever actually occurs. This is all operations on type information at compile time.
Upvotes: 2
Reputation: 399823
This is all done statically, i.e. no dereferencing is happening at runtime. This is how the sizeof
operator works, unless you use variable-length arrays (VLAs), then it must do work at runtime.
Which is why you can get away with sizeof
:ing through a NULL
pointer, and other things.
You should still be getting trouble for
int *a = "";
which makes no sense. I really dislike the c
initializer too, but at least that makes sense.
Upvotes: 3
Reputation: 8142
sizeof()
is based on the data type, so whilst it's getting the sizes outside the bounds of memory allocated to your variables, it doesn't matter as it's worked out at compile time rather than run time.
Upvotes: 1