What does sizeof Operator Return in C?

This C Tutorial explains sizeof Operator in C Language and the Type of Value Returned by the operator.

The sizeof operator returns the size, in bytes, of its operand. Recall that a C byte is defined as the size used by the char type. In the past, this has most often been 8 bits, but some character sets may use larger bytes. The operand can be a specific data object either a unary expression such as the name of a variable, array, structure or it can be a type name. If it is a type, such as float, the operand must be enclosed in parentheses. For example:

/* sizeof_1.c -- uses sizeof operator */
/* uses C99 %z modifier -- try %u or %lu if you lack %zd */
#include <stdio.h>
int main(void)
{
    int n = 0;
    size_t intsize;     /* size_t type used */
 
    intsize = sizeof (int);
    printf("n = %d, n has %zd bytes; all ints have %zd bytes.\n",
            ++n, sizeof ++n, intsize );
    /* sizeof doesn't evaluate the exp. */
    return 0;
}

Using sizeof with arrays

When sizeof is applied to the name of a static array (not allocated through malloc, calloc or realloc), the result is the size in bytes of the whole array. This is one of the few exceptions to the rule that the name of an array is converted to a pointer to the first element of the array, and is possible just because the actual array size is fixed and known at compile time, when sizeof operator is evaluated. The following program uses sizeof to determine the size of a declared array, avoiding a buffer overflow when copying characters:

/* sizeof_2.c -- use of sizeof operator with arrays */
#include <stdio.h>
#include <string.h>
 
int main(int argc, char **argv)
{
    char buffer[10];  /* Array of 10 chars */
 
    /* Copy at most 9 characters from argv[1] into buffer. */
    /* sizeof(char) is defined to be always 1. */
 
    strncpy(buffer, argv[1], sizeof buffer - sizeof buffer[0]);
 
    /* Ensure that the buffer is null-terminated */
    buffer[sizeof buffer - 1] = '\0';
    return 0;
}

Here, sizeof buffer is equivalent to 10 * sizeof buffer[0], or 10.

advertisement
advertisement

C99 adds support for flexible array members to structures. This form of array declaration is allowed as the last element in structures only, and differs from normal arrays in that no length is specified to the compiler. For a structure named flexarray containing a flexible array member named as array, for example:

/* sizeof_3.c -- use of sizeof with flexible array member to a structure */
#include <stdio.h>
 
struct flexarray {
        char val;
        int array[];
        /* Flexible array member; must be last element of struct */
};
 
int main(int argc, char **argv)
{
    printf("sizeof(struct flexarray) = %zu bytes\n",
            sizeof (struct flexarray));
 
    return 0;
}

Thus, in this case the sizeof operator returns the size of the structure, including any padding, but without any storage allowed for the flexible array. In the above example, the following output will be produced on most platforms:

sizeof (struct flexarray) = 4

Note: Join free Sanfoundry classes at Telegram or Youtube

C99 also allows variable length arrays where the length is specified at runtime. In such cases, the sizeof operator is evaluated in part at runtime to determine the storage occupied by the array. For example:

/* sizeof_4.c -- use of sizeof with variable length arrays */
#include <stddef.h>
#include <stdio.h>
 
size_t flexsize(int n)
{
    char b[n+3];      /* Variable length array */
    return sizeof b;  /* Execution time sizeof */
}
 
int main( void )
{
    size_t size = flexsize(10); /* flexsize returns 13 */
    return 0;
}

C says that sizeof returns a value of type size_t. This is an unsigned integer type, but not a brand-new type. Instead, like the portable types (int32_t and so on), it is defined in terms of the standard types. C has a typedef mechanism that lets you create an alias for an existing type. For example,

    typedef double real;

makes real another name for double. Now we can declare a variable of type real as

advertisement
    real deal;   /* using a typedef */

The compiler will see the word real, recall that the typedef statement made real an alias for double, and create deal as a type double variable. Similarly, the C header files system can use typedef to make size_t a synonym for unsigned int on one system or for unsigned long on another. Thus, when you use the size_t type, the compiler will substitute the standard type that works for your system.

C99 goes a step further and supplies %zd as a printf() specifier for displaying a size_t value. If your system doesn’t implement %zd, try using %u or %lu instead.

sizeof and incomplete types

sizeof can only be applied to “completely” defined types. With arrays, this means that the dimensions of the array must be present in its declaration, and that the type of the elements must be completely defined. For structs and unions, this means that there must be a member list of completely defined types. For example, consider the following two source files:

advertisement
/* file1.c */
    int arr[10];
    struct x {int one; int two;};
    /* more code */
 
/* file2.c */
    extern int arr[];
    struct x;
    /* more code */

Both files are perfectly legal C, and code in file1.c can apply sizeof to arr and struct x. However, it is illegal for code in file2.c to do this, because the definitions in file2.c are not complete. In the case of arr, the code does not specify the dimension of the array; without this information, the compiler has no way of knowing how many elements are in the array, and cannot calculate the array’s overall size. Likewise, the compiler cannot calculate the size of struct x because it does not know what members it is made up of, and therefore cannot calculate the sum of the sizes of the structure’s members (and padding). If the programmer provided the size of the array in its declaration in file2.c, or completed the definition of struct x by supplying a member list, this would allow the application of sizeof to arr or struct x in that source file.

Implementation

It is the responsibility of compilers to implement the sizeof operator correctly for each target platform. In many cases, there will be an official Application Binary Interface (ABI) document for the platform, specifying formats, padding, and alignment for the data types, to which the compiler must conform. In most cases, sizeof is a compile-time operator, which means that during compilation sizeof expressions get replaced by constant result-values. However, sizeof applied to a variable length array, introduced in C99, requires computation during program execution.

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

If you wish to look at all C Tutorials, go to C Tutorials.

If you find any mistake above, kindly email to [email protected]

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.