Radha Gogia
Radha Gogia

Reputation: 795

How does sizeof operator behaves in below code snippet?

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

Answers (4)

Vlad from Moscow
Vlad from Moscow

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

Fantastic Mr Fox
Fantastic Mr Fox

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.

Live example

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

unwind
unwind

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

Chris Turner
Chris Turner

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

Related Questions