sizeof operator in c

Listen to the article
1.0x
00:00

What is the sizeof operator?

The sizeof operator, returns the size of an expression, or of an object type in C. An expression is for example 1 + 2, an object is any region of memory, and a type is for example int. The value returned by the sizeof operator, is of type size_t, and its unit is byte.

  1. sizeof( Type )
  2. /*  When using sizeof with an object type
  3.     such as an int , the parenthesis ()
  4.     must be used .*/
  5.  
  6. sizeof expression
  7. sizeof( expression )
  8. /* When the sizeof operator is used
  9.    with an expression, the parenthesis ()
  10.    can or cannot be used .*/

size_t is an unsigned integer type, which is defined in the stddef.h header. It can hold any value returned by the sizeof operator, and has a min value of 0, and a max value of the largest value, that can be returned by the sizeof operator. size_t can for example be defined as:

  1. typedef unsigned long size_t;

The sizeof operator returns 1, meaning 1 byte, when used with the char, unsigned char, or signed char types.

  1. #include <stdio.h>
  2.  
  3. int main( int argc, char * argv [ ] ){
  4.     printf( "sizeof( char ) is: %lu\n", sizeof( char ) );
  5.     /*output:
  6.          sizeof( char ) is: 1 */
  7.     return 0;}

The number of bits in a char, is defined in the limits.h header, using the macro CHAR_BIT.

  1. #define CHAR_BIT        8

The following example illustrates, how to get the number of bits for other types.

  1. #include <stdio.h>
  2. /*  include the stdio.h header, in
  3.     order to use printf, to print
  4.     formatted strings .*/
  5.  
  6. #include <limits.h>
  7. /*  include the limits.h header,
  8.     to use CHAR_BIT, which defines
  9.     the number of bits, that the
  10.     char type can have .*/

  11. int main( int argc, char * argv[ ] )
  12. {
  13.     printf( "sizeof( int ) is: %lu bytes\n", sizeof( int ));
  14.     /* output:
  15.            sizeof( int ) is: 4 bytes .*/
  16.  
  17.     printf( "size of int in bits is: %lu bits\n", sizeof( int ) * CHAR_BIT );
  18.     /* output:
  19.            size of int in bits is: 32 bits .*/
  20.     return 0;}

sizeof and structures

When sizeof is used with a structure, it returns the size of the elements in this structure, with any padding. Padding will happen, when the size of the structure is not a multiple of the size of the largest element in this structure.

A structure is padded with bits, that don’t have any specific value, till it has a size which is a multiple of the largest element in this structure. Padding happens to have faster access to the structure elements, and because sometimes some cpu architecture don’t support access to non aligned memory.

  1. #include <stdio.h>
  2. /*  include the stdio header
  3.     to use the printf
  4.     function .*/
  5.  
  6. struct aPaddedStruct{
  7.     char aChar;
  8.     // aChar has a size of 1
  9.     int anInt;
  10.     /* anInt has a size of 4
  11.        bytes .*/ };
  12.     /*  The size of aPaddedStruct is 8
  13.     instead of 5, since the size of
  14.     the largest element in this struct
  15.     is 4 bytes .*/
  16.  
  17. int main( int argc , char * argv[ ] ){
  18.     printf( "sizeof( struct aPaddedStruct ) is: %lu",
  19.             sizeof( struct aPaddedStruct ));
  20.     // sizeof( struct aPaddedStruct ) is: 8
  21.     return 0; }

If the last element of a structure is an array, which size is not defined, then sizeof will return the size of the structure, without the array size.

  1. #include<stdio.h>
  2. /*  include the stdio header,
  3.     to use the printf
  4.     function .*/
  5.  
  6. struct aStruct{
  7.     short aShort;
  8.         /* size of short is
  9.            2  bytes .*/
  10.     char aCharOne;
  11.         // size of char is 1
  12.     char aCharTwo;
  13.         // size of char is 1
  14.     int anIntArray[ ];
  15.         /* anIntArray doesn't have a size,
  16.            because it does not define the
  17.            number of elements it has.*/ };
  18.     // size of aStruct is  4
  19.  
  20. int main( int argc, char *argv[ ] ){
  21.     printf( "sizeof( aStruct ) is: %lu", sizeof( struct aStruct ));
  22.     /*output :
  23.           sizeof( aStruct ) is: 4 */
  24.     return 0; }

sizeof and unions

sizeof returns the size of the largest element in a union.

  1. #include <stdio.h>
  2. /*  include the stdio header,
  3.     to use the printf
  4.     function .*/
  5.  
  6. union aUnion{
  7.     char aChar;
  8.         // size of char is 1
  9.     int anInt;
  10.         // size of int  is 4
  11.     long double aLongDouble;
  12.         /*size of long double
  13.           is 16 .*/ };
  14.     /* union aUnion will have the
  15.        size of its largest element,
  16.        it is aLongDouble, which is
  17.        a long double, as such
  18.        it has a size of 16 .*/
  19.  
  20.  
  21. int main( int argc, char * argv[ ] ){
  22.     printf( "sizeof( union aUnion ) is: %lu" ,sizeof( union aUnion ));
  23.     /* output:
  24.            sizeof( union aUnion ) is: 16 .*/
  25.     return 0;}

A compiler might add padding to a union, so that its size, will be a multiple of the size of the largest element, in this union. This is used to allow faster access, or because some cpu architecture, don’t allow access to non aligned boundaries.

  1. #include <stdio.h>
  2. /*  include the stdio header,
  3.     to use the printf
  4.     function .*/
  5.  
  6. struct _aStruct{
  7.     int anIntOne;
  8.         // size of an int is 4
  9.     short aShort;
  10.         // size of a short is 2
  11.     int anIntTwo;
  12.         /* size of an int is 4 .*/ };
  13.     /* The size of _aStruct  is 12,
  14.        since it is padded to the size of its
  15.        largest element, which is an int .*/

  16. union aUnion{
  17.     struct _aStruct aStruct;
  18.          // size of struct _aStruct is 12
  19.     long aLong;
  20.         /* size of long is 8 .*/ };
  21.     /* The size of the largest element  
  22.        in this union is long. The
  23.        union is padded to the size of
  24.        its largest element, hence
  25.        it has a size of 16 .*/
  26.  
  27. int main( int argc, char * argv[ ] ){
  28.     printf( "The size of aUnion is: %lu\n",
  29.             sizeof( union aUnion ));
  30.     /*output:
  31.           the size of aUnion is: 16 */
  32.     return 0;}

sizeof and arrays

When using sizeof with an array, it will return the size of all the elements in the array.

  1. #include <stdio.h>
  2. /*  include the stdio header,
  3.     to use the printf
  4.     function .*/
  5.  
  6.  
  7. int main( int argc, char * argv[ ] ){
  8.  
  9.     int anIntArray[ 22 ];
  10.     /*  anIntArray has a size
  11.         of the size of
  12.         the int type, multiplied by 22.
  13.         so it has a size of 4 * 22 = 88
  14.         bytes .*/
  15.  
  16.     printf( "sizeof( anIntArray ) is: %lu\n" , sizeof( anIntArray ));
  17.     // sizeof( anIntArray ) is: 88
  18.  
  19.     char aCharArray[ 3 ];
  20.     /*  aCharArray has a size
  21.         of the size of
  22.         the char type, multiplied by 3 .
  23.         so it has a size of 1 * 3 = 3
  24.         bytes .*/
  25.    
  26.     printf( "sizeof( aCharArray ) is: %lu\n" , sizeof( aCharArray ));
  27.     // sizeof( aCharArray ) is: 3
  28.    
  29.     return 0;}

sizeof can be used to calculate the number of elements in an array, by dividing the size of the array, by the size of an element in the array.

  1. #include <stdio.h>
  2. /*  include the stdio header,
  3.     to use the printf
  4.     function .*/
  5.  
  6. int main( int argc, char * argv[ ] ){
  7.  
  8.     short aShortArray[ 4 ];
  9.     /*  aShortArray has a size of
  10.         the size of the short
  11.         type, multiplied by
  12.         4, so it has a size
  13.          of 2 * 4 = 8 .*/
  14.  
  15.    printf( "Number of elements in the array is: %lu\n",
  16.            sizeof( aShortArray ) / sizeof( aShortArray[ 0 ] ));
  17.    /* sizeof( aShortArray ) is equal to sizeof( short ) * 4
  18.       sizeof( aShortArray[ 0 ] ) is equal to sizeof( short )
  19.       hence sizeof( aShortArray ) / sizeof( aShortArray[ 0 ] ) = number of elements in the array
  20.       output:
  21.           Number of elements in the array is: 4 .*/

  22.    return 0;}

sizeof and pointers

A pointer is simply an address which is stored in memory, as such it has a size. The sizeof operator, can be used to get the size of a pointer. There is no defined size of a pointer in C, it is defined by the implementation, usually on a 32 bits machine, a pointer has a size of 32 bits, and on a 64 bits machine, a pointer has a size of 64 bits.

  1. #include <stdio.h>
  2. /*  include the stdio header,
  3.     to use the printf
  4.     function .*/
  5.  
  6. int main(int argc, char * argv[ ]){
  7.     printf("sizeof( void * ) is %lu\n", sizeof (void * ));
  8.     // sizeof( void * ) is 8
  9.  
  10.     printf( "sizeof( char * ) is %lu\n", sizeof( char * ));
  11.     // sizeof( char * ) is 8
  12.    
  13.     return 0;}

sizeof and other object types

An object is just a memory region, so it has an allocated size. The object types in C are:

  • integer types, such as int, short, enum…
  • floating types, such as float, double, long double.
  • structures.
  • unions.
  • arrays.
  • pointers.
  • atomic types.
  1. #include <stdio.h>
  2. /*  include the stdio header, to
  3.     use the printf function .*/
  4.  
  5. #include <stdatomic.h>
  6. /*  include the stdatomic header,
  7.     to access the atomic types .*/
  8.  
  9. enum Binary{
  10.     zero,
  11.     one };
  12.     /*  define the enum Binary,
  13.         an enum is an integer of
  14.         the type int .*/
  15.  
  16. struct Boolean{
  17.     char _cBool;
  18.     unsigned char _iBool;
  19.   } true = {'T', 1}, false = {'F', 0};
  20.   /* define a Boolean structure.
  21.      the Boolean structure defines that
  22.      a boolean, has a char and an int
  23.      representation.
  24.      Two variables were initialized
  25.      from this structure, true and
  26.      false .*/
  27.  
  28.  
  29. union BooleanOrBinary {
  30.     enum Binary binary;
  31.     struct Boolean boolean;};
  32.     /* Define a union BooleanOrBinary, to
  33.        store a boolean value ,
  34.        as either of type struct Boolean
  35.        or as of type enum Binary .*/

  36. /*  Print the sizeof object types
  37.     on a given machine.
  38.     The sizeof a char is always 1.
  39.     The sizeof object types are a
  40.     multiple of the sizeof a char.
  41.     The size of objects types
  42.     might vary from one machine
  43.     to another .*/

  44. int main( ){
  45.     printf( "sizeof( char ) is : %lu byte\n", sizeof( char ));
  46.     // sizeof( char ) is: 1 byte
  47.  
  48.     printf( "sizeof( short ) is : %lu byte\n", sizeof( short ));
  49.     // sizeof( short ) is: 2 byte
  50.  
  51.     printf( "sizeof( int ) is: %lu byte\n", sizeof( int ));
  52.     // sizeof( int ) is: 4 byte
  53.  
  54.     printf("sizeof( long int ) is: %lu byte\n", sizeof( long int ));
  55.     // sizeof( long int ) is: 8 byte
  56.  
  57.     printf( "sizeof( long long int ) is: %lu byte\n", sizeof( long long int ));
  58.     // sizeof(long long int) is : 8 byte
  59.  
  60.     printf( "sizeof( float ) is: %lu byte\n", sizeof( float ));
  61.     // sizeof( float ) is: 4 byte
  62.  
  63.     printf( "sizeof( double ) is: %lu byte\n", sizeof( double ));
  64.     // sizeof( double ) is: 8 byte
  65.  
  66.     printf( "sizeof( long double ) is: %lu byte\n", sizeof( long double ));
  67.     // sizeof( long double ) is: 16 byte
  68.  
  69.     printf( "sizeof( enum  binary ) is: %lu byte\n", sizeof( enum Binary ));
  70.     // sizeof( enum  binary ) is: 4 byte
  71.  
  72.     printf( "sizeof( struct  Boolean ) is : %lu byte\n", sizeof( struct Boolean ));
  73.     // sizeof( struct  Boolean ) is: 2 byte
  74.  
  75.     printf( "sizeof( union BooleanOrBinary ) is: %lu byte\n",
  76.              sizeof( union BooleanOrBinary ));
  77.     // sizeof( union BooleanOrBinary ) is: 4 byte
  78.  
  79.     printf( "sizeof( void * ) is %lu byte\n", sizeof( void * ));
  80.     // sizeof( void * ) is 8 byte
  81.  
  82.     printf( "sizeof( int[ 1 ] ) is: %lu byte\n", sizeof( int[ 1 ] ));
  83.     // sizeof( int[ 1 ] ) is: 4 byte  
  84.  
  85.     printf( "sizeof( atomic_int_fast32_t ) is: %lu byte\n",
  86.             sizeof( atomic_int_fast32_t ));
  87.     // sizeof( atomic_int_fast32_t ) is: 4 byte
  88.     return 0; }

sizeof and expressions

  1. sizeof expression
  2. sizeof( expression )

An expression is simply a combination of operands and operators, whatever these operand or operators are. When using the sizeof operator with an expression, the parenthesis () can be used or skipped .

  1. #include <stdio.h>
  2. /*  include the stdio header,
  3.     to use the printf
  4.     function .*/
  5.  
  6.  
  7. int sum( int x, int y ){
  8.     /* return the sum of x and y */
  9.     return x + y; }
  10.  
  11.  
  12. int main( int argc, char * argv[ ] ){
  13.  
  14.     int anInt = 1;
  15.     printf( "sizeof anInt is: %lu \n", sizeof anInt );
  16.     // sizeof anInt is: 4
  17.  
  18.     double aDouble = 3.0;
  19.     printf( "sizeof aDouble is: %lu \n", sizeof aDouble );
  20.     // sizeof aDouble is: 8
  21.  
  22.     printf( "sizeof( aDouble + anInt ) is: %lu \n",
  23.             sizeof( aDouble + anInt ));
  24.     // sizeof( aDouble + anInt ) is: 8
  25.  
  26.     printf( "sizeof( 3.0f + 1 ) is: %lu \n", sizeof( 3.0f + 1 ));
  27.     /* 3.0f is a float
  28.        3.0f + 1 = 4.0f
  29.        4.0f is a float
  30.        sizeof( float ) is 4
  31.        Output:
  32.            sizeof (3.0 + 1) is: 4 .*/
  33.    
  34.     printf( "sizeof sum( 1, 5 ) is: %lu \n", sizeof sum( 1, 5 ));
  35.     // sizeof sum( 1, 5 ) is: 4
  36.  
  37.     printf( "sizeof 100 is: %lu \n", sizeof 100 );
  38.     // sizeof 100 is: 4
  39.    
  40.     return 0;}

sizeof cannot be applied?

The sizeof operator, cannot be applied to a non object type, such as a function, or to an incomplete type. An incomplete type, is a type which is declared but not yet defined, or a type which doesn’t have a size, such as the void type.

  1. struct incompleteTypeStruct;
  2. /*  struct incompleteTypeStruct is declared
  3.     but is not yet defined , as such it
  4.     is an incomplete type .*/
  5.  
  6. enum incompleteTypeEnum;
  7. /*  enum incompleteTypeEnum is declared
  8.     but is not yet defined, as such it is
  9.     an incomplete type .*/
  10.  
  11. int anIntarray[ ];
  12. /*  anIntarray size is not defined, as
  13.     such it is an incomplete type .*/
  14.  
  15. int main( int argc, char * argv[ ] ){
  16.     sizeof( struct incompleteTypeStruct );
  17.     sizeof( enum incompleteTypeEnum );
  18.     sizeof( anIntarray );
  19.     sizeof( void );
  20.     /*  These statements will cause
  21.         an error, since they are trying to
  22.         get the size of incomplete types .*/
  23.    
  24.     return 0;}