Go to the first, previous, next, last section, table of contents.


5.4.6 Function Declarations

The syntax for declaring and defining C++ functions is the same as in C++ [ANSI95] with some additions. See section 6 Function Specifications for the syntax of fun-spec-body, and for how to specify (and not just declare or define the interface of) a function. The syntax for a compound-statement is as in C++ (see Section 17.6 of [Ellis-Stroustrup90][ANSI95]), except that traits can be passed to higher-order functions (see section 6.13 Specifying Higher-Order Functions for the syntax of using-trait-list), and Larch/C++ adds specification-statements (see section 6.14 Behavior Programs, for these), and annotated-iteration-statements (see section 6.15 Annotated Iteration Statements) to C++. Since, aside from these additions, the syntax of statements and expressions is identical to that in C++, it is not given in full here.

function-definition ::= fun-interface [ fun-spec-body ] [ ctor-initializer ] fun-body
        | fun-interface [ fun-spec-body ] function-try-block

fun-interface ::= [ decl-specifier-seq ] declarator
        | [ decl-qualifier-seq ] ctor-declarator
        | [ decl-qualifier-seq ] special-function-declarator

decl-qualifier ::= storage-class-specifier | function-specifier | friend | typedef
decl-qualifier-seq ::= decl-qualifier [ decl-qualifier ] ...
ctor-initializer ::= : mem-initializer [ , mem-initializer ] ...
mem-initializer ::= mem-initializer-id ( expression-list )
mem-initializer-id ::= complete-class-name | identifier

expression-list ::= expression [ , expression ] ...
expression ::= exactly as in C++, but add the following
postfix-expression ::= postfix-expression ( [ expression-list ] [ using-trait-list ] )
    | simple-type-name ( [ expression-list ] [ using-trait-list ] )

function-try-block ::= try [ ctor-initializer ] fun-body handler-seq
handler-seq ::= handler [ handler ] ...
handler ::= catch ( exception-declaration ) compound-statement
exception-declaration ::= type-specifier-seq declarator
        | type-specifier-seq [ abstract-declarator ]
        | `...'

compound-statement ::= { statement-seq }
statement-seq ::= statement [ statement ] ...
statement ::= as in C++, but add ...
        | specification-statement
        | annotated-iteration-statement

ctor-declarator ::= complete-class-name param-qualifier
        | complete-template-class-name param-qualifier
complete-template-class-name ::= [ :: ] [ nested-name-specifier ] template-class-name
special-function-declarator ::= [ :: ] nested-name-specifier dtor-name param-qualifier
        | dtor-name param-qualifier | declarator-id param-qualifier
dtor-name ::= ~ original-class-name | ~ template-class-name

fun-body ::= compound-statement

The form of a fun-interface starting with an optional explicit followed by a complete-class-name or a template-ctor-name is for the constructor of a class (see section 7.2.1 Constructors). (The use of explicit in constructors is a feature of the proposed C++ standard [Stroustrup95] [ANSI95].) (See section 7.2.2 Destructors for how to declare and specify destructors. See section 5.4 Declarators for the syntax of destructor names, which is unqualified-id.)

A normal fun-interface has the following form, just as in C++ (see Section r.8.2.5 of [Stroustrup90]).

[ decl-specifier-seq ] declarator ( [ parameter-declaration-clause ] ) [ cv-qualifier-seq ]
                                         [ exception-decl ]

That is, one specifies the function's return type (in the decl-specifier-seq and parts of the declarator), name (in the declarator), and formal arguments (in the parameter-declaration-clause). The use of const and volatile in the cv-qualifier-seq is restricted as in C++ (see Section r.8.2.5 of [Stroustrup90]). Finally, one can declare the exceptions that may be raised by the function in the optional exception-decl (see section 6.11 Exceptions). See section 5.4 Declarators for details of the syntax.

The syntax for declaring the arguments to a C++ function is also the same as in C++, with a slight addition. See section 5.4 Declarators for the syntax of declarator, which is used to declare a function interfaces by using a param-qualifier. The syntax for a param-qualifier allows one to specify what traits should also be passed to the function. See section 6.13 Specifying Higher-Order Functions for how to use this extension.

parameter-declaration-clause ::= parameter-declaration-list [ `...' ]
        | `...' | parameter-declaration-list , `...'
parameter-declaration-list ::= parameter-declaration [ , parameter-declaration ] ...
parameter-declaration ::= decl-specifier-seq declarator [ parameter-initializer ]
        | decl-specifier-seq [ abstract-declarator ] [ parameter-initializer ]
parameter-initializer ::= = assignment-expression
assignment-expression ::= exactly as in C++

Note that the three dots in `...' are not a meta-notation; they form a single token in the C++ syntax (see Section 8.2.5 in [Ellis-Stroustrup90]). For example, one would write:

int printf(char *fmt, ...);

The sort of a global function name is ConstObj[cpp_function]. Consider the following.

Declaration      Name   Its Sort (when used as a global variable)
-------------    ----   -----------------------------------------
int f(int i);    f      ConstObj[cpp_function]

That f has sort ConstObj[cpp_function] means that it is an object whose abstract value cannot be changed. C++ functions used as global variables are modeled as objects because one can take their address.

A declaration such as int f(int i) makes Larch/C++ implicitly use the trait cpp_function. See section 11.12 Function Types for details of the trait that defines this sort.

In a class, a function is called a member function. If the declaration of f appeared in a class, it would have sort ConstObj[cpp_member_function] when used as a global variable. Such a declaration makes Larch/C++ implicitly use the trait cpp_member_function. See section 11.12 Function Types for details on this trait.

See section 6.13 Specifying Higher-Order Functions for how to specify functions that take and return pointers to functions.


Go to the first, previous, next, last section, table of contents.