Chapter Contents |
Previous |
Next |
Code Generation Conventions |
This section describes reentrant
and non-reentrant identifiers and explains how to use the
rent
,
rentext
, and
norent
compiler options as well as
the
__rent
and
__norent
keywords to control
whether an identifier is reentrant or non-reentrant.
The reentrant and non-reentrant attributes apply only
to
extern
or
static
data. All functions, parameters, and automatic
data are automatically reentrant.
Non-reentrant Identifiers |
The compiler places non-reentrant data in the
static
CSECT. Wherever possible, non-reentrant data are initialized
at compile time and are referenced using address constants (ACONs).
Reentrant Identifiers |
Placement of Data |
In general,
static
and
extern
identifiers can
be placed in either the non-reentrant section or the reentrant section (PRV).
A number of rules control where a particular identifier is placed.
First, if you code an explicit
__rent
or
__norent
keyword, then the identifier is always placed in the section
specified. With
__rent
and
__norent
you can control
which section is used.
If you do not provide an explicit keyword, then generally
the
rent
,
rentext
or
norent
compiler option determines the section into which the identifier is placed.
rent
places both
externs
and
statics
(without a
__rent
or
__norent
keyword) in the
reentrant section.
norent
places them both in the non-reentrant
section.
rentext
places
externs
in the reentrant
section and
statics
in the non-reentrant section.
There are two exceptions (cases where the compiler option
is overridden). The first exception occurs with
extern
identifiers whose
names start with an underscore. These are always placed in the reentrant
section. (The ISO/ANSI C Standard reserves such names for use by the compiler
implementor).
The second exception occurs if the
const
keyword is used.
const
declares constant data. Since the data are
not expected to change during program execution, the compiler tries to promote
const
identifiers into the non-reentrant section. The rules for this
are fairly complicated. An identifier is promoted to the non-reentrant section
if all of the following are true:
const
keyword.
volatile
keyword.
__rent
keyword.
static
scope or, if
extern
, the first letter of the identifier's name is not an underscore.
The
const
type qualifier is ignored (not
used to place the data object in the string literal CSECT) in the following
situations:
volatile
type
qualifier
__local
function pointer.
Initialization and Reentrancy |
rent
or
rentext
compiler option was specified; that is, you requested that a reentrant
executable be created.
Declarations Must Agree |
This applies not only to explicit use of the
__rent
and
__norent
keywords, but to the implicit assignment
of data to the reentrant and non-reentrant section using compiler options
and the
const
keyword, as described above.
All declarations of an identifier must agree. Use the
same
rent
,
rentext
, and
norent
settings for all compilations, or use the
__rent
or
__norent
keywords.
Cross-reference |
The cross-reference tells you whether an identifier is reentrant
(
rent
is listed) or non-reentrant (
norent
is listed). This
information is produced regardless of how the reentrancy was determined (keywords,
compilation options, etc). This may be helpful to you in cases where the
rules above are not clear.
Sharing External Variables with Assembler Language Programs |
External variables stored in the static CSECT can be accessed from assembler language programs via a V-type address constant (VCON). Accessing an external variable stored in a pseudoregister must be done indirectly by computing the offset of the variable in the pseudoregister vector. The address of the pseudoregister vector is stored at decimal offset 12 from the address in general register 12. (This area is known as CRABPRV.) Sample Assembler Language Routine for Accessing an External Variable Stored as a Pseudoregister sketches an assembler language routine that accesses an external variable stored as a pseudoregister.
Sample Assembler Language Routine for Accessing an External Variable Stored as a Pseudoregister
LRX,12(,R12) Set RX to point to CRABPRV. This assumes that register 12 has the CRAB address. ALRX,=Q(ZZZ) RX now contains the address of the external variable USING ZZZ,RX ZZZ. ZZZ is the name of the variable as defined in the C program. MVCZZZ1,=F'2' Set integer variable to 2. . . . ZZZ DSECT Identify the dummy section ZZZ. ZZZ1 DSF
Sharing External Variables with FORTRAN Programs |
It is possible for a C program that has been compiled with
rent
or
rentext
to share data with
FORTRAN programs. The
values to be shared are in one or more FORTRAN COMMON blocks, where FORTRAN
code can access them directly. C code accesses the COMMON blocks through function
pointers. Each COMMON block is described by a C structure, with the structure
tag the same as the name of the COMMON. Each COMMON block code is declared
as a function of the same name. For example, the following code declares the
COMMONs named
comona
and
comonb
:
extern comona(); extern comonb();
C code accesses the COMMONs through pointers. Each pointer
is set up by invoking a macro, called
COMPTR
, in the example
below. The complete definition for the
comona
structure is assumed
to be elsewhere in the program:
#define comptr(block) (*(struct block**)&block) . . . struct comona *aptr; /* Declare aptr as pointer to comona struct. */ aptr = comptr(comona); aptr->field1 = 1; . . .
Note that the structure tag,
comona
, is the same as
the name of the COMMON. This is not required, but it simplifies the macro
and makes the data sharing more obvious.
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.