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

2.8 Objects and Values

As in Section 3.7 of [Ellis-Stroustrup90], "an object is a region of storage." Note that a C++ variable of type int is an object in this sense, although it does not respond to messages. We use the term instance for emphasis when discussing an object of a class; instances are what are usually called objects in object-oriented programming. Instances respond to messages. A variable of type int is not an instance. All objects in C++ have an address, or location, which we will sometimes call an object identifier.

Values are stored in objects. To emphasize that a value is the value of an instance of a class, we sometimes use the term instance value. In contrast to the abstract values used in specifications, the values manipulated by C++ programs, are thought of as concrete values. Each concrete value, a bit pattern, is thought of as a representation of an abstract value. For example, a C++ int variable holds a bit pattern that corresponds to an abstract value which is a mathematical integer, specified by the trait int (see section 11.1 Integer Types).

As an illustration of the concept of objects and values, the following is a picture of the Larch/C++ model of an integer variable, i. In the picture, i is an object, which contains the abstract value 228. To be more specific, the following is a picture of i in some program state. A state, as in the picture, associates to each object, an abstract value. The abstract value of an assignment may change from state to state, as the program executes (for example, the value of i may be changed by an assignment statement in C++). For the most part, Larch/C++ specifications only describe states just before and just after the call of a C++ function.

      i: !          228    !

     The Larch/C++ model of an integer variable,
     containing the abstract value 228.

Unlike C++, in the Larch/C++ model, an object can contain an arbitrarily complex abstract value. That is, a state may map an object to any value defined by a trait. For example, the Larch/C++ picture of a variable myHeap of type IntHeap might be as follows. See section 1.1 Larch-style Specifications for the specification of the class IntHeap and the trait that defines its abstract values.

 myHeap: !  add(6, add(7, empty)) !

 The Larch/C++ model of an IntHeap variable,
 containing the abstract value add(6, add(7, empty)).

Finally, in Larch/C++, values can contain objects, which enables complex, even circular, object structures to be modeled. (One way to think of this is that objects are just a special kind of abstract value.) For example, the following is a picture of variable mySet, whose abstract value is a set of point objects. The picture represents the abstract value of the set as {*,*,*}, where the *s are the tails of three arrows that show what object is contained in the set. Each of the point objects has an abstract value that is a LSL tuple of two integers. In general, users of Larch/C++ will model objects and values in such layers.

 mySet:  !  { * ,       * ,       * } !
              !         !         !
              v         v         v
         !--------!  !--------!  !----------!
         ! [3, 4] !  ! [5, 6] !  ! [-12, 5] !
         !--------!  !--------!  !----------!

 The Larch/C++ model of a Set variable with an abstract
 value that contains containing three other objects.

The word lvalue means a term (something like a C++ expression, see section 6.1 Predicates for details) that denotes an object or a function. Recall that in C++ an array name is not an lvalue.

In contrast to C++ (but like LCL), Larch/C++ does not consider formal parameters passed by value to be objects. This is because parameters passed by value cannot be changed from the point of view of the client (the caller), and so are not objects from the point of view of the client. Therefore in Larch/C++, only formal parameters passed by reference are objects. Pointers that are passed by value are not objects but do point to objects. For example, within the specification of a function with the following heading the expressions cr and *ip are lvalues (denote objects), but i and ip are not.

int foo(int i, char & cr, int * ip)

Whether or not a formal parameter is declared to be const does not affect this distinction. For example, within the specification of a function with heading

int foo(const int ci, const char & ccr, const int * cip)

the expressions ccr and *cip are lvalues, but ci and cip are not.

The name result is used in postconditions to stand for what is returned by the C++ function being specified. It is considered to be an object only if the return type of the function is a reference type. That is, result is treated in the same way as a formal parameter. For example, within a function specification with the above header, result is not an lvalue. However, if the return type were specified as int &, then result would be an lvalue.

Values are formally modeled by various traits, most of which are specified by Larch/C++ users in LSL. Objects are formally modeled by the traits described below. These traits build on the more primitive notion of a state; states are formally modeled by another trait described below.

(Some of the discussion in the subsections below is quite technical. If you are new to Larch/C++, feel free to skim these subsections.)

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