Professional Documents
Culture Documents
TPSEC02
TPSEC02
• Keywords
• Declarations on page 2-2
° Storage Class Specifier on page 2-2
° Type Specifier on page 2-7
° Type Qualifier on page 2-9
° Attribute Specifier on page 2-10
• Pointer Modifiers on page 2-15
• Operators on page 2-18
• Data Types on page 2-20
This section describes the language extensions to the ISO/ANSI C standard that are
supported by the HP native C and C++ compilers, the TNS C compiler, and the TNS
C++ preprocessor.
Keywords
A keyword is a word symbol that has a special predefined syntactic or semantic
meaning in a programming language. Table 2-1 lists the reserved keywords that HP
has added as extensions to the C and C++ languages. Table 2-1 notes whether there
are differences between using the keyword in the native or TNS environment.
Native C and C++ treat these HP extensions as keywords only if the EXTENSIONS
pragma is in effect. This feature allows you to choose to compile a program so that
standards conformance is enforced. This feature also ensures the acceptance of a
Declarations
This subsection lists all the extensions HP has made to the declaration-
specifier syntax defined in the ISO/ANSI C standard. These syntax extensions also
apply to C++, because the rules for C are a subset of the rules for C++. In some cases,
C++ imposes additional usage considerations.
The storage-class-specifier, type-specifier, and type-qualifier are
defined in the ISO/ANSI C standard. Any extensions to these specifiers are described
in this subsection. The attribute-specifier is a P extension and is described
later in this subsection.
declaration-specifiers:
storage-class-specifier [ declaration-specifiers ]
type-specifier [ declaration-specifiers ]
type-qualifier [ declaration-specifiers ]
attribute-specifier [ declaration-specifiers ]
_lowmem
specifies that arrays and structures in the declaration are to be stored in the user
data space instead of the extended segment (only for TNS C and C++).
Consequently, _lowmem is useful only when compiling for the large-memory model
or the wide-data model. Note that you can use _lowmem alone, or you can specify it
after the auto, extern, or static storage-class specifiers.
The _lowmem storage class specifier is applicable only in the TNS environment. In
the native environment, _lowmem has no effect on code generation or the storage
of objects. It is supported to allow source-level compatibility with TNS C and C++.
Source-level compatibility involves only accepting syntactically correct TNS
programs, not diagnosing semantic violations with _lowmem usage.
° Variables declared within function bodies and variables declared within blocks
have the default storage class auto.
° Variables defined outside of a function have the default storage class extern.
Examples
This example shows how _lowmem affects allocation of data storage using the large-
memory model:
#pragma XMEM
export-attribute:
export$
import$
export$
indicates that a specification is a definition and its associated members will be
exported.
import$
indicates that a specification is only a declaration and that the definition will be
found through external linkage to a library where the associated members are
exported. If applied to a definition, the definition will be treated as a declaration.
• Do not export a class definition in more than one compilation unit or load unit, and
do not mix explicit export$/import$ usage with default class definitions. That is,
linking or loading errors, or erroneous run-time type checking can occur if either
one of these two paradigms is not followed:
° Exactly one compilation unit (and one load unit) explicitly exports the class
(wholly or selectively), and all others explicitly import it.
° Every compilation unit defining the class uses a default definition (neither
export$ nor import$).
//selective exporting/importing
class C3a {
public :
int I;
int foo (void) {return I;} // Member function -
// neither exported nor imported
export$ static int J; // Exported static data member
};
int C3a::J = 1; //Definition for exported static data member
class C3b {
public :
int I;
int foo (void) {return I;} // Member function -
// neither exported nor imported
import$ static int J; // Imported static data member
};
//Error to export & import members from a class in a single compilation unit
class C5 {
public :
int I;
export$ int foo (void) {return I;} // Exported member function
import$ static int J; // Error
};
Type Specifier
For the TNS compilers, the _cc_status type specifier is a HP extension. For the
native compilers, _cc_status is a typedef in the tal.h header file, and you must
include this header file to use _cc_status.
Note. Do not write C functions or TAL procedures that set a condition code and use
_cc_status because that is an outdated programming practice. Guardian system procedures
retain this interface for reasons of compatibility only.
type-specifier
void | char | short | int | long | float | double|
signed | unsigned | bool | _cc_status |
struct-or-union-specifier | enum-specifier | typedef-name
_cc_status
indicates that a procedure does not return a value but does set a condition code.
Usage Guidelines
• If _cc_status is used as the return type for a function declaration, the language
specifier, if used, must be one of _c, _tal, or _unspecified.
• The tal.h header contains three macros that interrogate the results of a function
declared with the _cc_status type specifier. These macros are:
Examples
This example shows the difference between using the new macros defined at the D40
release and those used prior to the D40 release to examine _cc_status.
_tal _extensible _cc_status READX ( ... );
#include <tal.h>
...
_cc_status cc;
cc = READX ( ... );
/* Pre-D40 method */
if (cc == CCL) {
...
} else if (cc == CCG) {
...
}
HP C/C++ Programmer’s Guide for NonStop Systems —429301-010
2 -8
C and C++ Extensions Declarations
/* D40 method */
if (_status_lt(cc)) {
...
} else if (_status_gt(cc)) {
...
}
Type Qualifier
The _cspace type qualifier is an HP extension. The _cspace type qualifier is
applicable only in the TNS Guardian environment. _cspace is unnecessary in the
native environment; however the native compilers recognize the _cspace keyword to
provide source-level compatibility with the TNS compiler. Source-level compatibility
involves only accepting syntactically correct TNS programs, not diagnosing semantic
violations with _cspace usage.
type-qualifier
const
is described in the ISO/ANSI C standard.
_cspace
indicates that the specified constant is stored in the current code space (only for
TNS C and C++). The _cspace type qualifier must be accompanied by the const
type qualifier. For more details on the use of the _cspace type qualifier, see
Section 9, System-Level Programming.
volatile
In the ISO/ANSI C standard, if a variable is declared with the volatile type
qualifier, the variable can be modified by an agent external to the program. The
architecture of HP NonStop systems does not support external modifications to
variables by agents external to the program. For compatibility with the ISO/ANSI
C standard, HP defines volatile to mean:
• For the TNS C compiler and the TNS C++ preprocessor, the volatile type
qualifier is accepted and ignored.
• For the native C and C++ compilers, if a variable is qualified with the volatile
type qualifier, this means that loads and stores of this variable must access
memory, not a register.
For TNS C++, you cannot use volatile to distinguish specific instances of
overloaded member functions.
Attribute Specifier
The attribute specifier is an HP extension. It is used for writing system-level C and C++
functions and for declaring external routines written in other languages.
Note. The attribute specifier is an outdated syntax for mixed-language programming and is
maintained only for compatibility. To declare external routines written in another language, you
should use the FUNCTION pragma syntax as described in FUNCTION on page 13-35.
attribute-specifier:
[ language-specifier ] [ attribute [ attribute ]... ]
language-specifier
A language-specifier for a function prototype specifies the language of the
body of the external routine being declared.
attribute
specifies a function attribute.
Table 2-2 shows the effect of function attributes for each language. “Valid” indicates
that the compiler accepts the attribute. “Ignore” indicates that the compiler accepts
but ignores the attribute. “Error” indicates that the compiler issues an error.
_alias ("external-name")
identifies the name of the external routine being declared and is used for
mixed-language programming. _alias is used at bind-time for TNS C and
C++ programs or at link-time for native C and C++ programs. The external-
name argument must be enclosed in parentheses and quotation marks, as
indicated in the syntax. For example:
_alias ("MY^PROC")
Use _alias to describe the name of an external routine written in COBOL,
FORTRAN, D-series Pascal, or TAL that does not have a valid C name. The
external-name argument is neither modified (for example, upshifted) in any
manner, nor checked to verify that it is a valid identifier for the language of the
external routine.
Considerations for both the native and TNS compilers:
• A function pointer is not allowed to have an _alias attribute.
• The external-name argument cannot be introduced into the program’s
namespace.
• For C++, member functions, function templates and overloaded functions
are not allowed to have an _alias attribute.
_extensible [ ( param-count ) ]
directs the compiler to treat all parameters of the function as though they were
optional, even if some parameters are required by your code. You can add new
formal parameters to an _extensible function without recompiling callers
unless the callers use the new parameter.
_resident
causes the function code to remain in main memory for the duration of program
execution. The operating system does not swap pages of this code.
_variable
directs the compiler to treat all formal parameters of the function as though
they were optional, even if some parameters are required by your code.
Considerations for the native compilers only:
• _extensible and _variable are treated the same; _variable is a
synonym for _extensible.
Considerations for the TNS compilers only:
• A function with no prototype declaration or definition under pragma
OLDCALLS cannot be _extensible.
Examples
This function declaration declares a C or C++ function myproc, which is a TAL variable
procedure with the externally visible procedure name My^Proc:
_tal _variable _alias ("My^Proc") void myproc (short);
This example declares a function pointer pointing to a TAL integer extensible
procedure:
_tal _extensible short (*tal_func_ptr)(void);
Pointer Modifiers
The _baddr, _far, _near, _procaddr, and _waddr pointer modifiers are HP
extensions. They have been added to TNS C and C++ because the TNS architecture
has many pointer types, and it is necessary that you have a way to designate what
type of pointer is desired. For native C and C++, these pointer modifiers have no effect.
They are added to provide source-level compatibility with TNS C and C++. Source-
level compatibility involves only accepting syntactically correct TNS programs, not
diagnosing semantic violations with pointer modifier usage.
modifier-list:
modifier [ modifier-list ]
modifier:
_far | _near | _baddr | _waddr | _procaddr
modifier:
_far | _near | _baddr | _waddr | _procaddr
_far
denotes a 32-bit extended byte address.
_near
denotes a 16-bit address and points to the lower 32K of the user data segment.
_baddr
modifies _near, and denotes that the address is a byte address.
_waddr
modifies _near, and denotes that the address is a TNS word address.
_procaddr
denotes a DPCL entry point id in TNS environment.
Usage Guidelines
• For TNS C and C++, the pointer modifiers are independent of the memory model
used. A _near pointer is 16 bits for both the small and large-memory models. A
_far pointer is 32 bits for both the small and large-memory models. For native C
and C++, the pointer modifiers have no effect and are added only to provide
source-level compatibility with TNS C and C++. For native C and C++, all pointers
are 32-bit byte addresses.
• The same modifier is not allowed to appear more than once in the modifier-
list for a pointer declaration.
• The modifiers _far and _near are mutually exclusive.
• The modifiers _baddr, _waddr, and _procaddr are mutually exclusive; at most
one is allowed.
HP C/C++ Programmer’s Guide for NonStop Systems —429301-010
2-16
C and C++ Extensions Pointer Modifiers
• If _near is used to modify a pointer and neither _waddr or _baddr is specified, the
pointer can contain either a byte address or a TNS word address:
If Type Pointed To Is Then Pointer Contains
8-bit scalar * byte address
greater than an 8-bit scalar * TNS word address
void byte address
struct TNS word address
array Pointer is the same as a pointer to
an element of the array.
* Arithmetic types and pointer types are called scalar types. Integral and floating
types are collectively called arithmetic types.
• The type qualifier extptr is considered obsolete, but TNS C and C++ still support
it for _tal prototypes. Programs that use this feature will not compile with the
native C and C++ compilers.
• For TNS only, certain implicit casting of pointers might result in diagnostics.
Table 2-3 lists which implicit conversions cause a warning or an error. The column
on the far left lists the “from” pointer type and the column headings list the “to”
pointer types.
• For TNS only, the compiler generates code to perform implicit conversions for all
cases in Table 2-3, marked valid or warning. However, in the warning cases, the
resulting value may lose some information. Explicit casts can be used to override
the implicit casts.
• For TNS only, a pointer with a _baddr modifier cannot be used to access any TNS
word-addressed data types. A pointer with a _waddr modifier cannot be used to
access any byte-addressed data types.
• For TNS only, pointer arithmetic can be performed only on pointers that point to the
same address space. The address spaces are user data space and code space.
Operators
An expression comprises a sequence of operators and operands. An operator
specifies an operation that results in a value. The items on which the operator acts are
called operands. Operators that act on one operand are referred to as unary operators.
Operators that act on two operands are referred to as binary operators. This
subsection describes the extensions HP has made to the operators defined in the
ISO/ANSI C standard.
_arg_present()
The _arg_present() operator is an HP extension. _arg_present() is used to
determine the presence of a parameter in an extensible or variable function. The
compiler generates code to determine whether the supplied operand is present in the
actual function call. If the operand is present, 1 is returned; otherwise, 0 is returned.
unary-expression:
_arg_present (formal-parameter-name)
formal-parameter-name
defines the operand on which the _arg_present() operator operates.
Usage Guidelines
• The _arg_present() operator is allowed only in an extensible or variable
function.
_bitlength()
The _bitlength() operator yields the size, in bits, of its operand. Its operand can be
an expression or the parenthesized name of a type. The size is determined from the
type of the operand, which itself is not evaluated. The result is an integer constant. The
_bitlength() operator is similar to the sizeof() operator, except that for
_bitlength() the result is in bits and the unary-expression can be a bit-field
selection.
type-name
is the name of a type.
unary-expression
is a unary expression.
Usage Guideline
The _bitlength() operator cannot be applied to an operand of function type or of
incomplete type. If this application is attempted, the result is an unsigned constant
whose type is size_t.
_optional()
The _optional() operator is similar to the pTAL $OPTIONAL standard function. It
allows you to dynamically pass and omit actual parameters to extensible and variable
functions.
The first expression operand is a scalar expression that is evaluated to determine
whether an actual argument is to be evaluated and passed to the extensible or variable
function. If the first expression is zero, the second expression operand is not evaluated
and no actual argument is passed. If the first expression is not zero, the second
expression operand is evaluated and passed as the actual argument.
When the _optional() operator is used, the extensible and variable mask and count
words are computed at run-time. The code generated is slightly slower than using
“normal” calls where the mask word and count words are computed at compile time.
Usage Guidelines
• The _optional() operator can be used only as an actual argument to a variable
or extensible function.
• The first expression must be scalar.
Examples
1. This example shows a caller of an extensible function that dynamically decides to
pass one of its arguments.
_extensible foo (int, int, int);
2. This example shows a function that passes along one of its optional parameters
only if an actual parameter is supplied.
_extensible foo (int, int, int);
Data Types
The native C and C++ compilers, the TNS C compiler, and the TNS C++ preprocessor
support the predefined data types described in the ISO/ANSI C standard. In addition,
HP has added three additional data types: decimal,long long and unsigned
long long. Table 2-4 summarizes the predefined data types.
decimal
The data type decimal is an HP extension. decimal is applicable only for the native
C and TNS C languages, which use the pragma SQL.
decimal specifies the predefined decimal type, which is used to access data in an
SQL database. If you use decimal, you must specify the SQL pragma. If you want
functions to manipulate decimal variables, you must specify the SQL pragma and
include the header sqlh. For more details regarding the use of the data type
decimal, see the NonStop SQL/MP Programming Manual for C.
long long
The data type long long is a 64-bit integer. This HP extension is applicable for the
native and TNS C and C++ languages.
For TNS C++, type matching occurs for initialization, expressions, and argument lists.
Variables of type long long are allowed in all contexts that TNS C allows them.
Constants of type long long are recognized when the decimal number is followed by
the modifier LL or ll. Variables and constants of type long long are allowed in
classes and templates.
signed char
The data type signed char is an HP extension to Cfront, the TNS C++ preprocessor.
The data type signed char can be used to distinguish a specific instance of an
overloaded member function.
Table 2-5. Relationship Between WIDE Pragma and Types short, int, and long
Size Without WIDE Pragma Size With WIDE Pragma
Data Type Specified Specified
short 16 bits 16 bits
int 16 bits 32 bits
long 32 bits 32 bits
For TNS C and C++, relative sizes of the types short, int, and long depend on
whether you compile the program under the 32-bit (wide) data model.
Without the 32-bit (wide) data model: With the 32-bit (wide) data model:
char < short = int < long char < short < int = long
For application portability and compatibility with native C and C++, use the 32-bit
(wide) data model whenever possible. For more details on the WIDE pragma, see WIDE
on page 13-115. For more details on the 32-bit (wide) data model, see Two Data
Models: 16-Bit and 32-Bit on page 19-9.