Search code examples
cgccsizeofcomma-operator

Why in C does the function sizeof() output the size of right most operand when more than one operands are passed separated by comma?


I have the following code in C:

#include <stdio.h> 

void main() {
    printf("%d %d\n",sizeof(5),sizeof(5,5));   
    printf("%d %d\n",sizeof(5),sizeof(5.0,5)); 
    printf("%d %d\n",sizeof(5),sizeof(5,5.0)); 
}

And I get the output:

4 4

4 4

4 8

I understand that sizeof(5) would return me the size of integer and sizeof(5.0) would return the size of a double, but why does it give the size of the rightmost operand in case more than one arguments are passed separated by comma? Why not the first argument or the collective size of all the arguments?

I am compiling online using OnlineGDB.com compiler for C.

Thanks for your help.


Solution

  • The simple reason is: Because sizeof is not a function! It is an operator that takes some expression on its right. Syntactically, it behaves the same as the return operator. The parentheses are only added by the programmers for clarity, and are not needed in most cases:

    sizeof(foo);       //no surprise, take the size of the variable/object
    sizeof foo;        //same as above, the parentheses are not needed
    
    sizeof(void*);     //you cannot pass a type to a function, but you can pass it to the sizeof operator
    sizeof void*;      //same as above
    
    typedef char arrayType[20]
    arrayType* bar;    //pointer to an array
    sizeof(*bar);      //you cannot pass an array to a function, but you can pass it to the sizeof operator
    sizeof*bar;        //same as above
    
    //compare to the behavior of `return`:
    return foo;     //no surprise
    return(foo);    //same as above, any expression may be enclosed in parentheses
    

    So, what happens when you say sizeof(5, 5.0)? Well, since sizeof is an operator, the parentheses are not a function call, but rather interpreted like the parentheses in 1*(2 + 3) == 5. In both cases, the ( follows an operator, and is thus not interpreted as a function call. As such, the comma does not separate function call arguments (because there is no function call), rather it's interpreted as the comma operator. And the comma operator is defined to evaluate both its operands, and then return the value of the last operand. The operator nature of the sizeof dictates how the expression on its right is parsed.