Friday, March 28, 2014

Face-off with sizeof()



sizeof : Brief
The unary operator sizeof is used to calculate the size of any datatype, measured in the number of bytes required to represent the type. The result of sizeof is the size of the type of the expression or parenthesized type-specifier that it precedes, and has an unsigned integral type which is usually denoted by size_t ( From Wiki ).
The sizeof() operator behaves differently in comparison with other operators. In this blog let us call out some of the uniqueness of this operator by taking two real time programming examples. The first one is about compile time behavior and second one is during run time behavior.
Case 1: Compile time behavior 
To start with, let us consider the simple code (Fig 1 below):



Fig 1: Sample program to demonstrate the sizeof() operator


Can you guess what would be the output of the above mentioned program? By first look anybody would say it as 4 (Assuming the sizeof(int) is 4 bytes) & 11. But, when I run the program in my system, it is showing 4 & 10 (ref: Fig 2 below)

Fig 2: Output
Why are we getting the value of variable ‘i’ as 10 instead of 11? Here is the reason:
  1. Sizeof operator is the only operator in C, which is evaluated at the compile time. Where sizeof(i++) is replaced the value 4.
  2. One can observe this, shown in the figure given below(inside the box), which contains the assembly code equivalent to the statement in C.



Fig 3: Assembly code generated by the compiler.

Note:
To obtain the assembly code as shown in Fig 3, follow the below given steps.
+ gcc -g filename.c ( In our case sizeof_run.c)
+ objdump -S output_file ( In our case a.out)


From the above figure, one can see that the sizeof() is completely evaluated at the compile time. And the whole sizeof(i++) is replaced by the constant value 4. so, there is no assembly code for i++ at all, which is to be evaluated at the run-time.
Case 2: Run- time behavior
As, I told before Sizeof() operator is the only operator in C, which is evaluated at the compile time.But, there is an exception for this in C99 standards, for variable length arrays.
To start with, Let us consider an code snippet shown below,


Fig 4: Code containing variable length array


Let us see the output, when the above code is compiled & run ( shown in fig 5 below)


Fig 5: Output of the sizeof_run.c


From the above output it is very clear that sizeof() operator is evaluated at the run-time, One can observe the equivalent assembly code generated by the compiler as shown in the Fig 6 given below.
Also, see the difference between the assembly code in the Fig 3 & Fig 6.

Fig 6: Assembly code generated by the compiler, for variable length array.


According to the C99 standards, the sizeof() operator yields the size (in integer bytes) of its operand, which may be an expression or the parenthesized name of a type. If the type of the operand is a variable length array type, the operand is evaluated at run time; otherwise, the operand is not evaluated and the result is an integer constant, during the compile time itself.


In the next blog we will see,
1. Need of sizeof().
2. Cases where sizeof() will not work.
3. How sizeof() is different from function call.

3 comments:

  1. Good introduction to sizeof's compile and run time behavior. Thanks satya.

    ReplyDelete
  2. Nice to see your comment Mubeen. Keep reading them offline and share your valuable comments as we publish more.

    ReplyDelete