sizeof a function types in C

Viewed 1821

I have a some cases about sizeof operator, which is used with function types.

Case 1 : [Live Demo]

#include <stdio.h>

char func()
{
    printf("sizeof func = %zu\n", sizeof(func())); //Ok. Output : 1
    return 0;
}

int main(void)
{
    func();
}

Is sizeof(func()) valid in C?

Case 2 : [Live Demo]

printf("sizeof func = %zu\n", sizeof(&func())); // error

It is not working. compiler give an error. Why?

Case 3 : [Live Demo]

printf("sizeof func = %zu\n", sizeof(&func)); //Ok. Output : 8

Here, Is sizeof(&func) equal to the sizeof the pointer?

Here, case 3 working fine, where as case 2 give an error. Why?

3 Answers

The operand of sizeof can have two forms:

  • A paranthesized type name, e.g. (char), (int), (struct mystruct), ... The result is the storage size of the named type.

  • An expression. The result is the storage size of the type the expression would evaluate to (but it isn't evaluated).

None of your examples is a type name. The type name for your function would be char (void). So all your parantheses are superfluous.

In your first example, you have sizeof func(). Evaluating func() would return a char, therefore the result is 1.

In your third example, you have sizeof &func. Evaluating &func would give you a function pointer and the size of a function pointer is 8 on your machine.

The second example is just wrong, &func() is not a valid expression. You can't take a pointer to a function call. In standard terms, func() is not an lvalue, which is required to apply &.

sizeof(type) returns the size in bytes of the object representation of type.

sizeof(expr) returns the size in bytes of the object representation of the type that would be returned by expression, if evaluated.

case 1

func is a function that returns a value of type char. So sizeof(func()) is the same as sizeof(char), which is 1

case 2

&func() is not a valid expression (you are trying to get the address of the return value of the function, which is undefined)

case 3

&func returns the address of the function func, which is a pointer. On a 64-bits system, sizeof(&func) will be the size of a pointer, that is 8. It will be 4 on a 32-bits OS.

In this statement

printf("sizeof func = %zu\n", sizeof(func())); 

there is outputted the size of the expression (that is not evaluated) func(). As the return type of the function is char then the expression func() has the type char and sizeof( char ) is equal to 1.

From the C Standard (6.5.3.4 The sizeof and alignof operators)

4 When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1....

In this statement

printf("sizeof func = %zu\n", sizeof(&func())); 

there is an attempt to apply the unary operator & to a temporary object that is evaluated as the expression func(). You may not apply the operator to a temporary object.

From the C Standard (6.5.3.2 Address and indirection operators)

1 The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

for comparison consider the following program

#include <stdio.h>

char * func()
{
    static char i = 0;

    printf("sizeof func = %zu\n", sizeof(&*func()));

    return &i;
}

int main(void)
{
    func();
}

In this program the function returns pointer to the lvalue i with the static storage duration. So applying the unary operator * you will get the lvalue. So you may apply the operator & in this case.

The program output will be

sizeof func = 8

In this statement

printf("sizeof func = %zu\n", sizeof(&func)); 

there is evaluated the operator sizeof for a function pointer of the type char ( * )( void ). Again according to the quote from the C Standard the operator & may be applied to a function designator.

Take into account that the function definition shall look like

char func( void )
           ^^^^ 
{
    printf("sizeof func = %zu\n", sizeof(func())); //Ok. Output : 1
    return 0;
}
Related