Shared attributes are similar to object attributes, but are shared between all the instances of a class. They are essentially global variables that reside within a class namespace. They can be accessed and modified by any instance of the class. Shareds can have the same private and readonly restrictions that regular attributes have

private shared i,j:INT;
readonly shared c:CHAR := 'x'

Unlike regular attributes, when only a single shared attribute is defined, a constant initializing expression may be provided.

shared s:STR := "name";
-- ILLEGAL shared s,p:STR := "name";
-- cannot use initializing expression if two shareds are
-- declared at the same time

If no initializing expression is provided, the shared is initialized to the value 'void'.

Constants are accessible by all objects in a class and may not be assigned to - they must have an initializing expression from which their value is determined at compile time (there is an exception when no type is specified, as descrbed in the next subsection). If a type is specified, then the construct defines a single constant attribute which must be initialized to a constant expression. Constant expressions are recursively composed out of a combination of literals, function calls on literals, and references to other constants. More precisely, legal assignments are to

a character, boolean, string, integer or floating point literal

a void or void test expression

an and or or expression, each of whose components is a constant expression

an array literal, each of whose components is a constant expression

a routine call applied to a constant expression, each of whose arguments is a constant expression other than void. This caveat is imporant, since create routines are called on void. Thus the following is illegal:[1]

[1] Implementation Note: The compiler currently does not always detect this illegal case.

Integer constants and Enumerated Types

If a type specifier is not provided, then no initializing expression is required and the construct defines one or more successive integer constants. The first identifier is assigned the value zero by default; its value may also be specified by a constant expression of type INT. The remaining identifiers are assigned successive integer values. This is the way to do enumeration types in Sather. It is an error if no type is specified and there is an assignment that is not of type INT.

Since constant initialization involves permits operations on the built-in types, the operations on the built-in types are designed so that no observable side-effects can occur during constant initialization.

The prefix readonly cannot be applied to constants, since constants cannot be modified in any case.

Due to their definition, constants are only useful for the basic classes such as numbers, booleans and characters. All other constants can only be assigned to be void!

The shared and const class data can then be accessed using the :: notation

#OUT+ FOO::a+"\n";
FOO::d := 3;

When a method is called using the '::' notation, it is equivalent to calling the method on a void object. Calling a method on a void object makes sense if the feature only makes use of shared data and local state. If the method makes use of object data, a run-time error will result.