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