United States    
COMPAQ STORE | PRODUCTS |
SERVICES | SUPPORT | CONTACT US | SEARCH
C++
Compaq C++

Compaq C++
Using Compaq C++ for OpenVMS Alpha


Previous Contents Index


Chapter 9
Using 64-bit Address Space

Caution

This initial implementation of 64-bit pointers is subject to change based on customer feedback.

The introduction of 64-bit address space in OpenVMS greatly increases the amount of memory available to applications. Compaq C++ has been enhanced to permit use of this memory. The compiler provides a great deal of flexibility about how this memory can be used. Conceptually, this flexibility can be viewed as four models for development:

In a 32-bit development environment, all pointers are 32-bits long and only 2 gigabytes of address space is available. This is the default and was the only option that was available before this version of the compiler. In a 64-bit development environment, all pointers are 64-bits long and the address space is over a billion gigabytes.

Working in a homogeneous 32-bit or 64-bit environment is the prefered and recommended way to do development. Compaq C++ for OpenVMS, combined with the C Run-Time library, provide a seemless environment for development. It should be possible for a well written, portable program developed using 32-bit pointers to be recompiled and relinked to use 64-bit pointers.

Because it is not always possible or desirable to work in a homogeneous pointer environment. Compaq C++ supports mixed pointer sizes, however, it requires greater care by developers. Some contexts where heterogeneous pointer sizes might be used are:

When the memory requirements of a 32-bit application begins to exceed 2 gigabytes, the most straight forward solution is to convert the application to be a 64-bit application. Since practical considerations, like the size of the application or the lack of source code for all parts can prevent this, the alternative approach of isolating the use of 64-bit pointers to a small portion of the application may be preferable. In this situation, development would continue in the 32-bit environment, using long pointers when necessary.

When doing 64-bit development, there are times when it becomes necessary or desirable to use 32-bit pointers. The most common instance is interfacing with a 32-bit library. Another is to save space, because 64-bit pointers consume twice as much memory as 32-bit pointers. In this situtation, development could be done in a 64-bit environment, using short pointers when necessary.

Limited empirical envidence suggests that using 32-bit pointers to save space can reduce memory consumption by approximately 25% but at the cost of greater complexity and the creation of potentially unneccessary constraints in the application.

9.1 32-bit Versus 64-bit Development Environment

Besides pointer size, the following components of the development environment determine whether it is a 32- or 64-bit environment:

Memory allocators control where in the address space memory is allocated. Memory can be allocated in 32- or 64-bit space independent of the pointer size. The default memory allocator is appropriate for the development environment being used.

Libraries in a 32-bit environment expect pointers to be 32-bits and memory to reside in the 32-bit address space, while libraries in the 64-bit environment expect pointers to be 64-bits. Compaq C++ for OpenVMS ships with two libraries: one for the 32-bit environment and one for the 64-bit environment. In addition to supporting the 64-bit environment, the second library also supports the new object model refered to as model ANSI.

The C Runtime is a single library that supports both environments. See the Compaq C Run-Time Library Reference Manual for OpenVMS Systems for information about how support for both environments was achieved with a single library. See Section 9.5 for a discussion of why it is difficult to produce a single C++ library to support both environments.

9.1.1 Model ANSI

The new ANSI object model allows the compiler to better conform to the ANSI/ISO C++ standard while providing the 64-bit development environment. This object model is specified using the /MODEL=ANSI compiler and link options. To build a 64-bit application using the ANSI object model, you enter commands in the following format:


$ cxx /model=ansi filename.cxx
$ cxxlink/model=ansi filename

9.1.2 Memory Allocators

In C++, the primary memory allocator is new . Use of the default allocators causes memory to be allocated that is appropriate for the default pointer size for the module (not the current pointer size). Specialized placement-new allocators can be used to control where an object is allocated. The header newext.hxx contains the following definitions:


enum addr32_t (addr_32 }; 
enum addr64_t {addr_64 }; 
 
#pragma pointer_size short 
void *operator new(addr32_t, size_t s) { return _malloc32(s); } 
void *operator new[](addr32_t, size_t s) { return _malloc32(s); } 
 
#pragma pointer_size long 
void *operator new(addr64_t, size_t s) { return _malloc64(s); } 
void *operator new[](addr64_t, size_t s) { return _malloc64(s); } 

Use of the allocators from the C Run Time is also possible. You can select a specific C allocator by adding a prefix underbar and either 32 or 64 as a suffix.
Function 32-bit 64-bit
malloc _malloc32 _malloc64
calloc _calloc32 _calloc64
realloc _realloc32 _realloc64
strdup _strdup32 _strdup64

When attempting to mix pointer sizes in your program, distinguish between the concepts of pointer size and memory allocators. The pointer size dictates the maximum amount of address space a pointer can reference, while the allocator controls the where the memory will be allocated.

A library implemented with 64-bit pointers that uses only a 32-bit allocator can with care be used by an application that uses 32-bit pointers. If the library uses a 64-bit allocator, the application cannot reference any pointers returned. To a large extent, it is the memory allocator, not the pointer size, that determines interoperability.

9.1.3 64-bit Pointer Support in the C Run Time Library

In addition to allocators, other functions in the C Run Time Library, such as strcpy , are affected by pointer size. As with the alloators, the C++ compiler calls a version of the routine is for the development environment. See the Compaq C Run-Time Library Reference Manual for OpenVMS Systems for more details.

9.2 Qualifiers and Pragmas

The following qualifiers, pragmas, and predefined macros control pointer size:

9.2.1 The /MODEL=ANSI Qualifier

The /MODEL=ANSI qualifier enables the new ANSI object model. This model implies /POINTER_SIZE=LONG in addition to supporting new C++ constructs that could not be supported in the object object model designed to support the ARM definition of the language. This option must be specified during compilation and linking.

9.2.2 The /POINTER_SIZE Qualifier

The /POINTER_SIZE qualifier lets you specify a value of 64 or 32 (or LONG or SHORT) as the default pointer size within the compilation unit. You can compile one set of modules using 32-bit pointers and another set using 64-bit pointers. Take care when these two separate groups of modules call each other.

The default is /NOPOINTER_SIZE, which has the following effects:

This default represents no change from previous versions of Compaq C++.

Specifying /POINTER_SIZE with a keyword value (32, 64, SHORT, or LONG) has the following effects:

Use of the /POINTER_SIZE qualifier also influences the processing of Compaq C RTL header files:

See the Compaq C Run-Time Library Reference Manual for OpenVMS Systems for more information on the impact of 64-bit pointer support on Compaq C++ RTL functions.

9.2.3 The __INITIAL_POINTER_SIZE Macro

The __INITIAL_POINTER_SIZE preprocessor macro is useful for header-file authors to determine:

Header-file code can then be conditionalized using the following preprocessor directives:


#if defined (__INITIAL_POINTER_SIZE) /* Compiler supports 64-bit pointers */ 
#if __INITIAL_POINTER_SIZE > 0       /* Application uses 64-bit pointers */ 
#if __INITIAL_POINTER_SIZE == 32   /* Application uses some 64-bit pointers, 
                                       but default RTL routines are 32-bit.*/ 
 
#if __INITIAL_POINTER_SIZE == 64   /* Application uses 64-bit pointers and 
                                       default RTL routines are 64-bit. */ 

9.2.4 Pragmas

The #pragma pointer_size and #pragma required_pointer_size preprocessor directives can be used to change the pointer size currently in effect within a compilation unit. You can default pointers to 32-bits and then declare specific pointers within the module as 64-bits. In this case, you also need to specifically call the appropriate allocator to obtain memory from the 64-bit memory area.

These pragmas have the following format:

#pragma pointer_size keyword
#pragma required_pointer_size keyword

The keyword is one of the following:
{ short |32} 32-bit pointer
{ long |64} 64-bit pointer
save Saves the current pointer size
restore Restores the current pointer size to its last saved state

The #pragma pointer_size and #pragma required_pointer_size directives work essentially the same way, except that #pragma required_pointer_size always takes effect regardless of command-line qualifiers, while #pragma pointer_size is in effect only when the /POINTER_SIZE command-line qualifier is used.

By changing the command-line qualifier, #pragma pointer_size allows a program to be built using 64-bit features as purely as a 32-bit program.

The #pragma required_pointer_size is intended for use in header files where interfaces to system data structures must use a specific pointer size regardless of how the program is compiled.

An alternative to controling the pointer size is #pragma environment . This pragma controls all compiler states that include pointer size. This pragma is fully documented in Section 2.1.1.2. The primary change for support of long pointers is the addition of a new cxx_header_defaults keyword.

This new keyword is similar to the header_defaults keyword, but differs in the effect on pointer_size . With header_defaults, pointer_size is made short, while with cxx_header_defaults, the pointer_size depends on the model being used. When developing in model ANSI, the pointer_size is 64 bits; in model ARM (the default), it is 32 bits.

9.3 Determining Pointer Size

The pointer-size qualifiers and pragmas affect only a limited number of constructs in the C++ language itself. At places where the syntax creates a pointer type, the pointer-size context determines the size of that type. Pointer-size context is defined by the most recent pragma (or command-line qualifier) affecting pointer size.

Here are examples of places in the syntax where a pointer type is created:

9.3.1 Special Cases

The following special cases are not affected by pointer-size context:

9.3.2 Mixing Pointer Sizes

An application can use both 32-bit and 64-bit addresses. The following semantics apply when mixing pointers:

9.4 Header File Considerations

Take note of the following general header-file considerations:

Be aware that pointer-size controls are not unique in the way they affect header files; other features that affect data layout have similar impact. For example, most header files should be compiled with 32-bit pointers regardless of pointer-size context. Also, most system header files (on Alpha systems) must be compiled with member_alignment regardless of user pragmas or qualifiers.

To address this issue more generally, you can use the pragma environment directive to save context and set header defaults at the beginning of each header file, and then to restore context at the end. See Section 2.1.1.2 for a description of pragma environment .

9.5 Avoiding Problems

Consider the following suggestions to avoid problems related to pointer size:

9.6 Reasons for Not Using Mixed Pointer Sizes

Although Compaq C and C++ allow mixing pointer sizes, mixed pointers can cause certain types of error when used incorrectly. Consider the following examples:

Furthermore, the following C++ features discourage the use of mixed pointers:


Previous Next Contents Index
  

1.800.AT.COMPAQ

privacy and legal statement