• No results found

Pragmas affecting conditions under which variables may be referenced

In document SRC TN 2000 002 pdf (Page 41-44)

2.5.0 spec_public pragma

A spec_public pragma is a modifier pragma. It may occur as a modifier only of a non-public field

declaration. It has the form

spec_public

in pragmas, see section 3.3) as they would have been if the declaration had been public.

For example, if a private field of a class is declared with a spec_public pragma, then the field can be

mentioned in pre- and postconditions of a public method, but clients of the class cannot modify the field

directly. Example

Consider the Bag example form section 0. In presenting this example, we glossed over the issue of accessibility.

To allow clients of the Bag class to make use of the routines of the class (Bag,extractMin, and others that we

might add), these routines should be declared public. On the other hand, the fields a and n used in the

implementation ought not to be public. For example, arbitrary clients ought not to be able to write these fields

except by calling routines of the Bag class.

If we simply declare the routines, but not the fields of Bag to be public, ESC/Java will complain: ESC/Java input from Bag.java

1: class Bag {

2: /*@ non_null */ int[] a; 3: int n;

... ...

13: //@ requires n >= 1; 14: public int extractMin() { ... ...

ESC/Java output:

Bag.java:13: Error: Fields mentioned in this modifier pragma must be at least as accessible as the field/method being modified (perhaps try spec_public)

//@ requires n >= 1; ^

Caution: Turning off extended static checking due to type error(s) 1 caution

1 error

If programmers using the Bag class are not supposed to know that its implementation includes the field n, then it

is unreasonable to expect them to establish a precondition involving n before calling extractMin. We can

prevent ESC/Java from complaining by declaring the field n to be spec_public: 3: /*@ spec_public */ int n;

This will allow n to be mentioned in requires pragmas of public routines, as well as in pragmas occurring in

other packages that import the Bag class. Of course, actual Java code in other packages will not be able to read

or write the n field directly (as would be allowed if n were declared with a Java public modifier).

Fine point

By declaring n with a spec_public pragma, the implementer of the Bag class expresses a design decision that

design decision could cause problems if implementer later decided to change the implementation to represent a

Bag using a data structure that did not include an explicit count--for example, a linked list. See the first example

in section 2.6.2 for further discussion of this issue. 2.5.1 readable_if pragma

A readable_if pragma is a modifier pragma. It can occur only as a modifier of a field declaration or of a local

variable declaration. It has the form

readable_if E ;

opt

where E is a boolean specification expression.

The pragma causes ESC/Java to check that E is true just before any read access of any of the variable(s)

declared in the declaration. The pragma thus expresses the programmer's intention that the variable modified by the pragma has a meaningful value only when E is true.

The specification expression E is allowed to mention this if the pragma modifies an instance field declaration, or

if the pragma modifies a local variable declaration within an instance method or a constructor. If the pragma modifies the declaration of an instance field f, then for purposes of checking a read access O.f, occurrences of this in E are taken to denote the value of O.

Fine points

If the pragma modifies a local variable declaration then the variables declared by the declaration are not in scope in E, even if the pragma occurs just before the final semi-colon instead of before the type.

class C { boolean b; void m() {

boolean b /*@ readable_if b */;

// "b" in the pragma above means this.b, not the local b // "b" in the pragma below means the local b

/* readable_if b */ int c; ...

} }

If the pragma modifies a field declaration, then all fields of the containing class are in scope in E, even those that

are declared in textually later declarations.

class C extends B {

/*@ readable_if b */ int a; boolean b;

// "b" in the pragma means this.b, not ((B)this).b ...

}

declared by the declaration are accessible according to Java's access control rules [JLS, 6.6]

Remark: For the picky, a more precise name for this pragma might be ``meaningful_only_if''.

Remark: Perhaps unfortunately, ESC/Java does not provide a way to say when particular array elements are readable (meaningful). This could be useful since one could then express, for example, ``a[i] is meaningful only

if 0 <= i & i < n'', which says that only the first n elements of array a are in use. 2.5.2 uninitialized pragma

An uninitialized pragma is a modifier pragma. An uninitialized pragma can occur as a modifier only of

a local variable declaration that has an initializer. The pragma causes ESC/Java to check that no execution path reads the variable without first performing an assignment (other than the initializer) to the variable.

The intended use of the uninitialized pragma is for situations in which the conservative nature of Java's

``definite assignment'' rules [JLS, 16] has forced the programmer to supply an irrelevant initial value.

In document SRC TN 2000 002 pdf (Page 41-44)