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

6.3.2 The Trashes Clause

When an object is trashed, it can no longer be used. In the Larch/C++ model of C++, a function call can make this can happen in the following ways.

Functions that trash objects must include a trashes-clause-seq. If a trashes clause is not included, then the function may not trash any objects. If such a clause is included, then only the objects described may be trashed. An object is described by the trashes-clause if it is listed explicitly, or if it depends on a described object. This means that objects that are not described in the trashes-clause-seq cannot be made unassigned or deallocated. The objects described in the trashes-clause-seq do not have to be trashed, the point is that they are allowed to be trashed.

Because objects that are not described by the trashes-clause-seq are not allowed to be trashed, the postcondition of a function specification does not have to mention that all other objects stay allocated or assigned. Hence, the trashes-clause-seq, along with the modifies-clause-seq, gives a complete frame axiom [Borgida-etal95] for the function specification.

The idea of the trashes-clause-seq and its utility in making Larch-style specifications referentially transparent and less verbose is taken from Chalin [Chalin95].

The trashes-clause-seq has a syntax that is very similar to the syntax of the modifies-clause-seq.

trashes-clause-seq ::= trashes-clause [ trashes-clause ] ...
trashes-clause ::= trashes [ redundantly ] store-ref-list ;

See section 6.9.4 Redundancy in Frames for the meaning of redundantly used in a trashes-clause. When several non-redundant trashes-clauses are listed in a trashes-clause-seq, this is the same as listing each of their store-ref-lists in a single trashes-clause. If more than one non-redundant trashes-clause is given, then none of the store-ref-lists may be of the form nothing or everything. Because it is possible to translate multiple non-redundant trashes-clauses into a single trashes-clause, we will assume from now on that there is only one non-redundant trashes-clause.

For example, the following specifies a function that deallocate an integer object. The requires-clause states that the pointer passed must be a non-null pointer, and that it points to allocated storage. (Equivalently, this could have been stated as allocated(p, pre), see section 11.8 Pointer Types for the details of these trait functions.) The trashes-clause says that the function is allowed to, but does not have to, deallocate or make unassigned the object *p. The postcondition states that *p must be deallocated. The redundant postcondition follows from the meaning of ~allocated(p, post) in the pointer traits. (See section 6.9.3 Redundant Ensures Clauses or Claims for the meaning of a redundant ensures-clause.)

// @(#)$Id: dealloc_int_obj.lh,v 1.7 1998/08/27 22:42:12 leavens Exp $

extern void dealloc_int_obj(int *p) throw();
//@ behavior {
//@   requires isValid(p) /\ allocated(*p, pre);
//@   trashes *p;
//@   ensures ~allocated(*p, post);
//@   ensures redundantly ~allocated(p, post);
//@ }

Other topics related to the trashes-clause are discussed below.

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