DIGITAL C++
Using DIGITAL C++ for DIGITAL UNIX Systems


Previous Contents Index


Chapter 2
DIGITAL C++ Implementation

This chapter discusses the features and characteristics specific to the DIGITAL C++ implementation, including pragmas, predefined names, numerical limits, and other implementation-dependent aspects of the language definition.

2.1 Compatibility with Other C++ Compilers

In default mode (-std ansi), the DIGITAL C++ compiler implements most features of the Final Draft International ANSI C++ Standard (FDIS), including:

A std -arm mode provides compatibility with previous DIGITAL C++ compiler versions, which implement the language definition as specified in The Annotated C++ Reference Manual. For stricter ANSI operation, users can specify -strict_ansi or -strict_ansi_errors mode.

Note that because the current compiler performs more error checking than previous versions, it generates significantly more diagnostic messages. However, you can use the -msg_quiet option to relax error checking and reduce the severity of many diagnostics. See Section 2.4.

To enhance compatibility with other C++ compilers, DIGITAL C++ supports options that direct the compiler to interpret the source program according to certain rules followed by other implementations. The currently supported options are:

These options direct the DIGITAL C++ compiler to interpret your source code, as far as possible, according to conventions used by other C++ implementations.

2.2 Implementation-Specific Attributes

This section describes pragmas, predefined names, and limits placed on the number of characters and arguments used in DIGITAL C++ programs.

2.2.1 #pragma Preprocessor Directive

The #pragma preprocessor directive is a standard method for implementing features that differ from one compiler to the next. This section describes pragmas specifically implemented in the DIGITAL C++ compiler for DIGITAL UNIX systems.

Although certain #pragma directives are subject to macro expansion, not all of those new to the language in this and later releases are subject to such expansion. Therefore, users should not write programs that rely on macro expansion of the newer pragmas.

2.2.1.1 #pragma define_template Directive

The #pragma define_template preprocessor directive instructs the compiler to define a template with the arguments specified in the pragma. This pragma has the following syntax:

#pragma define_template name < template-argument-list >

For example, the following statement instructs the compiler to define the template mytempl with the arguments arg1 and arg2:


#pragma define_template mytempl<arg1, arg2> 

For more information on how to use templates with the #pragma
define_template directive, see Chapter 5.

2.2.1.2 #pragma instantiate Directive

DIGITAL C++ provides several other pragmas that provide finer control over the instantiation process. Instantiation pragmas can be used to control the instantiation of specific template entities or sets of template entities. There are two instantiation pragmas:

For more information on how to use templates with the #pragma instantiate directive, see Chapter 5.

2.2.1.3 #pragma environment Directive

The #pragma environment preprocessor directive offers a way to single-handedly set, save, or restore the states of context pragmas. This directive protects include files from contexts set by encompassing programs and protects encompassing programs from contexts that could be set in header files that they include.

On DIGITAL UNIX systems, the #pragma environment directive affects the following pragmas:

This pragma has the following syntax:

#pragma environment command_line
#pragma environment header_defaults
#pragma environment restore
#pragma environment save

command_line

Sets, as specified on the command line, the states of all the context pragmas. You can use this pragma to protect header files from environment pragmas that take effect before the header file is included.

header_defaults

Sets the states of all the context pragmas to their default values for DIGITAL UNIX systems. This is almost equivalent to the situation in which a program with no command-line options and no pragmas is compiled.

restore

Restores the current state of every pragma that has an associated context.

save

Saves the current state of every pragma that has an associated context.

Someone who creates a general purpose library, distributed as an archive or shared library, typically distributes header files that specify the interface to the library. For calls to the library to work, the header file must normally use the same member alignment, pointer size, extern model, and other compilation options as when the library was built. That header file should contain pragmas to save the user's compilation options, set the correct compilation options for the library, and then restore the user's compilation options when the include file ends. The pragmas let library users choose whatever compilation options are appropriate for their own code without unintentionally affecting the interface to the library.

Not only is the #pragma environment preprocessor directive more convenient than explicitly specifying each individual pragma that controls a compilation option, it is also upwardly compatible. As new pragmas are added to DIGITAL C++, #pragma environment header_defaults will be enhanced to set the state of the new pragmas to their default. Thus, a header file that uses #pragma environment sets a known state for not only the current pragmas in DIGITAL C++, but future pragmas as well. Without requiring further changes to the source code, you can use #pragma environment to protect header files from things like language extensions and enhancements that might introduce additional contexts.

A header file can selectively inherit the state of a pragma from the including file and then use additional pragmas as needed to set the compilation to nondefault states. For example:


#ifdef __PRAGMA_ENVIRONMENT 
#pragma __environment save  (1)
#pragma __environment header_defaults (2)
#pragma member_alignment restore (3)
#pragma member_alignment save (4)
#endif 
. 
.  /* contents of header file */ 
. 
#ifdef __PRAGMA_ENVIRONMENT 
#pragma __environment restore 
#endif 

In this example:

  1. Saves the state of all context pragmas
  2. Sets the default compilation environment
  3. Pops the member alignment context from the #pragma member_alignment stack that was pushed by #pragma __environment save (restoring the member alignment context to its preexisting state)
  4. Pushes the member alignment context back onto the stack so that the #pragma __environment restore can pop off the entry

Thus, the header file is protected from all pragmas, except for the member alignment context that the header file was meant to inherit.

2.2.1.4 #pragma [no]member_alignment Directive

By default, the DIGITAL C++ compiler aligns structure members so that members are stored on the next boundary appropriate to the type of the member; that is, bytes are on the next byte boundary, words are on the next word boundary, and so on.

You can use the #pragma member_alignment preprocessor directive to explicitly specify member alignment. For example, using #pragma member_alignment aligns a long variable on the next longword boundary, and it aligns a short variable on the next word boundary.

Using #pragma nomember_alignment causes the compiler to align structure members on the next byte boundary regardless of the type of the member. The only exception to this is for bit-field members.

If used, the nomember_alignment pragma remains in effect until the compiler encounters the member_alignment pragma.

This pragma has the following syntax:

#pragma member_alignment
#pragma member_alignment save
#pragma member_alignment restore
#pragma nomember_alignment [base_alignment]

restore

Restores the current setting of the member_alignment pragma.

save

Saves the current setting of the member_alignment pragma.

2.2.1.5 #pragma pack Directive

The #pragma pack preprocessor directive specifies the byte boundary for packing members of C structures and C++ classes.

The #pragma pack directive has the following format:

#pragma pack [(n)]

n specifies the new alignment restriction in bytes as follows:
1 Align to byte
2 Align to word
4 Align to longword
8 Align to quadword
16 Align to octaword

A structure member is aligned to either the alignment specified by #pragma pack or the alignment determined by the size of the structure member, whichever is smaller. For example, a short variable in a structure gets byte-aligned if #pragma pack (1) is specified. If #pragma pack (2), (4), or (8) is specified, the short variable in the structure gets aligned to word.

If #pragma pack is not used, or if (n) is omitted, packing defaults to 8 on DIGITAL UNIX systems.

2.2.1.6 #pragma pointer_size Directive

The #pragma pointer_size preprocessor directive controls pointer size allocation for the following:

For this pragma to have any effect, you must specify -xtaso, -xtaso_short, -vptr_size, or -vptr_size_short on the cxx command.

This pragma has the following syntax:

#pragma pointer_size {long|64}
#pragma pointer_size {short|32}
#pragma pointer_size restore
#pragma pointer_size save

long, or 64

Sets as 64 bits all pointer sizes in declarations that follow this directive, until the compiler encounters another #pragma pointer_size directive.

short, or 32

Sets as 32 bits all pointer sizes in declarations that follow this directive, until the compiler encounters another #pragma pointer_size directive.

restore

Restores the saved pointer size from the pointer size stack.

save

Saves the current pointer size on a pointer size stack.

The save and restore option are particularly useful for specifying mixed pointer support and for protecting header files that interface to older objects. Objects compiled with multiple pointer size pragmas will not be compatible with old objects, and the compiler cannot discern that incompatible objects are being mixed.

Use of short pointers is restricted to DIGITAL C++ and the C compilers resident on DIGITAL UNIX systems. Programs should not attempt to pass short pointers from C++ routines to routines written in any other language except the C programming language. Also, DIGITAL C++ may require explicit conversion of short pointers to long pointers in applications that use short pointers. You should first port those applications in which you are considering using short pointers, and then analyze them to determine if short pointers would be beneficial.

A difference in the size of a pointer in a function declaration is not sufficient to overload a function.

DIGITAL C++ issues an error-level diagnostic if:

2.2.1.7 #pragma required_pointer_size Directive

The #pragma required_pointer_size preprocessor directive controls pointer size allocation in the same way as #pragma pointer_size but without interaction with command-line options. This pragma is always enabled, whether or not you specify any pointer size options on the command line. The same syntax, precautions, and restrictions pertain as with #pragma pointer_size. Neither the pragma name nor its arguments are subject to macro expansion.

2.2.1.8 #pragma required_vptr_size Directive

The #pragma required_vptr_size preprocessor directive controls pointer size allocation in the same way as #pragma required_pointer_size, but it applies to virtual function pointers and virtual bases in a C++ class object. This pragma has the following syntax:

#pragma required_vptr_size {long|64}
#pragma required_vptr_size {short|32}
#pragma required_vptr_size restore
#pragma required_vptr_size save

The parameters have the same meaning as with #pragma required_pointer_size (see Section 2.2.1.6).

The #pragma required_vptr_size directive takes effect at the opening brace of a class declaration. This pragma is always enabled, whether or not you specify any pointer size options on the command line.

2.2.2 Predefined Names

Table 2-1 lists the predefined C++ macros used by DIGITAL C++. For information on using predefined macros in header files in the common language environment, see Section 3.1.

Table 2-1 Predefined Macros
Macro Description
_BOOL_EXISTS Indicates that bool is a keyword
_WCHAR_T Indicates that wchar_t is a keyword
__DATE__ A string literal containing the date of the translation in the form Mmm dd yyyy , or Mmm d yyyy if the value of the date is less than 10
__FILE__ A string literal containing the name of the source file being compiled
__TIME__ A string literal containing the time of the translation in the form of hh:mm:ss
__LINE__ A decimal constant containing the current line number in the C++ source file

Table 2-2 lists other names predefined by DIGITAL C++.

Table 2-2 Other Predefined Names
Name  
__cplusplus Language identification name.
__DECCXX Language identification name.
__INITIAL_POINTER_SIZE A decimal constant containing the initial pointer size allocation, as specified by the command line. Valid values are: 0 (no pointer size option set), 32 (short or 32-bit pointers allocated), and 64 (long or 64-bit pointers allocated).

On DIGITAL UNIX systems, DIGITAL C++ supports the predefined macro names described in Table 2-3.

Table 2-3 Predefined Macros Specific to DIGITAL UNIX Systems
Name Description
__alpha System identification name
__host_alpha System identification name
__osf__ System identification name
__unix System identification name
__unix__ System identification name

C++ programmers using both DIGITAL UNIX and OpenVMS Alpha operating systems should use the predefined macro __alpha for code that is intended to be portable from one system to the other.

Predefined Implementation Compatibility Macros

Table 2-4 shows the macro names for the listed command-line options.

Table 2-4 Implementation Compatibility Macros
Command-line Option Macro Name
-implicit_include __IMPLICIT_INCLUDE_ENABLED
-global_array_new __GLOBAL_ARRAY_NEW
-pch , -create_pch , -use_pch __PCH_ENABLED
-stdnew __STDNEW
-std cfront, -cfront __CFRONT , __STD_CFRONT
-std ms, -ms __MS , __STD_MS
-std arm __STD_ARM
-std ansi __STD_ANSI
-std strict_ansi __STD_STRICT_ANSI
-std strict_ansi_errors __STD_STRICT_ANSI_ERRORS

Predefined __DECCXX_VER Version Number Macro

The __DECCXX_VER macro provides an integer encoding of the compiler version-identifier string that is suitable for use in a preprocessor #if expression, such that a larger number corresponds to a more recent version.

The format of the compiler version-identifier string is:


TMM.mm-eee

Where:

The format of the integer encoding for __DECCXX_VER is:


vvuuteeee

Where:

Table 2-5 __DECC_VER Version-Type Encodings
Type Numerical Encoding Description
T 6 Field-test version
S 8 Customer special
V 9 Officially supported version

The following describes how the __DECCXX_VER integer value is calculated from the compiler version-identifier string:

  1. The major version is multiplied by 10000000.
  2. The minor version (the digits between the period (.) and any edit suffix) is multiplied by 100000 and added to the suffix value (the suffix value has a range of 0 to 999).
  3. If the character immediately preceding the first digit of the major version number is one of those listed in Table 2-5, its numerical encoding is multiplied by 10000.
  4. The preceding values are added together.

The following examples show how different compiler version-identifier strings map to __DECCXX_VER encodings:


Previous Next Contents Index