31

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?

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
Pointer
  • 311
  • 3
  • 3
  • 6
    My guess is that the -1 was because of TIAS ("try it and see"). – luqui Apr 19 '10 at 09:54
  • 15
    The problem with TIAS is that it usually doesn't work, because all you see is what _your current compiler with your current options_ actually does, which could be quite different from what a compiler is _supposed to do_. Something that's just been proven another time with the discussions found below. (You actually have to add a `-pedantic` option to GCC's command line to observe the "official" behavior. And that's just one compiler) So here's a +1 from me just to counter the stupid TIAS down-vote. – sbi Apr 19 '10 at 10:18

4 Answers4

19

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.

qrdl
  • 34,062
  • 14
  • 56
  • 86
  • 3
    While `gcc` may compile it, it is not clear that it is performing the translation from `main` to `&main`. For example, codepad--which uses gcc 4.1.2--returns a size of 1 for `sizeof(main)` but a size of 4 for `sizeof(&main)`. – Matthew T. Staebler Apr 19 '10 at 10:26
  • 1
    @Aeth You are completely correct, I got the same result with latest and greatest GCC 4.5. Post edited. – qrdl Apr 19 '10 at 10:49
8

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 as size_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) is size_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.

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
6

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."

zoli2k
  • 3,388
  • 4
  • 26
  • 36
2

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.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Conforming implementations may offer extensions so long as they report diagnostics where required, and the extension does not alter the behaviour of any conforming program – M.M Aug 18 '15 at 02:36
  • 1
    if my memory is correct, `gcc` is defined to return `1`. correct me if my brain is in jam again. – Jason Hu Aug 18 '15 at 02:51
  • @Matt, good point, I originally saw this as a behavioural change hence disallowed. But, since the change would have been made to a *non* strictly conforming program, it's irrelevant. Updated the answer to adjust. – paxdiablo Aug 18 '15 at 02:52