By Wael

Last updated :

Posted :

What is the sizeof operator in c ?

The sizeof operator returns the size of an expression or of an object type in c . The value returned by the sizeof operator is of type size_t , and its unit is byte . This article will explain what is the sizeof operator , what is its return type and it will give examples of how to use it and where it can be applied .

sizeof(object type) , sizeof expression , sizeof(expression)
Table of contents What is the sizeof operator in c ? What is the value returned by the sizeof operator ? Using the sizeof operator with an object type Using sizeof with structures Using sizeof with unions Using sizeof with arrays Using sizeof with pointers Using the sizeof operator with an expression Where the sizeof operator cannot be applied ?

1- What is the sizeof operator in c ?

The sizeof operator returns the size of an expression or of an object type in c .

sizeof(Type)
/*
    When using sizeof with an object type 
    such as an int , the parenthesis () 
    must be used .
*/


sizeof expression
sizeof(expression)
/*
   When the sizeof operator is used
   with an expression , the parenthesis () 
   can or  cannot be used . 
*/

2- What is the value returned by the sizeof operator ?

The c standard defines that the sizeof operator must return a value of 1 byte , when used with the char type . It defines that the size of a char , unsigned char and signed char as 1 byte.

#include <stdio.h>
#include <limits.h>


int main(int argc, char const *argv[])
{
    printf("sizeof(char) is : %lu", sizeof(char));
    // output : sizeof(char) is : 1
    
    return 0;
}

The c standard defines that the minimum number of bits that a char can have is 8 , an implementation can define a larger size . The size of a char in bits for a given implementation can be found in the limits.h header , defined as part of the c89 standard . It is defined using the macro CHAR_BIT .

#define CHAR_BIT        8

For example in this c implementation , the size of a char in bits is 8 bits .

For other types , such as the int or float types , the sizeof operator , also returns the size of the type in bytes . To get the size of of a type in bits , the size returned by the sizeof operator , must be multiplied by the number of bits in a char .

#include <stdio.h>
/*
    include the stdio.h header in 
    order to use printf , to print 
    formatted strings .
*/


#include <limits.h>
/*
    include the limits.h header 
    to use CHAR_BIT , which defines 
    the number of bits that the
    char type can have . 
*/


int main(int argc, char const *argv[])
{
    printf("sizeof(int) is : %lu bytes\n", sizeof(int));
    // output : sizeof(int) is : 4 bytes

    printf("size of int in bits is : %lu bits\n", sizeof(int) * CHAR_BIT);
    // output : size of int in bits is : 32 bits

    return 0;
}

The type of the value returned by the sizeof operator , is size_t . It is defined in the stddef.h header which is defined as part of the c89 standard .

size_t is an unsigned integer type . It can hold the value returned by the sizeof operator . It has a min value of 0 , and a max value of the largest value that can be returned by the sizeof operator . Usually size_t is defined to be an unsigned int or an unsigned long .

typedef unsigned long size_t;

// or

typedef unsigned int size_t;

3- Using the sizeof operator with an object type

sizeof(object Type)

Object types in c are :

#include <stdio.h>
/*
    include the stdio header to 
    use the printf function .
*/


#include <stdatomic.h>
/*
    include the stdatomic header
    to access the atomic types .
*/


enum Binary
{
    zero,
    one
};
/*
    define the enum Binary ,
    an enum is an integer of
    the type int .
*/


struct Boolean
{
    char _cBool;
    unsigned char _iBool;
} true = {'T', 1}, false = {'F', 0};
/* 
    define a Boolean structure .
    the Boolean structure has
    a char representation and an int 
    representation for a boolean .
    Two variables were  initialized 
    from this structure , true and 
    false .
*/


union BooleanOrBinary {
    enum Binary binary;
    struct Boolean boolean;
};
/* 
    Define a union BooleanOrBinary , to 
    store a boolean value , 
    as either of type struct Boolean
    or as of type enum Binary .
*/



/*
    Print the sizeof object types 
    on a given machine .
    The sizeof a char is always 1 . 
    The sizeof object types are a
    multiple of the sizeof a char .
    The size of objects types 
    might vary from one machine 
    to another .
*/
int main()
{
    printf("sizeof(char) is : %lu byte\n", sizeof(char));
    // output : sizeof(char) is : 1 byte

    printf("sizeof(short) is : %lu byte\n", sizeof(short));
    // output : sizeof(short) is : 2 byte

    printf("sizeof(int) is : %lu byte\n", sizeof(int));
    // output : sizeof(int) is : 4 byte

    printf("sizeof(long int) is : %lu byte\n", sizeof(long int));
    // output : sizeof(long int) is : 8 byte

    printf("sizeof(long long int) is : %lu byte\n", sizeof(long long int));
    // output : sizeof(long long int) is : 8 byte

    printf("sizeof(float) is : %lu byte\n", sizeof(float));
    // output : sizeof(float) is : 4 byte

    printf("sizeof(double) is : %lu byte\n", sizeof(double));
    // output : sizeof(double) is : 8 byte

    printf("sizeof(long double) is : %lu byte\n", sizeof(long double));
    // output : sizeof(long double) is : 16 byte

    printf("sizeof(enum  binary ) is : %lu byte\n", sizeof(enum Binary));
    // output : sizeof(enum  binary ) is : 4 byte

    printf("sizeof(struct  Boolean ) is : %lu byte\n", sizeof(struct Boolean));
    // output : sizeof(struct  Boolean ) is : 2 byte
    // it is the size of two chars

    printf("sizeof(union BooleanOrBinary ) is : %lu byte\n", sizeof(union BooleanOrBinary));
    // output : sizeof(union BooleanOrBinary ) is : 4 byte

    printf("sizeof(void *) is %lu byte\n", sizeof(void *));
    // output : sizeof(void *) is 8 byte

    printf("sizeof(int [1]) is : %lu byte\n", sizeof(int[1]));
    // output : sizeof(int [1]) is : 4 byte   
  
    printf("sizeof(atomic_int_fast32_t ) is : %lu byte\n", sizeof(atomic_int_fast32_t));
    // output : sizeof(atomic_int_fast32_t ) is : 4 byte
    
    return 0;
}

3.1- Using sizeof with 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 specified 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 .

#include <stdio.h>
/*
    include the stdio header 
    to use the printf 
    function .
*/


struct aPaddedStruct{
    char aChar;
    // aChar has a size of 1 
    int anInt; 
    // anInt has a size of 4 
    // bytes .
};
/*
    The size of aPaddedStruct is 8 
    instead of 5 , since the size of 
    the largest element in this struct
    is 4 bytes.
*/


int main(int argc , char const *argv[])
{
    printf("sizeof(struct aPaddedStruct) is : %lu", sizeof(struct aPaddedStruct));
    // sizeof(struct aPaddedStruct) is : 8
    
    return 0;
}

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

#include<stdio.h>
/*
    include the stdio header 
    to use the printf 
    function .
*/


struct aStruct{
    short aShort; 
    	// size of short is
    	// 2  bytes
    char aCharOne; 
    	// size of char is 1
    char aCharTwo; 
    	// size of char is 1
    int anIntArray[];
    	// anIntArray doesn't have a size 
    	// because it doesn't define the 
    	// number of elements it has . 

};
// size of aStruct is  4


int main(int argc, char const *argv[]){
    printf("sizeof(aStruct) is : %lu " , sizeof(struct aStruct));
    //output : sizeof(aStruct) is : 4
    
    return 0;
}

3.2- Using sizeof with unions

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

#include<stdio.h>
/*
    include the stdio header 
    to use the printf 
    function .
*/

union aUnion{
    char aChar; 
    	// size of char is 1
    int anInt; 
    	// size of int  is 4 
    long double aLongDouble; 
    	//size of long double 
    	// is 16
};
/*
    union aUnion will have the 
    size of its largest element 
    , this is a long double
    and it has a size of 16 .
*/


int main(int argc, char const *argv[]){
    printf("sizeof(union aUnion) is : %lu" ,sizeof(union aUnion));
    // output : sizeof(union aUnion) is : 16 

    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 .

#include <stdio.h>
/*
    include the stdio header 
    to use the printf 
    function .
*/


struct _aStruct{
    int anIntOne; 
    	// size of an int is 4
    short aShort; 
    	// size of a short is 2
    int anIntTwo; 
    	// size of an int is 4
};/*
    The size of _aStruct  is 12 
    since it is padded to the size of the 
    largest element which is an int .
  */


union aUnion{
    struct _aStruct aStruct;
    	 // size of struct _aStruct 12
    long aLong; 
    	// size of long is 8
};
/*
    The size of the largest element  
    in this union is long . The 
    union is padded to the size of 
    its largest element.
    It has a size of 16 . 
*/


int main(int argc, char const *argv[]){
    printf("the size of aUnion is : ");
    printf("%lu\n" , sizeof(union aUnion));
    //output : the size of aUnion is : 16 
    
    return 0;
}

3.3- Using sizeof with arrays

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

#include <stdio.h>
/*
    include the stdio header
    to use the printf
    function . 
*/


int main(int argc, char const *argv[]){

    int anIntArray[22];
    /*  
        anIntArray has a size 
        of the size of 
        the int type  multiplied by 22 . 
        so it has a size of 4 * 22 = 88
        bytes .
    */

    printf("sizeof(anIntArray) is : %lu\n" , sizeof(anIntArray));
    // sizeof(anIntArray) is : 88

    char aCharArray[3];
    /*  
        aCharArray has a size 
        of the size of 
        the char type  multiplied by 3 . 
        so it has a size of 1 * 3 = 3
        bytes .
    */
    
    printf("sizeof(aCharArray) is : %lu\n" , sizeof(aCharArray));
    // output : sizeof(aCharArray) is : 3 
    
    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 .

#include <stdio.h>
/*
    include the stdio header
    to use the printf
    function .
*/


int main(int argc, char const *argv[]){

    short aShortArray[4];
    /* 
        aShortArray has a size of 
        the size of the short 
        type multiplied by 
        4 , so it has a size
         of 2 * 4 = 8
    */

   printf("Number of elements in the array is : ");
   printf("%lu\n",sizeof(aShortArray) / sizeof(aShortArray[0]));
   // sizeof(aShortArray) is equal to sizeof(short) * 4
   // sizeof(aShortArray[0]) is equal to sizeof(short)
   // hence sizeof(aShortArray) / sizeof(aShortArray[0]) = number of elements in the array
   // output : Number of elements in the array is : 4 
   
   return 0;
}

3.4- Using sizeof with 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 bit machine a pointer has a size of 32 bits , and on a 64 bit machine a pointer has a size of 64 bits

#include <stdio.h>
/*
    include the stdio header 
    to use the printf 
    function .
*/


int main(int argc, char const *argv[])
{
    printf("sizeof(void *) is %lu\n", sizeof(void *));
    // output : sizeof(void *) is 8

    printf("sizeof(char *) is %lu\n", sizeof(char *));
    // output : sizeof(char *) is 8
    
    return 0;
}

4- Using the sizeof operator with an expression

sizeof expression 
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 .

#include <stdio.h>
/*
    include the stdio header 
    to use the printf 
    function .
*/


int sum(int x, int y)
{
/*
    return the sum of x and y
*/
    return x + y;
}


int main(int argc, char const *argv[])
{

    int anInt = 1;
    printf("sizeof anInt is : %lu \n", sizeof anInt);
    // output : sizeof anInt is : 4

    double aDouble = 3.0;
    printf("sizeof aDouble is : %lu \n", sizeof aDouble);
    // output : sizeof aDouble is : 8

    printf("sizeof (aDouble + anInt) is : %lu \n", sizeof(aDouble + anInt));
    // output : sizeof (aDouble + anInt) is : 8

    printf("sizeof (3.0f + 1) is : %lu \n", sizeof(3.0f + 1));
    // output : sizeof (3.0 + 1) is : 4
    // 3.0f is a float 
    // 3.0f + 1 = 4.0f 
    // 4.0f is a float 
    // sizeof(float) is 4
    
    printf("sizeof sum(1,5) is : %lu \n", sizeof sum(1, 5));
    // output : sizeof sum(1,5) is : 4

    printf("sizeof 100 is : %lu \n", sizeof 100);
    // output : sizeof 100 is : 4 
    
    return 0;
}

5- Where the sizeof operator cannot be applied

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 .

struct incompleteTypeStruct;
/* 
    struct incompleteTypeStruct is declared 
    but is not  yet defined , as such it 
    is an incomplete type .
*/

enum incompleteTypeEnum;
/* 
    enum incompleteTypeEnum is declared 
    but is not yet defined as such its an 
    incomplete type .
*/

int anIntarray[];
/* 
    anIntarray size is not defined as 
    such it is an incomplete type .
*/

int main(int argc, char const *argv[])
{
    sizeof(struct incompleteTypeStruct);
    sizeof(enum incompleteTypeEnum);
    sizeof(anIntarray);
    sizeof(void);
    /*
        These statements will cause 
        an error since they are trying to
        get the size of incomplete types .
    */
    
    return 0;
}