Given:
int func(int x, int y) { /* ... */ }
the expression func
is of function type. Specifically, it's of type int(int, int)
, which is C's syntax for the type "function with two int
parameters returning int
. (You won't often see that particular syntax, since it's not common to refer to function types directly.)
In most contexts, an expression of function type is implicitly converted to a pointer to the function; in this case, the pointer is of type int(*)(int, int)
.
The contexts in which this implicit conversion does not occur are:
When the expression is the operand of unary &
; in that case, &func
yields the address of the function (just as func
by itself usually does); and
When the expression is the operand of sizeof
. Without this exception, sizeof func
would yield the size of a function pointer. Instead, it's a constraint violation, requiring a diagnostic from the compiler.
(A side note: This conversion does happen when the function name is used in a function call. The ()
"operator" (the standard doesn't call it that) requires a prefix of pointer-to-function type.)
gcc happens to have a non-standard extension; it permits pointer arithmetic on function pointers and on type void*
, acting like pointer arithmetic on char*
pointers (i.e., it operates in units of bytes). Unfortunately, IMHO, gcc did this via a kludge, setting the size of function types and of type void
to 1. That's why you get sizeof func == 1
; if you enable one of the standard conforming modes (e.g., gcc -std=c99 -pedantic
), you'll get a warning.
Incidentally, don't use %d
to print the result of sizeof
. sizeof
yields a result of type size_t
. If your implementation supports it (C99 or later), use %zu
; if not, you need to use a cast to explicitly convert the size_t
value to something that you can print. For example:
printf("%lu\n", (unsigned long)sizeof &func);