This document contains information about new and changed features in HP C++ V7.4-004 for OpenVMS Integrity servers Version 8.2-1 and higher.
Revision/Update Information: This is an updated manual
Software Version: HP C++ Version 7.4-004 for OpenVMS Integrity servers Version 8.2-1 and higher.
Hewlett-Packard Company
Palo Alto, California
© Copyright 2010 Hewlett-Packard Development Company, L.P.
Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license.
The information contained herein is subject to change without notice. The only warranties for HP products and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein.
Intel and Itanium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.
UNIX is a registered trademark of The Open Group.
Portions of the ANSI C++ Standard Library have been implemented using source licensed from and copyrighted by Rogue Wave Software, Inc. All rights reserved.
Information pertaining to the C++ Standard Library has been edited and reprinted with permission of Rogue Wave Software, Inc. All rights reserved.
Portions copyright 1994-2010 Rogue Wave Software, Inc.
Contents |
This document contains the release notes for HP C++ Version 7.4-004 for OpenVMS Integrity servers. The HP C++ product requires OpenVMS Integrity servers Version 8.2-1 or higher.
The release notes for previous HP C++ versions are also included:
This section describes enhancements, changes, and problems corrected since C++ Version 7.4-004 compiler for Integrity server systems.
static const int SERVICE_ELMT_ATTR = 39; // pr_alg_stat.h line 74 and int service_elmt_attr(long serv_elmt_id) // pr_alg_service_element.h |
This section describes enhancements, changes, and problems corrected in the C++ Version 7.3 compiler for Integrity server systems.
HP C++ V7.3-009 is largely a bug-fix release of the compiler, although it does contain some significant new features including multiple version support, new exception processing mode pure_unix, new command line qualifier /EXPORT_SYMBOLS, and an unsupported/experimental mechanism for generating a customized machine_code listing. The following describes these features along with problems fixed and restrictions in this version.
Do you want the defaults for all options? [YES] NO <RET> |
Would you like to set up your system for running alternate versions of C? [NO] YES <RET> |
$ @sys$system:cxx$set_version V7.2-018 |
$ @sys$system:cxx$set_version.com The following HP C++ compiler(s) are available in SYS$SYSTEM Filename Version Defaults ------------------------------------------------------- CXX$COMPILER.EXE T7.3-018 System Default CXX$COMPILER_T07_03-018.EXE T7.3-018 CXX$COMPILER_V07_01-011.EXE V7.1-011 CXX$COMPILER_V07_02-018.EXE V7.2-018 Enter Version number or SYSTEM: V7.1-011 |
cxxl$set_condition(pure_unix); |
#include <stdio.h> #include <cxx_exception.h> void generateACCVIO() { *((int*)0) = 0; } int main() { cxxl$set_condition(pure_unix); try { generateACCVIO(); } catch(...) { puts("caught"); } } |
/EXPORT_SYMBOLS=(OPTIONS_FILE=<name> [,EXCLUDE=<list of images>] [,export_option] [,NOTEMPLATES]) |
! ! Entries added for <module> ! <symbol vector> <symbol vector> . . . |
SYMBOL_VECTOR=(<global name>={DATA | PROCEDURE}) ! <comment field> |
<unmangled name> [<promoted static flag>] [<class information>] |
|
Expected Usage:
Because shareable images almost always contain a number of objects,
the commands for creating the options file the first time might be:
$ DELETE options_file.OPT;* $ CXX SOURCE1/EXPORT_SYMBOLS=OPTIONS_FILE=options_file $ CXX SOURCE2/EXPORT_SYMBOLS=OPTIONS_FILE=options_file $ CXX SOURCE3/EXPORT_SYMBOLS=OPTIONS_FILE=options_file . . . $ CXX SOURCEn/EXPORT_SYMBOLS=OPTIONS_FILE=options_file |
// classes.h // struct base { virtual char * name() { return "Unknown"; } }; struct base2 { virtual unsigned int print() = 0; }; // switching order of base and base2 // makes thunk error go away struct parent : base, base2 { unsigned int print(); }; struct child : parent { child() {} }; // thunk.cxx #include "classes.h" int main() { child c; return 0; } |
#pragma extern_model common_block #include <string> |
The following are known problems in this release of the compiler:
5 Enhancements, Changes, and Problems Corrected in the V7.3-009 C++ Standard Library
The following problems are fixed in this version of the C++ Library:
#include <vector> int main() { std::vector<int> v; v.push_back(0); } |
istream_type& get(char_type *s, streamsize n, char_type delim); istream_type& get(char_type *s, streamsize n); |
6 Release Notes for the V7.2 C++ Compiler
This section describes enhancements, changes, and problems corrected in
the C++ Version 7.2 compiler for Integrity server systems.
6.1 New Name Mangling/Prefixing Requires Recompile from Source
The V7.2 compiler generates different mangled names from V7.1 for user code. For 32-bit (default) compilations, V7.2 prefixes mangled names with "CX3$", where V7.1 used "CXX$". C++ library names remain unchanged, using the "CXXL$" prefix for 32-bit code. Applications built with the V7.1 compiler must be fully-recompiled from source when moving to V7.2. An application containing both "CXX$" and "CX3$" prefixed names will not work correctly. |
The introduction of 64-bit pointer support, described later, uncovered some errors in the names generated by the V7.1 compiler that could introduce incorrect run-time behaviors in standard-conforming programs without any diagnostic. These behaviors could range anywhere from harmless, to subtle, to access violations - and they are very difficult to diagnose. Basically, the names generated for certain globals such as initialization guard variables, vtables, and RTTI information used to identify exceptions embed the names of types. Type names must always be treated as case-sensitive in either C or C++. The V7.1 compiler erroneously treated these names, if they happened to be less than 32-characters long, as being subject to the /NAMES= command-line qualifier, which by default uppercases them. In addition, some of these names were not being given the facility prefix of "CXX$", even though they were compiler-generated and not explicitly present in the source code.
Because the Integrity servers implementation uses object module "group sections" (sometimes called comdats) to enforce the C++ "one definition" rule, a mismatch in generated names usually results in more than one definition for the same source entity without any diagnostic; whereas on OpenVMS Alpha or in languages other than C++, a mismatch usually results in a link-time diagnostic for an unresolved reference.
V7.1 was the initial release of the Integrity servers compiler, and the effects of mismatches caused by the V7.1 naming bugs can be very subtle and difficult to diagnose. And it was important to make the mangled names produced by V7.2 for 64-bit compilations not only correct but identical to the names it produces for 32-bit compilations (except for the prefix that distinguishes the pointer-size model). Therefore it was decided to change the default prefix for 32-bit compilations in order to distinguish object code that could contain the naming bugs (prefixed by "CXX$") from object code that does not contain the naming bugs (prefixed by "CX3$").
Applications that are linked from object modules against the C++ library shareables should not be affected when fully recompiled from source using the new compiler and relinked.
Shareable images built from 32-bit C++ object modules would not generally have universal symbols prefixed by the compiler's default prefix, but rather they would normally use #pragma extern_prefix to give their universals their own namespace (or export only C-linkage names, which are unchanged in V7.2). Users of such libraries would be unaffected unless one or more universals they use actually were affected by a naming bug. From experience with the C++ libraries this is thought to be relatively uncommon. And in that case, the build of the shareable image would fail when first built from object modules compiled by the new compiler, because correcting the naming bug would change the name of such a symbol. The library provider would then need to change the symbol vector to provide the new name as a universal, and alias the old name to it, which would again leave users of the library unaffected regardless of whether they compiled with the old or new compiler.
For shareable images built from object modules compiled by V7.1 that did not use #pragma extern_prefix, but instead directly exported symbols prefixed by "CXX$" (or exported erroneously unprefixed mangled names, which can be recognized as those beginning with "_Z"), the link would also fail when built from objects produced by V7.2. But in this case all of the symbol vector entries would fail because the prefixes would be different. A solution would be a global edit to the options file to change all of the "CXX$" prefixes to "CX3$", and prepend "CX3$" to all symbols beginning with "_Z", and relink. Failures in the relink would identify symbols that were affected by the naming bugs, and those would need to be corrected as in the preceding paragraph. Finally, aliases would need to be added from the original names to the new names to make the shareable usable to code produced by either V7.1 or V7.2 compilers.
For code that must link against object modules or shareable images that cannot be recompiled from source, and which contain names affected by the naming bugs (note this does *not* include the C++ libraries), the simplest soulution is to use the V7.1 compiler if any such code needs to be recompiled. If that is not feasible, unsupported switches may be available from your support contact to ease this situation.
The need to avoid mixing V7.1 32-bit object modules with V7.2 32-bit
object modules cannot be over-emphasized - compiling one module with
V7.2 requires full recompilation from source of all object modules. The
primary purpose of changing the default prefix is to make mixing easy
to detect by examining the link map: if the map contains both "CXX$"
names and "CX3$" names, the modules containing "CXX$" names need to be
recompiled by the new compiler.
6.2 64-bit Runtime Libraries
The runtime libraries for HP C++ ship with the OpenVMS operating
system. This compiler kit adds support for 64-bit pointers, which
requires the 64-bit runtime libraries be available. Those new libraries
will ship with a future release of the OpenVMS operating system. A
patch kit for the ICXXL component of the operating system is available
which provides the new libraries for older versions of the operating
system.
6.3 64-bit Pointer Support
This version of the compiler adds support for 64-bit pointers. This support is compatible with the 64-bit pointer support in the OpenVMS Alpha C++ and C compilers. It supports the same /POINTER_SIZE command-line qualifier, the __INITIAL_POINTER_SIZE predefined macro, and the same pragmas (#pragma pointer_size and #pragma required_pointer_size). However, the basic model for how and where pointers with a size different from the default size (the size specified by the command-line qualifier) can be declared and used in the language is considerably more limited than it is in the other compilers.
Limitations on the use of non-default-sized pointers are not generally diagnosed or enforced by the compiler. Programs that do not follow the model of mixed-size pointer usage outlined below are likely to fail at run-time without any compile-time diagnostic. |
The best-supported model of 64-bit pointer usage is when the command line uses the /POINTER_SIZE=64 qualifier, called a 64-bit compilation. In that case the entire C++ program is considered to use 64-bit addressing, with a few exceptions made to permit the use of data structures containing 32-bit pointers that are needed to communicate with OpenVMS services and other non-C++ libraries. Such data structures naturally contain only pointers to POD types, and the functions that operate on those types naturally have extern "C" linkage. The declarations of those data structures and functions reside in header files, and those header files are coded to use the __INITIAL_POINTER_SIZE macro and the pointer_size pragmas to ensure that they use appropriately-sized pointers regardless of the compilation mode. Except for those declarations, all addresses, pointers, and references in a C++ program compiled with /POINTER_SIZE=64, are considered to be 64-bit types, and all C++ "new" operators allocate data from a 64-bit heap.
If the command line specifies the /POINTER_SIZE=32 qualifier, then it is a 32-bit compilation, and the only use of 64-bit pointers can be pointers to POD types provided by calls to _malloc64(), or obtained from other non-C++ code.
While it is possible to use #pragma pointer_size 32 to declare 32-bit pointers explicitly within a 64-bit compilation, the region of source code covered by such pragmas should be made as small as possible, and preferably confined just to typedefs for pointer types that must be 32-bit pointers. In general, the source region should not contain class definitions for non-POD types, template declarations, declarations of functions that have C++ linkage, or executable code. This differs significantly from C++ for OpenVMS Alpha, which permits C++ classes to be defined with 32-bit pointers in a 64-bit compilation.
Another significant difference is that the Alpha compiler attempts to determine the "best" pointer size to use when determining the type of an "address-of" expression. It uses the fact that on OpenVMS, C++ declared objects (either stack-based or static-extent) always have addresses that fit in 32-bits; and for expressions that involve pointer-dereferencing it uses the width of the pointer that was dereferenced as the width of the pointer type given to the expression. This usually allows address-of expressions to be assigned to pointers without casting. In 64-bit mode, the Integrity servers compiler assumes that an address-of expression will yield a 64-bit pointer unless its operand is a dereference of a 32-bit pointer, and so it may issue spurious NARROWPTR warnings for assignments of address-of expressions to 32-bit pointers; an explicit cast to the correct 32-bit pointer type is needed to silence the warning. As a special case, 64-bit pointer-to-function values may be assigned to 32-bit pointer-to-function objects without complaint (the value of a function pointer always fits in 32-bits on OpenVMS).
Neither Alpha nor Integrity server system compilers include the pointer size when forming mangled names, so naturally it is not possible to overload functions based only on differences in pointer size: the Alpha compiler reports this explicitly at compile time when possible, but on Integrity servers it will just produce conflicting multiple definitions. In general, if a 32-bit pointer type needs to appear in a function prototype in a 64-bit compilation, it is a good practice to define a struct type just to hold the pointer, and pass the struct instead of the pointer type.
Except for names declared with extern "C" linkage, the Integrity server
system compiler produces completely disjoint external symbols in the
object modules for 64-bit compilations and 32-bit compilations. For
64-bit compilations, user-declared names are prefixed by "CX6$"
(instead of "CX3$"), and library names are prefixed by "CX6L$" (instead
of "CXXL$"). Following the prefix, names are mangled identically in the
two modes, so a given source declaration will produce the same name in
the object module differing only by the prefix if compiled in different
modes. So while it is possible to include both 32-bit and 64-bit
compilations in the same program, they will not interact with each
other except through extern "C" linkage names.
6.3.1 Pointer_Size Control Differences
Although the syntax and use of pointer_size controls are the same for Alpha and Integrity servers, and most programs that work correctly on Alpha should also work on Integrity servers without change, the differences in the compiler's model of how the pointer_size controls work on the two platforms can affect behavior, particularly in programs that create pointers to C++ objects (non-POD types) having a size that differs from the setting of the /POINTER_SIZE command-line qualifier, or that apply the sizeof operator to expressions that have a pointer type:
The following example program illustrates some of these differences:
#include <stdio.h> #if __INITIAL_POINTER_SIZE == 64 #define CMD "/POINT=64" #else #define CMD "/POINT=32" #endif #if __ALPHA #define MACH "Alpha" #else #define MACH "I64 " #endif void main(void) { printf(MACH CMD ":\n"); { #pragma __required_pointer_size 64 #define SZ " #pragma 64: " int i; printf(SZ "sizeof(&i) = %d.\n", sizeof(&i)); printf(SZ "value of &i = 0x%016llx.\n", (long long)&i); printf(SZ "sizeof(&\"str\"[1]) = %d.\n", sizeof(&"str"[1])); printf(SZ "value of &\"str\"[1] = 0x%016llx.\n", (long long)&"str"[1]); const char array[] = "str"; printf(SZ "sizeof(&array[1]) = %d.\n", sizeof(&array[1])); printf(SZ "value of &array[1] = 0x%016llx.\n", (long long)&array[1]); printf(SZ "sizeof(new int) = %d.\n", sizeof(new int)); printf(SZ "value of (new int) = 0x%016llx.\n", (long long)new int); char *newcp = new char[2]; printf(SZ "sizeof(newcp) = %d.\n", sizeof(newcp)); printf(SZ "value of newcp = 0x%016llx.\n", (long long)newcp); printf(SZ "sizeof(&newcp[1]) = %d.\n", sizeof(&newcp[1])); printf(SZ "value of &newcp[1] = 0x%016llx.\n", (long long)&newcp[1]); } printf("\n" MACH CMD ":\n"); { #pragma __required_pointer_size 32 #undef SZ #define SZ " #pragma 32: " int i; printf(SZ "sizeof(&i) = %d.\n", sizeof(&i)); printf(SZ "value of &i = 0x%016llx.\n", (long long)&i); printf(SZ "sizeof(&\"str\"[1]) = %d.\n", sizeof(&"str"[1])); printf(SZ "value of &\"str\"[1] = 0x%016llx.\n", (long long)&"str"[1]); const char array[] = "str"; printf(SZ "sizeof(&array[1]) = %d.\n", sizeof(&array[1])); printf(SZ "value of &array[1] = 0x%016llx.\n", (long long)&array[1]); printf(SZ "sizeof(new int) = %d.\n", sizeof(new int)); printf(SZ "value of (new int) = 0x%016llx.\n", (long long)new int); char *newcp = new char[2]; printf(SZ "sizeof(newcp) = %d.\n", sizeof(newcp)); printf(SZ "value of newcp = 0x%016llx.\n", (long long)newcp); printf(SZ "sizeof(&newcp[1]) = %d.\n", sizeof(&newcp[1])); printf(SZ "value of &newcp[1] = 0x%016llx.\n", (long long)&newcp[1]); } } |
Output on Integrity server system with /POINTER=32
Note that all of the pointer sizes, except for the explicitly declared 64-bit pointer variable, and the address of an array element access made through that pointer variable, reflect the command-line setting:
$ pipe cxx/point=32 pointers ; cxxlink pointers ; run pointers I64 /POINT=32: #pragma 64: sizeof(&i) = 4. #pragma 64: value of &i = 0x000000007acffb28. #pragma 64: sizeof(&"str"[1]) = 4. #pragma 64: value of &"str"[1] = 0x0000000000040001. #pragma 64: sizeof(&array[1]) = 4. #pragma 64: value of &array[1] = 0x000000007acffb11. #pragma 64: sizeof(new int) = 4. #pragma 64: value of (new int) = 0x00000000001e0b70. #pragma 64: sizeof(newcp) = 8. #pragma 64: value of newcp = 0x00000000001e0b50. #pragma 64: sizeof(&newcp[1]) = 8. #pragma 64: value of &newcp[1] = 0x00000000001e0b51. I64 /POINT=32: #pragma 32: sizeof(&i) = 4. #pragma 32: value of &i = 0x000000007acffb30. #pragma 32: sizeof(&"str"[1]) = 4. #pragma 32: value of &"str"[1] = 0x0000000000040001. #pragma 32: sizeof(&array[1]) = 4. #pragma 32: value of &array[1] = 0x000000007acffb21. #pragma 32: sizeof(new int) = 4. #pragma 32: value of (new int) = 0x00000000001e3690. #pragma 32: sizeof(newcp) = 4. #pragma 32: value of newcp = 0x00000000001e3670. #pragma 32: sizeof(&newcp[1]) = 4. #pragma 32: value of &newcp[1] = 0x00000000001e3671. |
Output on Alpha with /POINTER=32
Note that all of the pointer sizes, except for the result type of the "new" operator, reflect the pragma setting:
$ pipe cxx/point=32 pointers ; cxxlink pointers ; run pointers Alpha/POINT=32: #pragma 64: sizeof(&i) = 8. #pragma 64: value of &i = 0x000000007ad8f9e0. #pragma 64: sizeof(&"str"[1]) = 8. #pragma 64: value of &"str"[1] = 0x00000000000145e1. #pragma 64: sizeof(&array[1]) = 8. #pragma 64: value of &array[1] = 0x000000007ad8f9d9. #pragma 64: sizeof(new int) = 4. #pragma 64: value of (new int) = 0x000000000007f310. #pragma 64: sizeof(newcp) = 8. #pragma 64: value of newcp = 0x0000000000083350. #pragma 64: sizeof(&newcp[1]) = 8. #pragma 64: value of &newcp[1] = 0x0000000000083351. Alpha/POINT=32: #pragma 32: sizeof(&i) = 4. #pragma 32: value of &i = 0x000000007ad8f9d0. #pragma 32: sizeof(&"str"[1]) = 4. #pragma 32: value of &"str"[1] = 0x00000000000145e1. #pragma 32: sizeof(&array[1]) = 4. #pragma 32: value of &array[1] = 0x000000007ad8f9c9. #pragma 32: sizeof(new int) = 4. #pragma 32: value of (new int) = 0x0000000000083cb0. #pragma 32: sizeof(newcp) = 4. #pragma 32: value of newcp = 0x0000000000083cc0. #pragma 32: sizeof(&newcp[1]) = 4. #pragma 32: value of &newcp[1] = 0x0000000000083cc1. |
Output on Integrity server system with /POINTER=64
Note that all of the pointer sizes, except the explicitly declared 32-bit pointer variable, and the address of an array element access made through that pointer variable, reflect the command-line setting. The warning message identifies a real problem where the 64-bit pointer produced by "new" does not fit into the 32-bit pointer variable newcp, and the value of newcp reflects this by being sign-extended:
$ pipe cxx/point=64 pointers ; cxxlink pointers ; run pointers char *newcp = new char[2]; .................^ %CXX-W-MAYLOSEDATA, cast from long pointer to short pointer will lose data. at line number 54 in file DISK$:[DIR]POINTERS.CXX;1 %ILINK-W-COMPWARN, compilation warnings module: POINTERS file: DISK$:[DIR]POINTERS.OBJ;1 I64 /POINT=64: #pragma 64: sizeof(&i) = 8. #pragma 64: value of &i = 0x000000007acffb28. #pragma 64: sizeof(&"str"[1]) = 8. #pragma 64: value of &"str"[1] = 0x0000000000040001. #pragma 64: sizeof(&array[1]) = 8. #pragma 64: value of &array[1] = 0x000000007acffb11. #pragma 64: sizeof(new int) = 8. #pragma 64: value of (new int) = 0x000000008009c010. #pragma 64: sizeof(newcp) = 8. #pragma 64: value of newcp = 0x000000008009c030. #pragma 64: sizeof(&newcp[1]) = 8. #pragma 64: value of &newcp[1] = 0x000000008009c031. I64 /POINT=64: #pragma 32: sizeof(&i) = 8. #pragma 32: value of &i = 0x000000007acffb30. #pragma 32: sizeof(&"str"[1]) = 8. #pragma 32: value of &"str"[1] = 0x0000000000040001. #pragma 32: sizeof(&array[1]) = 8. #pragma 32: value of &array[1] = 0x000000007acffb21. #pragma 32: sizeof(new int) = 8. #pragma 32: value of (new int) = 0x000000008009c050. #pragma 32: sizeof(newcp) = 4. #pragma 32: value of newcp = 0xffffffff8009c070. #pragma 32: sizeof(&newcp[1]) = 4. #pragma 32: value of &newcp[1] = 0xffffffff8009c071. |
Output on Alpha with /POINTER=64
Note that all of the pointer sizes reflect the pragma setting, except for the result type of the "new" operator. The warning message identifies the same problem identified on Integrity servers, and the value of newcp similarly reflects this by being sign-extended:
$ pipe cxx/point=64 pointers ; cxxlink pointers ; run pointers char *newcp = new char[2]; .................^ %CXX-W-MAYLOSEDATA, cast from long pointer to short pointer will lose data. at line number 54 in file DISK$:[DIR]POINTERS.CXX;1 %LINK-W-WRNERS, compilation warnings in module POINTERS file DISK$:[DIR]POINTERS.OBJ;1 Alpha/POINT=64: #pragma 64: sizeof(&i) = 8. #pragma 64: value of &i = 0x000000007ad8f9e0. #pragma 64: sizeof(&"str"[1]) = 8. #pragma 64: value of &"str"[1] = 0x00000000000145e1. #pragma 64: sizeof(&array[1]) = 8. #pragma 64: value of &array[1] = 0x000000007ad8f9d9. #pragma 64: sizeof(new int) = 8. #pragma 64: value of (new int) = 0x0000000080000010. #pragma 64: sizeof(newcp) = 8. #pragma 64: value of newcp = 0x0000000080000030. #pragma 64: sizeof(&newcp[1]) = 8. #pragma 64: value of &newcp[1] = 0x0000000080000031. Alpha/POINT=64: #pragma 32: sizeof(&i) = 4. #pragma 32: value of &i = 0x000000007ad8f9d0. #pragma 32: sizeof(&"str"[1]) = 4. #pragma 32: value of &"str"[1] = 0x00000000000145e1. #pragma 32: sizeof(&array[1]) = 4. #pragma 32: value of &array[1] = 0x000000007ad8f9c9. #pragma 32: sizeof(new int) = 8. #pragma 32: value of (new int) = 0x0000000080000050. #pragma 32: sizeof(newcp) = 4. #pragma 32: value of newcp = 0xffffffff80000070. #pragma 32: sizeof(&newcp[1]) = 4. #pragma 32: value of &newcp[1] = 0xffffffff80000071. |
Mixed pointer-size allocators are placement-new allocators accepting addr_32 and addr_64 parameters. They are documented in Chapter 9.1.2 Memory Allocators in the HP C++ User's Guide for OpenVMS Systems. On both OpenVMS Alpha and Integrity server systems, these allocators are implemented in the <newext.hxx> header file.
Note the following differences between mixed pointer-size allocators on OpenVMS Alpha and Integrity server systems:
x.cxx below demonstrates the difference in behavior of the new(addr_64_space) allocator on Integrity servers and Alpha systems. Note that the behavior of the new(addr_32_space) allocator is the same on both platforms.
x.cxx ----- #include <newext.hxx> #include <stdio.h> main() { __char_ptr32 x; __char_ptr64 y; x = new (addr_32) char; y = new (addr_64) char; printf("x = %llx, y = %llx\n", x, y); printf("sizeof(new(addr_32)) = %d, sizeof(new(addr_64)) = %d\n", sizeof(new(addr_32) char), sizeof(new(addr_64) char)); } The output on Alpha system: --------------------------- $ pipe cxx/pointer=short x.cxx ; cxxlink x.obj ; run x.exe x = 78690 y = 80000010 sizeof(new(addr_32)) = 4 sizeof(new(addr_64)) = 8 $ pipe cxx/pointer=long x.cxx ; cxxlink x.obj ; run x.exe x = 78690 y = 80000010 sizeof(new(addr_32)) = 4 sizeof(new(addr_64)) = 8 $ The output on Integrity server system: -------------------------- $ pipe cxx/pointer=long x.cxx ; cxxlink x.obj ; run x.exe x = 1f48e0 y = 8009c010 sizeof(new(addr_32)) = 4 sizeof(new(addr_64)) = 8 $ pipe cxx/pointer=short x.cxx ; cxxlink x.obj ; run x.exe y = new (addr_64) char; ...........^ %CXX-W-ADDR64NOT, Use of std::addr_64 in placement new requires /POINTER_SIZE=LONG on this platform. sizeof(new (addr_32) char), sizeof(new (addr_64) char)); .................................................^ %CXX-W-ADDR64NOT, Use of std::addr_64 in placement new requires /POINTER_SIZE=LONG on this platform. x = 1f88d0 y = 0 sizeof(new(addr_32)) = 4 sizeof(new(addr_64)) = 4 $ |
/* Example to set up LIB$INITIALIZE usage by creating a reference ** to the LIB$INITIALIZE function, and an initialized list of ** functions to be called in the LIB$INITIALIZE psect. */ #ifdef __cplusplus extern "C" { #endif /* Declarations for initialization functions. */ extern void some_init_function(void); extern void some_other_init_function(void); /* etc, e.g. other declarations might come from header files */ /* Use 32-bit pointers */ #if __INITIAL_POINTER_SIZE #pragma pointer_size save #pragma pointer_size 32 #endif /* Create a reference to the LIB$INITIALIZE function. */ extern void LIB$INITIALIZE(void); extern void (*unused_global_variable_1)(void) = LIB$INITIALIZE; /* Create an array of pointers to the init functions in the special ** LIB$INITIALIZE section. */ #pragma extern_model save #pragma extern_model strict_refdef "LIB$INITIALIZE" gbl,noexe,nowrt,noshr,long extern void (* const unused_global_variable_2[])() = { some_init_function , some_other_init_function /* etc, other functions to be called by LIB$INITIALIZE() */ }; #pragma extern_model restore #if __INITIAL_POINTER_SIZE #pragma pointer_size restore #endif #ifdef __cplusplus } #endif /* End of example to set up LIB$INITIALIZE */ /* Begin executable test of LIB$INITIALIZE setup. */ #ifdef __cplusplus extern "C" { #endif extern int printf(const char *, ...); extern void some_init_function(void) { printf("In some_init_function.\n"); } extern void some_other_init_function(void) { printf("In some_other_init_function.\n"); } #ifdef __cplusplus } #endif void main(void) { printf("In main.\n"); } /* Compile with either C or C++ on Alpha or I64, link and run. ** The output is: ** In some_init_function. ** In some_other_init_function. ** In main. */ |
%ANALYZE-E-ELF_UNKNWNSEC, Unrecognized Elf Section Type 60000007 |
struct Base {}; struct Derived : Base {}; auto_ptr<Derived> source2() {return auto_ptr<Derived>(new Derived);} int main() { auto_ptr<Derived> d; auto_ptr<Base> b(d); // compiles auto_ptr<Base> p3(source2()); // doesn't compile return 0; } |
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/core-issues.htm |
http://www.gotw.ca/gotw/025.htm |
http://www.awl.com/cseng/titles/0-201-63371-X/auto_ptr.html |
This section describes enhancements, changes, restrictions and problems corrected for the V7.2 C++ Standard Library.
#include <iterator> #include <vector> class D : public std::reverse_iterator<std::vector<bool>::iterator> { }; int main(void) { D x, y; if ( std::operator== <std::vector<bool>::iterator>(x,y) ) return 0; if ( std::operator!= <std::vector<bool>::iterator>(x,y) ) return 0; if ( std::operator< <std::vector<bool>::iterator>(x,y) ) return 0; if ( std::operator<= <std::vector<bool>::iterator>(x,y) ) return 0; if ( std::operator> <std::vector<bool>::iterator>(x,y) ) return 0; if ( std::operator>= <std::vector<bool>::iterator>(x,y) ) return 0; return 1; } |
cxx x.cxx+SYS$LIBRARY:CXXL$ANSI_DEF.TLB/LIB+SYS$LIBRARY:DECC$RTLDEF.TLB/LIB |
This section describes the new features, differences, and restrictions of the C++ V7.1 compiler for Integrity server systems over the C++ V6.5 compiler for Alpha systems. See Section 9 for the release notes for the standard library, language run-time support library, and class library.
This release of the compiler uses a new technology base that differs substantially from both HP C++ for OpenVMS Alpha and HP C for OpenVMS Integrity servers. Although a great deal of work has been done to make it highly compatible with HP C++ for OpenVMS Alpha, there are a number of differences that you will likely notice. Some of these differences are temporary, some are changes that will be reflected in the next version of the compiler for Alpha systems, and some are permanent. Among the permanent differences are:
A problem has been corrected when using the common_block extern_model.
A temporary global symbol is no longer emitted when generating the data.
8.2 New Features in V7.1
The following new features and changes have been made since C++ Version
6.5 for OpenVMS Alpha systems.
8.2.1 cname Header Support
The C++ compiler implements section 17.4.1.2 - Headers [lib.headers] "C++ Headers for C Library Facilities" of the C++ Standard. See also Stroustrup's The C++ Programming Language, 3rd Edition sections 9.2.2 and 16.1.2.
The implementation consists of 18 <cname> headers defined in the C++ Standard:
<cassert> <cctype> <cerrno> <cfloat> <ciso646> <climits> <clocale> <cmath> <csetjmp> <csignal> <cstdarg> <cstddef> <cstdio> <cstdlib> <cstring> <ctime> <cwchar> <cwctype> |
As required by the C++ standard, the <cname> headers define C names in the std namespace. In /NOPURE_CNAME mode, the names are also inserted into the global namespace. See the description of the /[NO]PURE_CNAME compiler qualifier.
The <cname> headers are located in the same TLB library
that contains the C++ standard and class library headers:
SYS$SHARE:CXXL$ANSI_DEF.TLB.
8.2.2 __HIDE_FORBIDDEN_NAMES Predefined in Strict ANSI Mode
When compiling in /STANDARD=STRICT_ANSI mode, the compiler predefines the __HIDE_FORBIDDEN_NAMES macro, causing the C headers to expose only those symbols that are defined by the ANSI C Standard 89. While this is a change in behavior between C++ V6.5 for OpenVMS Alpha systems and C++ for Integrity server systems, the new behavior is consistent with the behavior of the C compiler in /STANDARD=ANSI89 mode.
As a result of this change, the following program would not compile on an Integrity server system in /STANDARD=STRICT_ANSI mode (note that fdopen is not part of the ANSI C Standard 89).
#include <stdio.h> void foo() { fdopen(0,0); } |
The /[NO]FIRST_INCLUDE qualifier is added. It has the following format:
/[NO]FIRST_INCLUDE=(file[,...])
This qualifier includes the specified files before any source files. It corresponds to the Tru64 UNIX -FI switch.
When /FIRST_INCLUDE=file is specified, file is included in the source as if the line before the first line of the source was:
#include "file" |
If more than one file is specified, the files are included in their order of appearance on the command line.
This qualifier is useful if you have command lines to pass to the C compiler that are exceeding the DCL command-line length limit. Using the /FIRST_INCLUDE qualifier can help solve this problem by replacing lengthy /DEFINE and /WARNINGS qualifiers with #define and #pragma message preprocessor directives placed in a /FIRST_INCLUDE file.
The default is /NOFIRST_INCLUDE.
8.2.4 #pragma include_directory Added
The effect of each #pragma include_directory is as if its string argument (including the quotes) were appended to the list of places to search that is given its initial value by the /INCLUDE_DIRECTORY qualifier, except that an empty string is not permitted in the pragma form.
The #pragma include_directory directive has the following format:
#pragma include_directory <string-literal> |
This pragma is intended to ease DCL command-line length limitations when porting applications from POSIX-like environments built with makefiles containing long lists of -I options that specify directories to search for headers. Just as long lists of macro definitions specified by the /DEFINE qualifier can be converted to #define directives in a source file, long lists of places to search specified by the /INCLUDE_DIRECTORY qualifier can be converted to #pragma include_directory directives in a source file.
Note that the places to search, as described in the help text for the /INCLUDE_DIRECTORY qualifier, include the use of POSIX-style pathnames, for example "/usr/base". This form can be very useful when compiling code that contains POSIX-style relative pathnames in #include directives. For example, #include <subdir/foo.h> can be combined with a place to search such as "/usr/base" to form "/usr/base/subdir/foo.h", which will be translated to the filespec "USR:[BASE.SUBDIR]FOO.H"
This pragma can appear only in the main source file or in the first
file specified on the /FIRST_INCLUDE qualifier. Also, it must appear
before any #include directives.
8.2.5 Messages
There have been some changes in the /WARNINGS qualifier. These include bug fixes and improved compatibility with the C compiler. Some changes that might affect user compilations are:
The move from Alpha systems to Integrity server systems will cause some
minor differences in certain compiler diagnostics that are signaled
from the code generator. As a result, diagnostics for unreachable code
and fetches of uninitialized variables might be different on the two
platforms. In addition to a change in message text, some conditions
detected on one platform might not be detected on the other.
8.2.6 New Front End
A new C++ front end provides improved conformance to the C++ International Standard.
8.3 Integrity servers Differences
This section describes differences between the C++ compiler on
Integrity server systems and Alpha systems.
8.3.1 Quotas
The C++ compiler for Integrity server systems is built from a different
code base than the C++ compiler for Alpha systems, and that code base
is larger than the code base for Alpha. Also, Integrity server system
images tend to be somewhat larger than Alpha images in general. Image
size mostly affects working-set size and the amount of pagefile quota
needed to execute an image without exhausting virtual memory. If you
find that programs that compile and run successfully on Alpha run out
of memory on Integrity server systems (either during compilation or
when run), you probably need to increase your pagefile quota. There are
no specific guidelines at this time. You might start by doubling the
quota that was sufficient on Alpha, and then use a "binary-search"
approach to arrive at a better quota value for Integrity server systems
(doubling again, or halving the increment, until your biggest programs
and compilations have just enough memory, and then adding an
appropriate safety margin).
8.3.2 Dialect Changes
The following dialect changes have been made:
The object model and the name mangling scheme used by the C++ compiler on Integrity server systems are different from those used on Alpha systems (different from both /MODEL=ARM and /MODEL=ANSI). The Integrity server system compiler uses the interface described by the Integrity servers Application Binary Interface (ABI).
See http://www.codesourcery.com/cxx-abi/abi.html for a draft description of the ABI specification.
The compiler has some additional encoding rules that are applied to symbol names after the ABI name mangling is determined. All symbols with C++ linkage have CRC encodings added to the name, are uppercased, and shorten to 31 characters if necessary. Since the CRC is computed before the name is uppercased, the symbol name is case sensitive even though the final name is uppercase. /names=as_is and /names=upper are not applicable to these symbols.
All symbols without C++ linkage will have CRC encodings added if they
are longer then 31 characters and /names=shorten is specified. Global
variables with C++ linkage are treated as if they have non-C++ linkage
for compatibility with C and older compilers.
8.3.4 Command-Line Qualifiers
This section describes qualifier differences for HP C++ on Integrity server systems.
Qualifiers/Features Not Supported on Integrity server Systems
The following command-line qualifiers and features are not supported on C++ for Integrity server systems, and are diagnosed by default because ignoring them is likely to alter program behavior:
A number of other qualifiers not supported on Integrity server systems are, by default, silently ignored by the compiler. These qualifiers fall into two groups:
Two optional compiler messages can be enabled to diagnose most of these cases:
If you encounter porting problems, compile /WARN=ENABLE=QUALCHANGE to determine if a qualifier change might be affecting your application.
If you wish to clean up your build scripts to remove extraneous qualifiers that are not meaningful on Integrity server systems, you can enable the QUALNA message.
A list of these qualifiers follows:
The following command-line qualifier is new for C++ V7.1 for Integrity server systems:
This section describes floating-point behavior on Integrity server systems.
IEEE Now the Default
On OpenVMS Integrity server systems, /FLOAT=IEEE_FLOAT is the default floating-point representation. IEEE format data is assumed and IEEE floating-point instructions are used. There is no hardware support for floating-point representations other than IEEE, although you can specify the /FLOAT=D_FLOAT or /FLOAT=G_FLOAT compiler option.
These VAX floating-point formats are supported in the Integrity servers compiler by generating run-time code that converts VAX floating-point formats to IEEE format to perform arithmetic operations, and then converts the IEEE result back to the appropriate VAX floating-point format. This imposes additional run-time overhead and some loss of accuracy compared to performing the operations in hardware on Alpha and VAX systems. The software support for the VAX formats is provided to meet an important functional compatibility requirement for certain applications that need to deal with on-disk binary floating-point data.
On Integrity server systems, the default for /IEEE_MODE is DENORM_RESULTS, which is a change from the default of /IEEE_MODE=FAST on Alpha systems. This means that by default, floating-point operations may silently generate values that print as Infinity or Nan (the industry-standard behavior), instead of issuing a fatal run-time error as they would when using VAX floating-point format or /IEEE_MODE=FAST. Also, the smallest-magnitude nonzero value in this mode is much smaller because results are allowed to enter the denormal range instead of being flushed to zero as soon as the value is too small to represent with normalization.
The conversion between VAX floating-point formats and IEEE formats on the Intel Itanium architecture is a transparent process that will not impact most applications. All you need to do is recompile your application. Because IEEE floating-point format is the default, unless your build explicitly specifies VAX floating-point format options, a simple rebuild for Integrity server systems will use the native IEEE formats directly. For the large class of programs that do not directly depend on the VAX formats for correct operation, this is the most desirable way to build for Integrity server systems.
When you compile an OpenVMS application that specifies an option to use VAX floating-point on an Integrity server system, the compiler automatically generates code for converting floating-point formats. Whenever the application performs a sequence of arithmetic operations, this code does the following:
Where no arithmetic operations are performed (VAX float fetches followed by stores), no conversion will occur. The code handles such situations as moves.
VAX floating-point formats have the same number of bits and precision as their equivalent IEEE floating-point formats. For most applications, the conversion process will be transparent and, therefore, a non-issue.
In a few cases, arithmetic calculations might have different results because of the following differences between VAX and IEEE formats:
These differences might cause problems for applications that do any of the following:
You can test an application's behavior with IEEE floating-point values by first compiling it on an OpenVMS Alpha system using /FLOAT=IEEE_FLOAT/IEEE_MODE=DENORM.
If that produces acceptable results, then simply build the application on the OpenVMS Integrity server system using the same qualifier.
If you determine that simply recompiling with an /IEEE_MODE qualifier is not sufficient because your application depends on the binary representation of floating-point values, then first try building for your Integrity server system by specifying the VAX floating-point option that was in effect for your VAX or Alpha build. This causes the representation seen by your code and on disk to remain unchanged, with some additional runtime cost for the conversions generated by the compiler. If this is not an efficient approach for your application, you can convert VAX floating-point binary data in disk files to IEEE floating-point formats before moving the application to an Integrity server system.
/IEEE_MODE Notes
On Alpha systems, the /IEEE_MODE qualifier generally has its greatest effect on the generated code of a compilation. When calls are made between functions compiled with different /IEEE_MODE qualifiers, each function produces the /IEEE_MODE behavior with which it was compiled.
On Integrity server systems, the /IEEE_MODE qualifier primarily affects only the setting of a hardware register at program startup. In general, the /IEEE_MODE behavior for a given function is controlled by the /IEEE_MODE option specified on the compilation that produced the main program: the startup code for the main program sets the hardware register according the command-line qualifiers used to compile the main program.
When applied to a compilation that does not contain a main program, the /IEEE_MODE qualifier does have some effect: it might affect the evaluation of floating-point constant expressions, and it is used to set the EXCEPTION_MODE used by the math library for calls from that compilation. But the qualifier has no effect on the exceptional behavior of floating-point calculations generated as inline code for that compilation. Therefore, if floating-point exceptional behavior is important to an application, all of its compilations, including the one containing the main program, should be compiled with the same /IEEE_MODE setting.
Even on Alpha systems, the particular setting of /IEEE_MODE=UNDERFLOW_TO_ZERO has the following characteristic: its primary effect requires the setting of a runtime status register, and so it needs to be specified on the compilation containing the main program in order to be effective in other compilations.
Differences in Undefined Behavior
Programs containing undefined floating-point behavior, such as assigning a negative floating-point number to an unsigned integer variable, could generate different results when compiled and run on Integrity server systems. The compiler diagnostics and runtime results can both differ. One runtime difference is the case where one system generates an exception, while the other silently produces a result.
More Information
For more information on Integrity servers floating-point behavior, see
the white paper OpenVMS floating-point arithmetic on the Intel
Itanium architecture at
http://www.hp.com/products1/evolution/alpha_retaintrust/download/i64-flo
ating-pt-wp.pdf .
8.3.6 Intrinsics and Builtins
The C++ built-in functions available on OpenVMS Alpha systems are also available on Integrity server systems, with some differences, as described in this section. This section also describes built-in functions that are specific to Integrity server systems.
Builtin Differences on Integrity server Systems
The <builtins.h> header file contains comments noting which built-in functions are not available or are not the preferred form for Integrity server systems. The compiler issues diagnostics where using a different built-in function for Integrity server systems would be preferable.
The comments in <builtins.h> reflect only what is explicitly present in that header file itself, and in the compiler implementation. You should also consult the content and comments in <pal_builtins.h> to determine more accurately what functionality is effectively provided by including <builtins.h>. For example, if a program explicitly declares one of the Alpha built-in functions and invokes it without having included <builtins.h>, the compiler might issue the BIFNOTAVAIL error message, regardless of whether or not the function is available through a system service. If the compilation does include <builtins.h>, and BIFNOTAVAIL is issued, then either there is no support at all for the built-in function or a new version of <pal_builtins.h> is needed. |
Here is a summary of these differences on Integrity server systems:
__int64 __RETURN_ADDRESS(void); |
Built-in Functions Specific to Integrity server Systems
The <builtins.h> header file contains a section at the top conditionalized to just __ia64 with the support for built-in functions specific to Integrity server systems. This includes macro definitions for all of the registers that can be specified to the __getReg, __setReg, __getIndReg, and __setIndReg built-in functions. Parameters that are const-qualified require an argument that is a compile-time constant.
The following lists the C++ built-in functions available on OpenVMS Integrity server systems.
/* Intel compatible */ unsigned __int64 __getReg(const int __whichReg); void __setReg(const int __whichReg, unsigned __int64 __value); unsigned __int64 __getIndReg(const int __whichIndReg, __int64 __index); void __setIndReg(const int __whichIndReg, __int64 __index, unsigned __int64 __value); void __break(const int __break_arg); /* Native I64 arg */ void __dsrlz(void); void __fc(__int64 __address); void __fwb(void); void __invalat(void); void __invala(void); /* alternate spelling of __invalat */ void __isrlz(void); void __itcd(__int64 __address); void __itci(__int64 __address); void __itrd(__int64 __whichTransReg, __int64 __address); void __itri(__int64 __whichTransReg, __int64 __address); void __ptce(__int64 __address); void __ptcl(__int64 __address, __int64 __pagesz); void __ptcg(__int64 __address, __int64 __pagesz); void __ptcga(__int64 __address, __int64 __pagesz); void __ptri(__int64 __address, __int64 __pagesz); void __ptrd(__int64 __address, __int64 __pagesz); void __rsm(const int __mask); void __rum(const int __mask); void __ssm(const int __mask); void __sum(const int __mask); void __synci(void); __int64 /*address*/ __thash(__int64 __address); __int64 /*address*/ __ttag(__int64 __address); /* Intel _Interlocked intrinsics */ unsigned __int64 _InterlockedCompareExchange_acq( unsigned int *__Destination, unsigned __int64 __Newval, unsigned __int64 __Comparand); unsigned __int64 _InterlockedCompareExchange64_acq( unsigned __int64 *__Destination, unsigned __int64 __Newval, unsigned __int64 __Comparand); unsigned __int64 _InterlockedCompareExchange_rel( unsigned int *__Destination, unsigned __int64 __Newval, unsigned __int64 __Comparand); unsigned __int64 _InterlockedCompareExchange64_rel( unsigned __int64 *__Destination, unsigned __int64 __Newval, unsigned __int64 __Comparand); /* GEM-added builtins */ void __break2(__Integer_Constant __break_code, unsigned __int64 __r17_value); void __flushrs(void); void __loadrs(void); int __prober(__int64 __address, unsigned int __mode); int __probew(__int64 __address, unsigned int __mode); unsigned int __tak(__int64 __address); __int64 __tpa(__int64 __address); /* _Interlocked* builtins return the old value and have the ** newval and comparand arguments in a different order than ** __CMP_SWAP* builtins that return the status (1 or 0). ** Forms without trailing _ACQ or _REL are equivalent to ** the _ACQ form. On Alpha, _ACQ generates MB after the swap, ** _REL generates MB before the swap. */ int __CMP_SWAP_LONG(volatile void *__addr, int __comparand, int __newval); int __CMP_SWAP_QUAD(volatile void *__addr, __int64 __comparand, __int64 __newval); int __CMP_SWAP_LONG_ACQ(volatile void *__addr, int __comparand, int __newval); int __CMP_SWAP_QUAD_ACQ(volatile void *__addr, __int64 __comparand, __int64 __newval); int __CMP_SWAP_LONG_REL(volatile void *__addr, int __comparand, int __newval); int __CMP_SWAP_QUAD_REL(volatile void *__addr, __int64 __comparand, __int64 __newval); /* ** Produce the value of R26 (Alpha) or B0 (I64) on entry to the ** function containing a call to this builtin. Cannot be invoked ** from a function with nonstandard linkage. */ __int64 __RETURN_ADDRESS(void); |
Programs must not use memcpy with overlapping arguments.
HP C++ for OpenVMS Integrity servers optimizes the use of standard C library functions memcpy and memmove somewhat differently than HP C for OpenVMS Integrity servers and the HP C and C++ compilers for OpenVMS Alpha. Because of this, the use of memcpy with arguments that overlap in memory can produce results that differ from the other compilers.
Note that the behavior of memcpy is formally undefined if its
arguments overlap; only memmove should be used in this case.
However, the other compilers generally treat memcpy in a way
that handles overlapping arguments in the same way as memmove,
while HP C++ for OpenVMS Integrity servers does not. So when using
memcpy, take care that the arguments do not refer to memory
that might overlap; if overlap is a possibility, you must use
memmove instead of memcpy.
8.3.8 ELF
ELF Used on Integrity server systems.
On OpenVMS Alpha systems, the C++ compiler uses a proprietary object format specific to OpenVMS.
On OpenVMS Integrity server systems, the compiler generates ELF objects. ELF is an industry standard object format used on many UNIX platforms, including Linux. This change should be transparent to most users; it is primarily of interest to compiler and tools developers. The greatest benefit of this change is that it should make it easier to create development tools that work on OpenVMS and other platforms.
Extensions to ELF have been used as needed to provide functionality unique to OpenVMS. See the Porting Applications from HP OpenVMS Alpha to HP OpenVMS Industry Standard 64 for Integrity Servers for more information on ELF.
COMDATS/Group Sections
One feature that ELF provides that is new to OpenVMS is the COMDAT section group---a group of sections in an object file that can be duplicated in one or more other object files. The linker is expected to keep one group and ignore all others. The benefit of this feature is that it permits compilers to generate definitions for symbols for things used in multiple objects without having to worry about creating a single definition in one place. The most notable uses for this feature are templates and inline functions.
New ELF Type for Weak Symbols
A new Executable and Linkable Format (ELF) type was generated to distinguish between the two types of weak symbol definitions.
For modules with ABI versions equal to 2 (the most common version used by compilers):
The Librarian supports both the ELF ABI versions 1 and 2 of the object
and image file formats within the same library.
8.3.9 Templates
This section describes template instantiation for Integrity server systems.
Implemented using ELF COMDATS/Groups Sections
The Alpha C++ compiler had numerous models for instantiating templates. Each attempted to solve the issue of how to generate one and only one copy of each template. The use of ELF on OpenVMS Integrity server systems provided the compiler with the additional option of using COMDAT section groups. Since this technique is superior to all the models supported on Alpha, this is the only model supported on Integrity server systems.
In this model, templates are instantiated in a COMDAT section group inside every object module that uses them. This is very similar to the /TEMPLATE=LOCAL on Alpha systems, except that when the objects are linked together, the linker removes the duplicate copies. The primary advantage of this technique over /TEMPLATE=LOCAL and /TEMPLATE=IMPLICIT_LOCAL is the reduction in image size.
A secondary advantage is the elimination of distinct data for each template. For example, if a template maintained a list of elements it created, each module would have a separate copy of the list. This behavior does not conform to the standard. If you are currently using /TEMPLATE=LOCAL or /TEMPLATE=IMPLICIT_LOCAL, you will likely experience no difficulty from this change.
Not in Repository
The most visible difference that results from this new instantiation model occurs in models that instantiate templates into the repository (/TEMPLATE=AUTOMATIC|ALL_REPOSITORY|USED_REPOSITORY).
With the new model, no repository is needed. Build procedures that use CXXLINK will work transparently. Builds that attempt to manipulate objects in the repository will fail and will need to be changed. In most cases, the reason for manipulating the repository directly has been eliminated with the new template instantiation model.
Restriction
For OpenVMS Integrity servers and Alpha systems, the
/TEMPLATE_DEFINE=ALL qualifier is not guaranteed to work with the
Standard Library. Use automatic instantiation or specify
/TEMPLATE_DEFINE=USED instead.
8.3.10 Exceptions and Condition Handlers
The command-line option /EXCEPTIONS=NOCLEANUP is not implemented. As a result, you might see destructors being called during cleanup in code previously compiled with this option.
Exception specifications are not implemented. Exception specifications on routine declarations and definitions are accepted syntactically, but their run-time behavior has not yet been implemented.
According to the C++ Standard, an implementation may or may not unwind the stack before calling terminate when no matching handler is found for a thrown exception. On Integrity server systems, the implementation unwinds the stack. On Alpha systems, it does not.
Consider the following program:
#include <exception> #include <cstdio> #include <cstdlib> class C { public: C() { std::printf("Created\n"); } ~C() { std::printf("Destroyed\n"); } }; void announce1() { std::printf("In terminate\n"); exit(0); } int main() { C c; std::set_terminate(announce1); throw 5; return 0; } |
For the above program, the output on OpenVMS Alpha and Integrity server systems is:
Alpha: Integrity servers: Created Created In terminate Destroyed In terminate |
The compiler assumes that the only two ways an exception can be propagated into a function are:
As a result of this assumption, some exceptions such as those thrown
from a signal handler will not be caught.
8.3.11 Overriding new and delete
Full support for allowing a user to override operators new and
delete is not yet completed. As a result, when you override
new and delete, you might see multiply-defined
symbols when linking. This will be fixed in a future release.
8.4 Integrity servers Known Issues
Version 7.1 of the C++ compiler has the following known issues:
Qualifiers
By default the compiler's optimizer will not unroll loops. If you wish to turn the optimization on, you must compile /OPTIMIZE=UNROLL=N
Destruction of Initialized Aggregate Members
If an aggregate class/struct (such as struct B in the example below) contains a member with a destructor, and an object of that class is initialized with a brace-enclosed initializer list, and initialization of some member terminates by throwing an exception (thereby interrupting the initialization of the B object), members already completely initialized at that point will not be destructed. However, if the B object is completely initialized, each of its members will be destructed correctly.
// Aggregate initialization, cleanup on throw extern "C" int printf(const char *, ...); int count; int stopon; struct A { int n; A(int i) : n(i) { if (n == stopon) { printf("throwing...\n"); throw "help"; } printf("A::A(%d)\n", n); count++; } ~A() { printf("A::~A(%d)\n", n); count--; } }; struct B { A a; const A &r; const A &r2; A aa; ~B() { printf("B::~B()\n"); } }; main () { for (stopon = 1; stopon <= 5; stopon++) { try { B b = {1, A(2), A(3), 4}; throw 5; } catch (...) { printf("catch\n"); printf("----------\n"); } } return !(count == 0); } |
Debugger
struct A { int a_member; }; struct B : A { int b_member; }; struct C { int c_member; }; struct D : B, C { int d_member; }; struct E : D { int e_member; }; struct F { int f_member; }; struct G : F { int g_member; }; struct H : E, G { int h_member; }; struct I : H { int i_member; }; struct J : I { int j_member; }; static J j_object; main(){ j_object.j_member = 1; } |
DBG> exam j_object.B::A::a_member %DEBUG-W-NOFIELD, 'B::A::a_member' is not a field in this record DBG> deposit j_object.I::a_member = 13 |
// using %name you can set a break on a destructor DBG> set break stack::%name'~stack' // however setting a break on an operator is not working yet DBG> set break stack::%name'operator++'() %DEBUG-I-NOTUNQOVR, symbol 'stack::operator++' is overloaded overloaded name stack::operator++ instance stack::operator++(int) instance stack::operator++() %DEBUG-E-REENTER, reenter the command using a more precise pathname |
#include <stdio.h> void t2(); int main() { /* comment lines within executable code visible*/ printf("in main\n"); t2(); } /* last line in routine main */ /* This comment will not be visible */ #include "t2.c" |
DBG> go break at routine GEM_BUGS10682\main 4: int main() { %DEBUG-I-DYNLNGSET, setting language C++ DBG> type 1:20 module GEM_BUGS10682 1: #include <stdio.h> 2: 3: void t2(); 4: int main() { 5: /* comment lines within executable code visible*/ 6: printf("in main\n"); 7: t2(); 8: } /* last line in routine main */ 9: extern "C" {int printf(const char *,...);} 10: void t2() { 11: printf("in t2\n"); 12: } /* last line in routine t2 */ DBG> sho calls module name routine name line rel PC abs PC *GEM_BUGS10682 main 4 0000000000000000 0000000000010000 *GEM_BUGS10682 MAIN 00000000000000F0 0000000000010170 FFFFFFFF80B1CC20 FFFFFFFF80B1CC20 DBG> set break t2 DBG> go in main break at routine GEM_BUGS10682\t2 10: void t2() { DBG> sho calls module name routine name line rel PC abs PC *GEM_BUGS10682 t2 10 0000000000000000 00000000000101C0 *GEM_BUGS10682 main 7 0000000000000050 0000000000010050 *GEM_BUGS10682 MAIN 00000000000000F0 0000000000010170 |
1 #include <stdio.h> 1552 1553 void t2(); 1554 int main() { 1555 /* comment lines within executable code visible*/ 1556 printf("in main\n"); 1557 t2(); 1558 } /* last line in routine main */ 1559 /* This comment will not be visible */ 1560 1561 #include "t2.c" 1568 1569 |
for (i=0; i<10; i++) y_v10_int[i] = x_v10_int[i]; for (i=0; i<10; i++) {y_v10_int[i] = x_v10_int[i];} for (i=0; i<10; i++) { y_v10_int[i] = x_v10_int[i]; } |
For Integrity server systems, the C++ standard library has been upgraded and organized as a shareable image. All applicable fixes and enhancements done in the C++ standard library for Alpha systems, have been applied to the C++ standard library for Integrity server systems.
For Integrity server systems, the C++ class library is based on the
same code as the C++ class library on Alpha systems. The major change
in the C++ class library for Integrity server systems is the removal of
the tasks and complex packages.
9.1 Library Reorganization
The standard library, language run-time support library, and class
library have been reorganized for Integrity server systems.
9.1.1 Standard Library and Language Run-Time Support Library
On Alpha systems, the C++ standard library and language run-time support library is delivered in an object library, LIBCXXSTD.OLB, shipped with the compiler kit.
On Integrity server systems, the C++ standard library and language run-time support library are delivered as separate system shareable images shipped with the base operating system. The names of the images are: CXXL$RWRTL.EXE and CXXL$LANGRTL.EXE, respectively. The images reside in the SYS$LIBRARY directory and are installed at system startup. The LIBCXXSTD.OLB object library does not exist on Integrity server systems.
On Alpha systems, the default C++ standard library LIBCXXSTD[_MA].OLB is a preinstantiation library. It contains instantiations of commonly used templates on commonly uses types like std::basic_string<char>, std::basic_iostream<char>, and so on. When you compile with /NOIMPLICIT_INCLUDE, standard library symbols defined in template definition files can be resolved from the preinstantiation library.
On Integrity server systems, there is no preinstantiation library. As a
result, compiling with /NOIMPLICIT_INCLUDE can result in undefined
symbols for standard library symbols that could have been resolved on
Alpha systems from the preinstantiation library.
9.1.2 Class Library
On Alpha systems, there are three class library shareable images: CXXL$011_SHR.EXE, CXXL$011_SHRTASK.EXE, and CXXL$011_TASK.EXE.
On Integrity server systems, the C++ class library continues to ship as
a system shareable image. Because the tasks and complex packages have
been removed, there is only one class library image: CXXL$011_SHR.EXE.
9.2 Language Run-Time Support Library
The following language run-time support library change has been made:
The following class library changes have been made:
This section describes changes to the C++ standard library.
9.4.1 Changes
There are two major changes in the C++ standard library for Integrity server systems as compared with the standard library for Alpha systems:
Additional standard library changes, known issues, and platform
differences are noted in the following sections.
9.4.2 Library Headers
While from the customers' perspective the change in the library distribution model is supposed to be transparent (except that application images will be much smaller on Integrity server systems), users on Integrity server systems may find that the new C++ Standard Library is much less forgiving in terms of including all necessary library headers than the old Standard Library.
For example, the following program compiles cleanly on OpenVMS Alpha systems despite the fact that it does not include the <iostream> header necessary for the std::cout object:
#ifndef __USE_STD_IOSTREAM #define __USE_STD_IOSTREAM #endif #include <fstream> using namespace std; main() { cout << "hello, world"; } |
However, on OpenVMS Integrity server systems, compilation fails with the following error:
%CXX-E-UNDECLARED, identifier "cout" is undefined |
It is nearly impossible to describe all combinations of library constructs and header files that would compile cleanly on Alpha systems and yet fail to compile on Integrity server systems because a library header required by the C++ standard for a particular construct has not been included. If a program that used to compile cleanly on an Alpha system fails to compile on an Integrity server system, it is always a good idea to check that all necessary library headers are included.
9.4.3 Internal Library Headers and Macros
A program that includes internal RW stdlib V2.0 library headers, like
<stddefs> or <stdcomp>, or that uses
internal library macros _RW_*, will have to be modified because the new
C++ standard library does not necessarily have the same internal
headers or use the same internal macros as the old one.
9.4.4 Known Issues
9.4.5 Differences Between Alpha and Integrity server Systems
The following are differences between the Integrity server systems and Alpha standard libraries:
istream_type& get(char_type *s, streamsize n, char_type delim); istream_type& get(char_type *s, streamsize n); |
#ifndef __USE_STD_IOSTREAM #define __USE_STD_IOSTREAM #endif #include <iostream> #include <cassert> using namespace std; int main() { char buffer[1024], c; int lines; for (lines = 0; cin.good(); ++lines) { cin.get(buffer, sizeof(buffer)); if ( !cin.eof() ) { // consume delimeter assert( (cin.get(c), c) == '\n' ); } } cout << lines << " lines were read\n"; } |
#include <complex> int main() { std::complex<int> ci(1, 2); std::complex<long> cl(3, 4); ci += cl; } |
strstream(char *ptr, streamsize count, ios_base::openmode mode = ios_base::in | ios_base::out); ostrstream(char *ptr, streamsize count, ios_base::openmode mode = ios_base::out); |
multimap<string, int, less<string>, allocator<string> > x; |
multimap<string, int, less<string>, allocator<pair<const string, int> > > x; |
Got an exception: string index out of range in function: basic_string:::replace(size_t,size_t,size_t,char) position: 100 is greater than length: 0 |
Got an exception: CSRC:[STDIPF_INCLUDE]STRING.CC;:416: basic_string::replace(size_type, size_type, size_type, value_type): argument value 100 out of range [0, 0) |
#ifndef __USE_STD_IOSTREAM #define __USE_STD_IOSTREAM #endif #include <strstream> #include <iostream> using namespace std; main() { istrstream is("32768"); // SHRT_MAX is 32767 short s; is >> s; cout << is.fail() << endl; cout << s << endl; } |
0 -32768 |
1 32767 |
find(InputIterator first, InputIterator last, const T& value) |
include <algorithm> #include <vector> struct S { int i; }; bool operator!=(S, int); bool operator==(S, int); void foo() { std::vector<S> v; std::find(v.begin(), v.end(), 0); } |
#include <vector> typedef std::reverse_iterator<std::vector<bool>::iterator> ri; main() { ri::pointer (ri::*foo)() const = &ri::operator->; } |
#include <algorithm> template <class T> class randomaccessiterator { public: typedef T value_type; typedef int difference_type; typedef T* pointer; typedef T& reference; typedef std::random_access_iterator_tag iterator_category; bool operator==(const randomaccessiterator&); bool operator!=(const randomaccessiterator&); T& operator*() const; T* operator->(); randomaccessiterator& operator++(); const randomaccessiterator& operator++(difference_type); randomaccessiterator& operator--(); const randomaccessiterator& operator--(difference_type); randomaccessiterator& operator+=(difference_type); randomaccessiterator& operator+(difference_type); randomaccessiterator& operator-=(difference_type); randomaccessiterator& operator-(difference_type); difference_type operator-(const randomaccessiterator&); // const; }; struct S {}; typedef randomaccessiterator<S> Iterator; typedef bool (*Predicate)(Iterator::value_type); template Iterator std::stable_partition<Iterator, Predicate>(Iterator, Iterator, Predicate); |
#ifndef __USE_STD_IOSTREAM #define __USE_STD_IOSTREAM #endif #include <sstream> using namespace std; void foo() { istringstream in("hello, world"); streamoff offset; offset = in.tellg().offset(); // Alpha only offset = streamoff(in.tellg()); // either Alpha or Integrity server } |
#include <vector> #include <algorithm> struct S { bool operator<(const S&) const; }; void foo() { std::vector<S> v; std::push_heap(v.begin(),v.end()); } |
x.cxx ----- #ifndef __USE_STD_IOSTREAM #define __USE_STD_IOSTREAM #endif #include <iostream> main() { std::cout << std::showpos << (unsigned)1 << std::endl; } |
1 |
+1 |
This section describes problems you might encounter when using the
current release of the C++ Standard Library with the HP C++ compiler.
Where appropriate, workarounds are suggested.
9.4.6.1 Using the C++ Standard Library in Microsoft Standard Mode
Compiling /STANDARD=MS has the following restrictions:
#include <iterator> std::reverse_iterator<int> x; |
#include <iterator> template <class T> typename std::iterator_traits<T>::value_type foo(void); void bar() { foo<int*>(); } |
#include <vector> #include <algorithm> void foo() { std::vector<int*> v; std::stable_sort(v.begin(),v.end()); std::sort(v.begin(),v.end()); } |
#ifndef __USE_STD_IOSTREAM #define __USE_STD_IOSTREAM #endif #include <ios> const std::ios_base::fmtflags *x = &std::ios_base::boolalpha; |
Because of changes in the architecture on Integrity server systems, CXXLINK plays a much smaller role. Its only remaining purpose is to provide human readable (demangled) names for mangled C++ names in diagnostics generated by the linker.
Specific changes are:
To install HP C++ for OpenVMS Integrity server systems, set the default directory to a writeable directory to allow the IVP to succeed. Then run the PRODUCT INSTALL command, pointing to the kit location. For example:
$ SET DEFAULT SYS$MANAGER $ PRODUCT INSTALL CXX/SOURCE=node::device:[kit_dir] |
After installation, these C++ release notes will be available at:
SYS$HELP:CXX.RELEASE_NOTES
SYS$HELP:CXX_RELEASE_NOTES.PS
Here is a sample installation log:
$ PRODUCT INSTALL CXX/SOURCE=NODE1$::DEV1$:[I64_CPP_KIT] The following product has been selected: HP I64VMS CXX V7.2-052 Layered Product Do you want to continue? [YES] Configuration phase starting ... You will be asked to choose options, if any, for each selected product and for any products that may be installed to satisfy software dependency requirements. HP I64VMS CXX V7.2-052: HP C++ for OpenVMS Industry Standard Copyright 2006 Hewlett-Packard Development Company, L.P. This software product is sold by Hewlett-Packard Company PAKs used: CXX-V Do you want the defaults for all options? [YES] Copyright 2006 Hewlett-Packard Development Company, L.P. HP, the HP logo, Alpha and OpenVMS are trademarks of Hewlett-Packard Development Company, L.P. in the U.S. and/or other countries. Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license. Do you want to review the options? [NO] Execution phase starting ... The following product will be installed to destination: HP I64VMS CXX V7.2-052 DISK$ICXXSYS:[VMS$COMMON.] The following product will be removed from destination: HP I64VMS CXX V7.1-152 DISK$ICXXSYS:[VMS$COMMON.] Portion done: 0%...60%...70%...80%...90%...100% The following product has been installed: HP I64VMS CXX V7.2-052 Layered Product The following product has been removed: HP I64VMS CXX V7.1-155 Layered Product %PCSI-I-IVPEXECUTE, executing test procedure for HP I64VMS CXX V7.2-052 ... %PCSI-I-IVPSUCCESS, test procedure completed successfully HP I64VMS CXX V7.2-052: HP C++ for OpenVMS Industry Standard The release notes are located in the file SYS$HELP:CXX.RELEASE_NOTES for the text form and SYS$HELP:CXX_RELEASE_NOTES.PS for the postscript form. |
Version 7.3 adds optional support for having multiple versions of the C compiler on your system. It works by appending an ident name to a previously installed compiler and saving it alongside the new compiler from this kit. Users on your system can then execute the sys$system:cxx$set_version.com and sys$system:cxx$show_versions.com command procedures to select the desired compiler for a given process and to view the list of available compiler versions.
To set this up, have your system administrator run the installation procedure, answering NO to the question about default options:
Do you want the defaults for all options? [YES] NO <RET> |
Then answer YES to the question about making alternate compilers available:
Would you like to set up your system for running alternate versions of C? [NO] YES <RET> |
Users can then execute the cxx$set_version.com command procedure with an argument to set up process default logicals that point to alternate compiler versions. For more information on using cxx$set_version.com and cxx$show_version.com see section: "Enhancements, Changes, and Problems Corrected in V7.3".
Sample installation for multiple-version Support:
$ product install CXX /source=disk$:[dir] The following product has been selected: HP I64VMS CXX T7.3-18 Layered Product Do you want to continue? [YES] Configuration phase starting ... You will be asked to choose options, if any, for each selected product and for any products that may be installed to satisfy software dependency requirements. HP I64VMS CXX T7.3-18: HP C++ for OpenVMS Industry Standard Copyright 2003-2007 Hewlett-Packard Development Company, L.P. This software product is sold by Hewlett-Packard Company PAKs used: CXX-V or CXX-V-USER Do you want the defaults for all options? [YES] no HP I64VMS VMS V8.3 [Installed] * Configuration options for this referenced product cannot * be changed now because the product is already installed. * (You can use PRODUCT RECONFIGURE later to change options.) Copyright 2003-2007 Hewlett-Packard Development Company, L.P. HP, the HP logo, Alpha and OpenVMS are trademarks of Hewlett-Packard Development Company, L.P. in the U.S. and/or other countries. Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license. Multi_Version Support: If you would like to set up your system to be able to run different versions of the compiler then answer yes. The installation procedure will then copy the previously installed C++ compiler and associated files along side the new compiler in this kit with a suffix appended to the name that corresponds to the version number. Users may then execute CXX$SET_VERSION.COM to run an alternate version of the compiler and CXX$SHOW_VERSIONS.COM to show available versions at anytime after this installation. Would you like to set up your system for running alternate versions of C++? [NO] yes Do you want to review the options? [NO] Execution phase starting ... The following product will be installed to destination: HP I64VMS CXX T7.3-18 DISK$ICXXSYS:[VMS$COMMON.] Portion done: 0%...60%...70%...80%...90%...100% The following product has been installed: HP I64VMS CXX T7.3-18 Layered Product %PCSI-I-IVPEXECUTE, executing test procedure for HP I64VMS CXX T7.3-18 ... %PCSI-I-IVPSUCCESS, test procedure completed successfully HP I64VMS CXX T7.3-18: HP C++ for OpenVMS Industry Standard Text form of the release notes are located in the file SYS$HELP:CXX.RELEASE_NOTES SYS$HELP:CXX_RELEASE_NOTES.PS contains the postscript form. A startup file SYS$STARTUP:CXX$STARTUP.COM has been provided. It contains commands which can be executed after the product install procedure has been run and at startup to allow for the best compilation performance. You may want to invoke this command file from your system's site-specific start up file. This command file does not have to be invoked for correct operation of HP C++. |
Please report problems or offer feedback using the mechanisms specified in the HP C++ User's Guide preface.
Contents |