6.7.5.3 Function declarators (including prototypes)

Previous Table of Contents

1581 A function declarator shall not specify a return type that is a function type or an array type.

1582 The only storage-class specifier that shall occur in a parameter declaration is register.

1583 An identifier list in a function declarator that is not part of a definition of that function shall be empty.

1584 After adjustment, the parameters in a parameter type list in a function declarator that is part of a definition of that function shall not have incomplete type.

1585 If, in the declaration “T D1”, D1 has the form

        D( parameter-type-list )

or

        D( identifier-listopt )

and the type specified for ident in the declaration “T D” is “derived-declarator-type-list T”, then the type specified for ident is “derived-declarator-type-list function returning T”.

1586 A parameter type list specifies the types of, and may declare identifiers for, the parameters of the function.

1587 A declaration of a parameter as “array of type” shall be adjusted to “qualified pointer to type”, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation.

1588 If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

1589 A declaration of a parameter as “function returning type” shall be adjusted to “pointer to function returning type”, as in 6.3.2.1.

1590 If the list terminates with an ellipsis ( , ...), no information about the number or types of the parameters after the comma is supplied.123)

1591 The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters.

1592 If, iIn a parameter declaration, a single typedef name in parentheses is taken to be an abstract declarator that specifies a function with a single parameter, not as redundant parentheses around the identifier for a declarator. an identifier can be treated as a typedef name or as a parameter name, it shall be taken as a typedef name.

1593 If the function declarator is not part of a definition of that function, parameters may have incomplete type and may use the [*] notation in their sequences of declarator specifiers to specify variable length array types.

1594 The storage-class specifier in the declaration specifiers for a parameter declaration, if present, is ignored unless the declared parameter is one of the members of the parameter type list for a function definition.

1595 An identifier list declares only the identifiers of the parameters of the function.

1596 An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters.

1597 The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied.124)

1598 123) The macros defined in the <stdarg.h> header (7.15) may be used to access arguments that correspond to the ellipsis.

1599 124) See “future language directions” (6.11.6).

1600 For two function types to be compatible, both shall specify compatible return types.125)

1601 Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator;

1602 corresponding parameters shall have compatible types.

1603 If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions.

1604 If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier.

1605 (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)

1606 EXAMPLE 1 The declaration


        int f(void), *fip(), (*pfi)();

declares a function f with no parameters returning an int, a function fip with no parameter specification returning a pointer to an int, and a pointer pfi to a function with no parameter specification returning an int. It is especially useful to compare the last two. The binding of *fip() is *(fip()), so that the declaration suggests, and the same construction in an expression requires, the calling of a function fip, and then using indirection through the pointer result to yield an int. In the declarator (*pfi)(), the extra parentheses are necessary to indicate that indirection through a pointer to a function yields a function designator, which is then used to call the function; it returns an int.

If the declaration occurs outside of any function, the identifiers have file scope and external linkage. If the declaration occurs inside a function, the identifiers of the functions f and fip have block scope and either internal or external linkage (depending on what file scope declarations for these identifiers are visible), and the identifier of the pointer pfi has block scope and no linkage.

1607 EXAMPLE 2 The declaration


        int (*apfi[3])(int *x, int *y);

declares an array apfi of three pointers to functions returning int. Each of these functions has two parameters that are pointers to int. The identifiers x and y are declared for descriptive purposes only and go out of scope at the end of the declaration of apfi.

1608 EXAMPLE 3 The declaration


        int (*fpfi(int (*)(long), int))(int, ...);

declares a function fpfi that returns a pointer to a function returning an int. The function fpfi has two parameters: a pointer to a function returning an int (with one parameter of type long int), and an int. The pointer returned by fpfi points to a function that has one int parameter and accepts zero or more additional arguments of any type.

1609 125) If both function types are “old style”, parameter types are not compared.

1610 EXAMPLE 4 The following prototype has a variably modified parameter.


        void addscalar(int n, int m,
                double a[n][n*m+300], double x);
        
        int main()
        {
                double b[4][308];
                addscalar(4, 2, b, 2.17);
                return 0;
        }
        
        void addscalar(int n, int m,
                double a[n][n*m+300], double x)
        {
                for (int i = 0; i < n; i++)
                        for (int j = 0, k = n*m+300; j < k; j++)
                                // a is a pointer to a VLA with n*m+300 elements
                                a[i][j] += x;
        }

1611 EXAMPLE 5 The following are all compatible function prototype declarators.


        double maximum(int n, int m, double a[n][m]);
        double maximum(int n, int m, double a[*][*]);
        double maximum(int n, int m, double a[ ][*]);
        double maximum(int n, int m, double a[ ][m]);

as are:


        void f(double (* restrict a)[5]);
        void f(double a[restrict][5]);
        void f(double a[restrict 3][5]);
        void f(double a[restrict static 3][5]);

(Note that the last declaration also specifies that the argument corresponding to a in any call to f must be a non-null pointer to the first of at least three arrays of 5 doubles, which the others do not.)

1612 Forward references: function definitions (6.9.1), type names (6.7.6).

Next

Created at: 2005-06-29 02:19:02 The text from WG14/N1124 is copyright © ISO