[an error occurred while processing this directive]
HP OpenVMS Systems Documentation |
HP Pascal for OpenVMS
|
Previous | Contents | Index |
The VALUE attribute causes the variable to be a reference to an external constant or to be the defining point of a global constant.
Usage and Default Information:
In this example, the linker resolves the reference to CLI$_PRESENT; the example writes the decimal value to OUTPUT. The example also defines a global symbol with the name My_Global and with a value of 1985.
PROGRAM Value_Test( OUTPUT ); VAR CLI$_PRESENT : [VALUE, EXTERNAL] INTEGER; My_Global : [VALUE, GLOBAL] INTEGER VALUE 1985; {In the executable section:} WRITELN( 'The value is', CLI$_PRESENT ); |
The VOLATILE attribute indicates to the compiler that the value of an object is subject to change at unusual points in program execution. Normally, during execution, an object's value changes only under the following circumstances:
In addition, the compiler expects to evaluate the object only when it appears in an expression.
The value of a volatile object can change as the result of an action not directly specified in the program. Thus, the compiler assumes that the value of a volatile object can be changed or evaluated at any time during program execution. Consequently, a volatile object does not participate in any optimization based on assumptions about its value.
The behavior of many device registers, and modifications by asynchronous processes and exception handlers, are two examples that demonstrate volatile behavior.
Usage and Default Information:
See Table 10-6, which also summarizes combinations of volatile and
nonvolatile parameters and variables accepted by the compiler.
Actual | Formal Parameter | ||
---|---|---|---|
Parameter | VAR | VAR [VOLATILE] | [VOLATILE] |
Volatile | No | Yes | Yes |
Nonvolatile | Yes | Yes | Yes |
Consider the following example:
VAR x : CHAR; a : [VOLATILE] RECORD CASE BOOLEAN OF FALSE : ( i : INTEGER ); TRUE : ( c : CHAR ); END; {In the executable section:} a.c := 'A'; {TRUE becomes the current variant} a.i := 66; {Assignment makes FALSE the current variant} x := a.c; {TRUE is again the current variant; X is assigned the value 'B', which has an ordinal value of 66} |
As the comments in this example show, a reference to one field
identifier causes the corresponding variant to become the current
variant. In addition, each reference immediately causes the other
variant to become undefined. So, when the assignment a.i := 66 is made,
the reference to a.i causes FALSE to become the current variant and a.c
to become undefined. As a result of the statement x := a.c, the value
last assigned to the variant is assigned to x. Ordinarily the compiler
could assume that a.c had retained the value 'A', because no further
assignments had been made directly to a.c. However, the value of a.c
changed unexpectedly through the assignment to a.i. Therefore, unless
the record a is declared VOLATILE, the result of the assignment
x := a.c would be undefined because the compiler's legitimate
assumptions had been incorrect.
Consider the following example:
PROGRAM Volatility( OUTPUT ); VAR Pint : ^[VOLATILE] INTEGER; i : INTEGER; j : [VOLATILE] INTEGER; a : ARRAY[0..10] OF INTEGER; {In the executable section:} NEW( Pint ); i := 0; j := 0; Pint^ := 0; {Compiler may assume i = 0, makes no assumptions about j} WRITELN( i, j, Pint^, a[i] ); {Values are 0, 0, 0, a[0] } Pint := ADDRESS( j ); {Pint^ now = j} Pint^ := 1; {Therefore j now = 1} {Compiler may assume i = 0, makes no assumptions about j} WRITELN( i, j, Pint^, a[i] ); {Values are 0, 1, 1, a[0]} Pint := ADDRESS( i ); {Causes a warning message because i is not VOLATILE} Pint^ := 2; {Compiler may assume i = 0 and a[I] = a[0], May make no assumptions about j} WRITELN( i, j, Pint^, a[i] ); {Actual values are 2, 1, 2, a[2]} |
This example assigns values to the variables i and j and to the newly created variable Pint^. The comments show the difference between the assumptions the compiler can legally make about the values of the variables and the values actually contained in the variables. The compiler's assumption about the value of i was incorrect because the value of i changed unexpectedly. The ADDRESS( i ) call caused Pint to point to i (that is, Pint^ and i became the same variable). When Pint^ was assigned the value 2, the variable i also received the value 2. Since i had been initialized to 0 and was not directly referred to in the rest of the program, the compiler assumed that a reference to i at this point would be equivalent to a reference to 0. Likewise, the compiler also assumed that a reference to a[i] would be equivalent to a reference to a[0]. However, when execution ceases, the value of i is 2 and the value of a[i] is the value of a[2].
Depending on the optimizations the compiler made based on the value of i, any operations performed after the unanticipated assignment to i could yield unexpected results. Because j was declared VOLATILE, the compiler did not optimize code based on the value of j. Therefore, any reference to j yields the expected results.
The ADDRESS( i ) call in this program causes a warning message. TheHP Pascal compiler assumes that pointer variables point only to variables in heap-allocated storage and not to statically allocated, nonvolatile variables such as i. So, ADDRESS( i ) in this case differs from the expected usage.
The WEAK_EXTERNAL attribute specifies that a variable or routine is not critical to the linking operation. To resolve a weak reference, the linker searches only the named input modules. You can specify an identifier with this attribute to indicate the name by which the corresponding object is known to the linker.
{identifier } [ WEAK_EXTERNAL [[ ( {'string-literal' } ) ]] ] { } |
Identifier passed to the linker. If you omit the identifier, the name of the variable is used as the name of the common block.identifier
Compilation units cannot have the EXTERNAL or WEAK_EXTERNAL attribute.
The WEAK_GLOBAL attribute specifies that an object is linked only when it is specifically included in the linking operation. To resolve a weak reference, the linker searches only the named input modules. You can specify an identifier to indicate the name by which the corresponding object is known to the linker.
{identifier } [ WEAK_GLOBAL [[ ( {'string-literal' } ) ]] ] { } |
Identifier passed to the linker. If you omit the identifier, the name of the variable is used as the name of the common block.identifier
The WORD attribute specifies the amount of storage in words to be received by the object.
WORD [[( n )]] |
The optional constant n indicates the number of word storage units.
The WRITEONLY attribute specifies that an object can have values assigned to it but cannot be read by a program.
Usage and Default Information:
Consider the following example:
PROGRAM SAMPLE; TYPE W_Only = [WRITEONLY] INTEGER; VAR Writ_Int : W_Only; Norm_Int : INTEGER; PROCEDURE Try_Access( VAR Write_Param : W_Only ); EXTERNAL; {In the executable section:} Writ_Int := SQR( Norm_Int ); Try_Access( Writ_Int ); |
This example shows legal statements involving write-only variables. The write-only variable Writ_Int is assigned the result of the square root operation, and is then passed as an actual parameter to a write-only formal parameter.
An attribute class can consist of a single attribute or of several attributes with a common characteristic. Table 10-7 lists the classes and their attributes.
Class | Attributes | Description of Attributes |
---|---|---|
Alignment | ALIGN, ALIGNED, UNALIGNED | Indicate whether the object should be aligned on a specific address boundary in memory. |
Allocation |
AT, AUTOMATIC,
COMMON, STATIC, PSECT |
Indicate the form of storage that the object should occupy. |
Asynchronous | ASYNCHRONOUS | Indicates that the routine can be called by an asynchronous event, such as a condition handler. |
Check | CHECK | Indicates error-checking options to be enabled or disabled. |
Double
precision |
FLOAT | Indicates the type of precision to use for objects of type DOUBLE. |
Enumeration | ENUMERATION_SIZE | Indicates the sizes used for enumerated types and Boolean types. |
Environment |
ENVIRONMENT,
PEN_CHECKING_STYLE |
Indicate that HP Pascal creates an environment file, which allows compilation units to share data definitions and declarations. |
Hidden | HIDDEN | Indicates exclusion of a declaration or definition from a created environment file. |
Ident | IDENT | Indicates the identification of a compilation unit to be passed to the linker. |
Inherit | INHERIT | Indicates that the compilation unit can use the definitions and declarations specified in the inherited environment file. |
Initialize | INITIALIZE | Indicates that the procedure is to be called before execution of the main program. |
Key | KEY | Indicates key information for a record field that is used when accessing data in an indexed file. |
List | LIST | Indicates that the routine can be called with actual parameter lists of various lengths. |
Optimization | OPTIMIZE, NOOPTIMIZE | Indicate whether HP Pascal should optimize code. |
Parameter
passing |
CLASS_A, CLASS_NCA,
CLASS_S, IMMEDIATE, REFERENCE |
Indicate the passing mechanism to be used for a parameter. |
Position | POS | Indicates that a record field should be forced to a specific bit position. |
Read-only | READONLY | Indicates that the object can be read but cannot be written to. |
Size |
BIT, BYTE, WORD,
LONG, QUAD, OCTA |
Indicate the amount of storage to be reserved for the object. |
Truncate | TRUNCATE | Indicates that the actual parameter list can be truncated at the position of this attribute in the formal parameter list. |
Unbound | UNBOUND | Indicates that the routine does not access automatic variables outside its scope. |
Unsafe | UNSAFE | Indicates that an object can accept values of any type without type checking. |
Value | VALUE | Indicates that the variable is a reference to an external constant or is the defining point of a global constant. |
Visibility |
LOCAL, EXTERNAL,
GLOBAL, WEAK_EXTERNAL, WEAK_GLOBAL |
Indicate the ability of an object to be shared by compilation units. |
Volatile | VOLATILE | Indicates that the value of an object can change at unusual points in program execution. |
Write-only | WRITEONLY | Indicates that the object can be written to but cannot be read. |
Some attributes are allowed to appear on routine declarations, routine parameters, and compilation units. Table 10-8 lists these attribute classes.
Class | Program Element | ||
---|---|---|---|
Routine Parameter |
Routine | Compilation Unit |
|
Allocation | No | Yes 1 | Yes 1 |
Asynchronous | Yes | Yes | No |
Check | No | Yes | Yes |
Double precision | No | No | Yes |
Enumeration | No | No | Yes |
Environment | No | No | Yes |
Ident | No | No | Yes |
Inherit | No | No | Yes |
Initialize | No | Yes | No |
List | Yes 2 | No | No |
Optimization | No | Yes | Yes |
Truncate | Yes | No | No |
Unbound | Yes | Yes | No |
Visibility | No | Yes | Yes 3 |
Previous | Next | Contents | Index |