Overview
A function f
without a following opening (
is converted to a pointer to its start. This is called function decay.
Prototypes
There exist two ways for a function declaration to use declarators: parameter type lists and identifier type lists. To make the distinction clear, consider the following ways of defining an add
function:
int f(int x, int y) { return x + y; } // Paramter type list
int f(x, y) int x; int y; { return x + y } // Identifier type list
A function prototype is a function declaration that specifies a function signature. There are three important points to make note of:
- Empty identifier lists are interpreted as “the compiler has not been told what this function’s arguments are.”
- The standard prohibits declaring functions with a non-empty identifier list.
- Empty parameter lists are not allowed.
Therefore:
// Uses an empty identifer list. This declares a function `foo`
// that takes an unknown specification of arguments.
void foo();
// Uses a non-empty identifier list. Compiler error.
void foo(x, y);
// Uses a non-empty identifier list. Compiler error.
void foo(x, y) int x; int y;
// Uses a non-empty identifier list. Definitions allow this.
void foo(x, y) int x; int y; { }
// Uses a non-empty parameter list. This prototypes a function
// `foo` that takes no arguments.
void foo(void);
// Uses a non-empty parameter list. This prototypes and defines
// a function `foo` that takes no arguments.
void foo(void) {}
Together these points imply a function prototype must use a parameter type list.
main
main
is a special function serving as the entrypoint to C programs. It can have several different prototypes, but the following two are always possible:
int main(void);
int main(int argc, char* argv[argc+1]);
The only two return values guaranteed to work on all platform is EXIT_SUCCESS
and EXIT_FAILURE
. Reaching the end of main
is equivalent to a reutrn
with value EXIT_SUCCESS
.
Variable-Length Arrays
Within a function prototype, a parameter can denote a VLA using [*]
syntax. For example, the following prototypes are all (more or less) equivalent:
int sum2d(int , int , int a[*][*]);
int sum2d(int n, int , int a[n][*]);
int sum2d(int , int m, int a[*][m]);
int sum2d(int n, int m, int a[n][m]);
int sum2d(int , int , int a[][*]);
int sum2d(int , int , int (*a)[*]);
int sum2d(int , int m, int (*a)[m]);
Bibliography
- “ISO: Programming Languages - C17,” April 2017, https://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf.
- Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).