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.