Sample code:
int main(void)
{
printf ("size = %d\n", sizeof(main));
}
What is the returned value sizeof
applied to a function name, for example main
?
Sample code:
int main(void)
{
printf ("size = %d\n", sizeof(main));
}
What is the returned value sizeof
applied to a function name, for example main
?
C standard forbids it - when compiled with gcc -pedantic
, it produces invalid application of ‘sizeof’ to a function type
warning.
However gcc
compiles it and returns 1
for sizeof(main)
, and it is not a size of function pointer.
It seems to be compiler-dependent.
The sizeof Operator
sizeof unary-expression sizeof ( type-name )
The operand is either an identifier that is a unary-expression, or a type-cast expression (that is, a type specifier enclosed in parentheses). The unary-expression cannot represent a bit-field object, an incomplete type, or a
function designator
. The result is an unsigned integral constant. The standard header STDDEF.H defines this type assize_t
.
Use compilation flag -Wall -pedantic
to emit warning about incorrect operand to sizeof
(remember sizeof
is a compilation time operator), Code:
$ cat sizeof.c
#include<stdio.h>
int main(){
printf("%zu %p\n", sizeof(main), (void*)main);
return 0;
}
Compilation message with GCC version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5):
$ gcc -Wall -pedantic sizeof.c -std=c99
sizeof.c: In function ‘main’:
sizeof.c:3:30: warning: invalid application of ‘sizeof’ to a function type
[-pedantic]
sizeof.c:3:38: warning: ISO C forbids conversion of function pointer to
object pointer type [-pedantic]
Read also:
6.5.3.4 The sizeof operator
1118 — The
sizeof
operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member
1127 — The value of the result is implementation-defined, and its type (an unsigned integer type) issize_t
, defined in<stddef.h>
(and other headers)
Additionally, correct format string for size_t
is %zu
and If it doesn't exists for example Microsoft's compiler then you can use %lu
and convert the returned value to unsigned long
.
ISO C++ forbids applying sizeof
to an expression of function type.
ISO/IEC 14882 on C++ says (section 5.3.3):
"The size operator shall not be applied to an expression that has function or incomplete type,..."
The same hold for standard C (ISO/IEC 9899:1999) section 6.5.3.4:
"The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member."
As per ISO C11 section 6.5.3.4 The sizeof and _Alignof operators
, sub-section 1 (constraints):
The
sizeof
operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.
There's also a subsection 4 in section 6.3.2.1 Lvalues, arrays, and function designators
which states:
A function designator is an expression that has function type. Except when it is the operand of the
sizeof
operator, the_Alignof
operator(65) or the unary&
operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type"".
Foot note 65, referenced from there, clarifies the point:
Because this conversion does not occur, the operand of the
sizeof
or_Alignof
operator remains a function designator and violates the constraints in 6.5.3.4.
As per section 4 Conformance
:
In this International Standard, "shall" is to be interpreted as a requirement on an implementation or on a program; conversely, "shall not" is to be interpreted as a prohibition.
Hence a strictly conforming program should never take the size of a function. But, then again, it probably should also use a correct form of main()
:-)
There is a loophole here, however. A conforming implementation is allowed to provide extensions "provided they do not alter the behavior of any strictly
conforming program" (section 4 Conformance
, subsection 6
).
You could argue that this is a behavioural change (allowing sizeof(function)
rather than disallowing it) but, since the original program wouldn't have been strictly conforming in the first place, the subsection does not forbid it.