Compaq C++ Version 5.6C
Compaq C++ Version 5.6C
Release Notes for OpenVMS VAX Systems
December, 1999
This document contains information about new and changed features in
this version of Compaq C++ for OpenVMS VAX Systems.
Compaq Computer Corporation
Houston, Texas
The information in this document is subject to change without notice
and should not be construed as a commitment by Digital Equipment
Corporation. Digital Equipment Corporation assumes no responsibility
for any errors that may appear in this document.
The software described in this document is furnished under a license
and may be used or copied only in accordance with the terms of such
license.
No responsibility is assumed for the use or reliability of software on
equipment that is not supplied by Digital Equipment Corporation or its
affiliated companies.
Restricted Rights: Use, duplication, or disclosure by the U.S.
Government is subject to restrictions as set forth in subparagraph
(c)(1)(ii) of the Rights in Technical Data and Computer Software clause
at DFARS 252.227-7013.
©1992-1999 Digital Equipment Corporation
Compaq, the Compaq logo, and Alpha, DEC, DECthreads, DECwindows,
OpenVMS, VAX, and VMS are registered in the U.S. Patent and Trademark
Office.
PostScript is a trademark of Adobe Systems Incorporated.
UNIX is a registered trademark in the United States and other countries
licensed exclusively through X/Open Company Ltd.
Other product names mentioned herein may be the trademarks of their
respective companies.
1 Introduction
This document contains the release notes for Compaq C++ Version 5.6C
for OpenVMS VAX Systems and for several previous versions of the
compiler.
The compiler requires OpenVMS VAX Version 5.5 or higher. If you are
installing on an OpenVMS VAX system older than Version 6.1, please read
Section 3.3.
The Compaq C++ distribution contains three kits:
- The CXX056 kit contains the Compaq C++ compiler and associated
files, such as the Compaq C++ Class Library header files.
- The AACRTnnn kit contains the C/C++ Run-Time Components,
to be used only when installing Compaq C++ on OpenVMS VAX systems
older than Version 6.1. See Section 3.3 for details.
The
AACRTnnn kit also contains a version of DECthreads to be used
only when installing Compaq C++ on OpenVMS VAX systems older than
Version 6.0
- The DBG060 kit contains VAX DEBUG Version 6.0C, to be installed
only on systems running version of OpenVMS VAX older than Version 6.0.
For instruction on installing this debugger, see Compaq C++ Installation Guide for OpenVMS VAX Systems.
2 Important Compatibility Information
- Automatic instantiation of templates is enabled by default,
begining with Version 5.3. If you use this feature, you must link using
the new CXXLINK command rather than the LINK command. See Section 4.2
for more information.
If you do not want to use automatic
instantiation, compile using the
/notemplate_define
qualifier. To do this most easily, in your SYS$LOGIN:LOGIN.COM file
define the
cxx
command as follows:
cxx == "cxx/notemplate_define"
|
You can then override this default when compiling specific files.
If the
cxx
command is defined as previously shown, you can compile with the
/template_define
qualifer in effect as follows:
cxx/template_define test.cxx
|
See Chapter 5 of Using Compaq C++ for OpenVMS Systems for more information.
- If your application uses the STL that was provided with a previous
version of the compiler, please read Section 13 for important
information about using the C++ Standard Library provided with the
current version of the compiler. Remember that the ANSI C++ Standard is
not yet finalized and thus our STL releases are not guaranteed to be
compatible with prior releases.
3 Installation Notes
These notes apply to Compaq C++ Version 5.6C for OpenVMS VAX. For
detailed directions on installing the kit, see the Compaq C++ Installation Guide for OpenVMS VAX Systems.
3.1 Changes with Version 5.3
This section describes changes made to the installation procedure with
Version 5.3:
- The procedures used to install the compiler for OpenVMS VAX are
now nearly identical to those used to install this product on OpenVMS
Alpha systems. Installers may notice small changes, such as in the
wording of messages, that reflect this procedure modification.
- The Standard Template Library files are placed as follows:
Header files --- in SYS$COMMON:[SYSLIB]CXXL$ANSI_DEF.TLB
Run-time support --- in SYS$LIBRARY:LIBCXXSTD.OLB
- The exception handling run-time support is placed in the file:
SYS$LIBRARY:LIBCXXSTD.OLB
3.2 Upgrading OpenVMS VAX
- If you install this compiler on a version of OpenVMS earlier than
6.2 and then upgrade your system to OpenVMS Version 6.2 or later,
Compaq recommends that you reinstall the compiler. Reinstalling the
compiler will ensure that your system has the latest run-time support
for exception handling.
- If you install this compiler on a version of OpenVMS earlier than
7.0, the installation supplies Class Library header files that do not
contain thread safety support. If you then upgrade your system to
OpenVMS Version 7.0 or later and wish to take advantage of the Class Library
thread safety support, you must reinstall the compiler. For details,
see Section 12.
3.3 C/C++ Run-Time Components
Read this section only if you are installing the compiler on
OpenVMS VAX systems older than Version 6.1. The Run-Time Components
include image files and libraries for the C Run-Time Library identical
to the binaries provided with Version 6.0 of OpenVMS for VAX. For
installation and usage information, see the Compaq C/C++ for OpenVMS VAX Run-Time Components Reference and Installation Manual in the
AACRTnnn kit's documentation directory.
4 Compiler Release Notes
This is Version 5.6C of the Compaq C++ compiler.
4.1 Enhancements and Changes in Version 5.6C
Changes and enhancements are as follows:
- The product name has been changed from DEC C++ to Compaq C++.
- HTML files are provided for the release notes and the product
manuals for use with a web browser. The name of the index file for the
HTML documentation has been changed from
cxx.html
to
index.htm
.
To view this documentation, open the following file using your
web browser:
file:/sys$common/syshlp/cxx$help/index.htm
|
- If external names are identical up to 31 characters, you can now
specify
/NAMES=SHORTENED
to create specially encoded 31-character names. All modules in an
application containing long external names must be compiled
consistently with either
/NAMES=TRUNCATED
or
/NAMES=SHORTENED
. For additional information, type HELP CXX/NAMES.
4.2 Enhancements and Changes in Version 5.6
This section briefly summarizes changes and enhancements that were made
in Version 5.6.
- HTML files are provided for the release notes and some of the
product manuals for use with a web browser.
To view this
documentation, open the following file using your web browser:
file:/sys$common/syshlp/cxx$help/cxx.html
|
- With Version 5.6, C++ provides support for most of the namespace
features described in the current draft ANSI/ISO C++ standard. See
Section 8.
- With Version 5.6, the compiler provides additional support for the
C++ Standard Library. See Section 13 for details.
- With Version 5.6, the CXXLINK facility now supports use of
LNK$LIBRARY
CXXLINK now works with the OpenVMS Linker's
LNK$LIBRARY
logicals. CXXLINK does this by checking all logical defntions of
LNK$LIBRARY_nnn
and defining
LNK$LIBRARY_nnn+1
to be
SYS$LIBRARY:LIBCXXSTD.OLB
.
This change places a limit on the number of
LNK$LIBRARY
definitions a user can have. That limit is 998.
The DCL command
used to define the
LNK$LIBRARY[_nnn]
logical is displayed if the /LOG qualifier was used.
- With Version 5.6, CXXLINK can now display errors from the prelink
phase.
CXXLINK can now display the output from its prelink phase.
This was not previously possible even if /LOG was used. Now user's have
the option of displaying the prelink phase's output to SYS$ERROR by
defining the logical name
CXX$LINK_VERBOSE_PRELINK
to any value. Note that output relating to the template instantiation
process will not be displayed. This will let users see possible errors
during the prelink phase that actually indicate that CXXLINK should be
aborted.
For example, to display prelinker errors enter the
following commands:
$ DEFINE CXX$LINK_VERBOSE_PRELINK 1
$ CXXLINK test
|
- Previously, the error diagnostics that occurred during a template
instantiation have always been generated at the site of the template
definition and have not included any useful information about the point
of instantiation. With this version, all error diagnostics generated
during an instantiation will now be accompanied by another diagnostic
indicating the template name, the type being used for the
instantiation, and the point of instantiation location.
- With this version, the
/version
command-line qualifier no longer requires specification of a file name.
4.3 Enhancements and Changes in Version 5.5
This section briefly summarizes changes and enhancements that were made
in Version 5.5.
- Compaq C++ provides two new compile-time template instantiations
options:
/template_define=local
and
/template_define=used
. As a result, the name of the prior compile-time instantiation option
was changed from
/template_define=compile_time
to
/template_define=all
. If you were using
/template_define=compile_time
, you will need to
use /template_define=all
instead. For information on the new options, see Section 9.
- Version 5.5 corrects a problem that occurred when using CXXLINK for
template instantiations that reference symbols in object libraries
specified. Formerly, CXXLINK created a linker options file in the first
writeable repository directory. With Version 5.5, the options file is
written in the directory of the first file specified to CXXLINK. Thus,
this directory must be writeable. See Section 4.10.
- Prior to C++ Version ersion 5.5, CXXLINK turned off VERIFY mode in
the subprocess that performed the compilations and links required for
automatic instantiation. The result was that linker option files input
to the OpenVMS linker would never have their content displayed.
This error was corrected in C++ Version ersion 5.5 by resetting the
VERIFY mode of the subprocess to the VERIFY mode of the parent process
before executing the final link.
A side effect of this bug fix is
that if you issue a DCL
set verify
command before using CXXLINK, the content of all linker options files
is displayed. If you do not want to see this output, issue a DCL
set noverify
command before using CXXLINK.
- Chapter 5 (Using Templates) of Using Compaq C++ for OpenVMS Systems has been expanded to
include discussion and examples of building a project using automatic
template instantiation.
4.4 Enhancements and Changes in Version 5.4
This section briefly summarizes changes and enhancements that were made
in Version 5.4.
- Substantial performance improvements have been implemented for
automatic instantiation of C++ templates.
The
/template_define
command line qualifier remains the default but now directs C++ to
automatically instantiate multiple member functions and static data
members of a particular template class in one object file within the
repository. If you want to take advantage of this performance
enhancement, Compaq suggests that you delete the contents of your old
Version 5.3 repository.
- The C++ compiler accepts template default parameters as specified
in the January 26, 1996 ANSI C++ Working Paper, Section 14.7, with some
restrictions (see Section 4.10).
- The compiler now accepts the syntax for explicit instantiation of
templates from the January 26, 1996 ANSI C++ Working Paper, Section
14.1. See Section 10 of the release notes.
4.5 Enhancements and Changes in Version 5.3
This section briefly summarizes changes and enhancements that were made
in Version 5.3. See Using Compaq C++ for OpenVMS Systems for details and additional information.
- Automatic instantiation of templates.
Compaq C++
automatically instantiates C++ templates when special conventions are
followed regarding the naming and location of template declaration and
definition files. Additionally, to successfully link your application
you must use the CXXLINK facility to ensure that all requested
instantiations are included in the application's resulting executable.
For details, see Chapter 5 of Using Compaq C++ for OpenVMS Systems.
- The Standard Template Library (STL), ported for use beginning with
C++ Version ersion 5.3.
See Chapter 6 in Using Compaq C++ for OpenVMS Systems.
- C++ exceptions.
This release supports C++ exceptions. See
Chapter 7 in Using Compaq C++ for OpenVMS Systems for details.
- A new facility, CXXDEMANGLE.
This facility enables users to
decode (or demangle) encoded (or mangled) external function names. See
Section 1.5 in Using Compaq C++ for OpenVMS Systems for details.
- A new facility, CXXLINK.
This facility is for linking C++
applications that make use of the new features in C++ Version ersion
5.3; specifically, automatic template instantiation and exception
handling. In addition, CXXLINK automatically displays any unresolved
symbols at link time in their demangled format. See Section 1.3 in
Using Compaq C++ for OpenVMS Systems for details.
- Changes to the
#include
preprocessing directive to include header files and text library
modules
The algorithm used by C++ Version ersion 5.3 to search for
included files has changed and is described in detail in the latest
cxx
online help for the
/include_directory
qualifier. Also see Section 6 for more information.
- Support removed for
/INSTANTIATE_TEMPLATES
.
C++ no longer supports this command line qualifier. Use the
/TEMPLATE_DEFINE
qualifier to compile programs with C++ templates.
4.6 Problems Fixed in Version 5.6
The following problems have been fixed in Version 5.6:
- Member functions of classes nested within template classes are now
automatically instantiated. [3807, 3433]
- Automatic template instantiation now works when
$ cxx/include:
is fed a directory in UNIX-style path syntax. [3598]
- Incomplete type-name template-args now work under automatic
template instantiation. [3864]
- Overload resolution now only instantiates functions when necessary.
This eliminates unjustified illegal argument combination diagnostics
for unnecessary functions. [3860, 3858, 3655, 3636]
- Template pure virtual functions with defined bodies are now
automatically instantiated. [3887]
- Make
#pragma extern_prefix
stop causing catch to miss exceptions. [3892]
- If the first inline virtual member function in a class template was
unused, it would get an undeserved
MISSINGFUNC
diagnostic under automatic template instantiation. This has been fixed.
[3903]
- Now code is generated for friend functions defined within a class
declaration under automatic template instantiation. [3926]
- Compiling complex programs (such as STL applications) under
#/debug
would cause LINK to give the diagnostic:
%LINK-W-ILLTIR, illegal relocation command ...
|
This has been fixed. [3888]
- Compiling a template valued function would fail with:
%CXX-E-COMPILERBUG, Bug found in compiler: create_vcg_symbol_node:
Non-based symbol lacks a data type.
|
Now this works. [3629]
- Diagnostics generated during an instantiation are now accompanied
by another diagnostic indicating the template name and the type
currently being used for the instantiation as well as the location of
instantiation. [2314]
- The compiler could run out of memory while processing complex
programs such as STL applications. The internal memory corruption
problem that caused this has been fixed. [3626]
- Function template overload resolution now takes cv-qualification
into account when resolving arguments that are pointers to functions.
[4138]
- Non-type template-arguments of nested enum type no longer crash the
compiler. [4141]
- Passing a (non-const) temporary value to a non-member user-defined
operators whose first argument is a non-const reference type no longer
gives an error-level diagnostic. [4107]
- Pointers to members are now allowed as template parameters. [3194]
- A reference downcast in the presence of multiple-inheritance no
longer causes an internal compiler error in routine
il_expression_mapping. [4054]
- User-defined reference conversion operators are now called by casts
under
/standard:ms
mode.
- Carriage return/line feed line terminators are now legal in
/standard:ms
mode. [3958]
- Explicit destructor calls for types with no destructors will now
execute any side-effect causing operators in the call's prefix
argument. [4269]
4.7 Problems Fixed in Version 5.5
The following problems have been fixed in Version 5.5:
- This version corrects a problem that could prevent successful
linking if the code for a template instantiation referenced a symbol in
an object library. [3981, UVO105103]
- This version fixes a problem that could cause an undefined symbol (
__cxxl_stream_format_buffer
) if a source file includes stream.hxx. [4008, UVO105102]
- CXXLINK/VERSION no longer requires a parameter, but CXX/VERSION
still does. For example:
$ CXXLINK/VERSION
DEC C++ CXXLINK V5.5-015
$ CXX/VERSION NL:
C++ Version 5.5-015 ...
|
- This version fixes a problem that caused the compiler to
incorrectly generate a diagnostic for the parameter list of
method
in the sample code below [3750]:
template<class T>
class opiRef;
class opiRef<double> {
opiRef();
void method(double, opiRef<double>);
};
|
- With this version, C++ automatic instantiation no longer
instantiates inline member functions of a class template if these
functions are not used within the application.
- This version fixes a problem that caused programs to access violate
because a variable needing run-time initialization was allocated in a
read-only psect. [1939]
- This version fixes a problem that could cause the compiler to
access violate when compiling a comma list of source files using the
/list qualifier.
- This release fixes a problem that could result in the following
diagnostic from the linker for modules compiled with the
/debug
qualifier [3888]:
%LINK-W-ILLTIR, illegal relocation command
|
- See Section 13.3 for problems fixed in the C++ Standard Library.
4.8 Problems Fixed in Version 5.4
The following problems have been fixed in Version 5.4:
- This version fixes a problem involving try blocks within handlers
where a throw caused an access violation before the catch block was
reached. [3437]
- The C++ compiler now accepts calls of destructors on built-in
types. [321]
- See Section 13 for problems fixed in the STL.
4.9 Problems Fixed in Version 5.3
The following problems have been fixed in Version 5.3:
- Problem depending on exact names of included files
Previously,
a problem involving, among other factors, the exact lengths of file
names processed by the compiler caused the compiler to bug check.
Immediately preceding the bug check was an error message giving the
text of a
#include
directive with no error marker pointing at a location within the
directive. This problem has been fixed.
- In Version 5.2, logical name translation was inadvertantly applied
to text library module names. This could cause text library modules not
to be found. This problem has been fixed.
A problem with deriving
the device:directory specification for a "parent file" was
also introduced in Version 5.2. This problem has also been fixed.
- C++ used to require explicit definitions for static data members.
Tentative definitions are now provided automatically when compiling
with the
/STANDARD:CFRONT
compatibility mode switch. [127]
- Previously, C++ would only allow references to static data members
within default arguments in member functions if the static data members
had been declared earlier in the class. Now, forward references are
allowed. [290]
- Previously, C++ would reject as an error the use of a protected or
private type in an invocation of #pragma define_template. This is now
accepted. [646]
- C++ passes class objects with user-defined constructors by
reference. This caused the
va_start
macro to fail if the parameter before the ellipsis was one of these
objects. The compiler and the
stdarg.h
header file have been fixed so that the
va_start
macro adjusts the parameter list correctly to point to the first
parameter passed by ellipsis. [1103]
- Previously, C++ required template-names within the bodies of
template declarations to have a template-arg-list argument,
and did not allow the names of constructors and destructors to have
template-arg-list arguments, as, for example, in the following
:
template <class T> class C {
public:
C();
~C();
C<T> *p;
};
|
Such template-arg-list arguments (for example,
<T>
) are now optional. Thus, C++ now accepts the following: [1316]
template <class T> class C {
public:
C<T>();
~C<T>();
C *p;
};
|
- The
/TEMPLATE_DEFINE
qualifier now instantiates template friend functions. [1738]
- Inline function templates with const arguments are now successfully
instantiated by calls with non-const arguments. [1742]
- The
/TEMPLATE_DEFINE
qualifier no longer causes multiply-defined symbols for explicit
specializations. For example, C++ now accepts the following: [1970]
template <class T> class C { void f(T); };
template <class T> void C<T>::f(T) {}
void C<char>::f(char) {}
|
- C++ no longer diagnoses extraneous semicolons at file scope under
the
/STANDARD:CFRONT
and
/STANDARD:MS
compatibility modes. [2175]
- C++ no longer bugchecks when compiling a program containing a call
to a virtual function of a
template-arg
type. For example, C++ now accepts the following: [2454]
template <class T> class HANDLE {
public:
HANDLE(T &t) { t.use(); }
};
class CHAR {
public:
virtual void use() {}
HANDLE<CHAR> resize();
};
|
- C++ now accepts main functions declared with return type
void
. If the program exits by returning from such a main program, a
successful status value is implicitly returned to the command language
interpreter. [2542]
- Previously, C++ would reject as an error the declaration of a union
containing a struct, which in turn contained a volatile member. Such
declarations are now accepted. [2971]
4.10 Current Restrictions
This section contains usage notes and known problems with C++
Version 5.6.
- See Section 8.6 (namespace restrictions) for restrictions related
to support for namespaces.
- If you compile a program that performs many complicated template
instantiations you may receive the following message:
Fatal: Insufficient virtual memory to continue compilation.
%LIB-F-INSVIRMEM, insufficient virtual memory
|
To workaround this problem try the following:
- Raising your paging file quota: to see your current paging file
quota, enter
show process/quota
on the command line.
- Separating the instantiations into different files that can be
compiled independently. This may reduce the amount of the paging file
quota required by each compilation unit.
- C++ recognizes
memset
,
memmove
, and
memcpy
as builtin functions. The string.h header file defines macros that will
cause, for example,
memset
to be replaced by
__MEMSET
in a function call context. This in turn invokes the builtin version of
the memset function. Using the global scope operator (::) in an
invocation of these function can interfere with the compiler's builtin
function processing. The result is an undefined symbol, such as
__MEMSET
, when linking an application.
To workaround this problem either
add an
#undef
directive (for example,
#undef memset
after a
#include
of string.h) or avoid using the global scope operator (::) with these
functions.
- When linking, CXXLINK creates a linker options file in the
directory of the first file specified as the first parameter to
CXXLINK. Thus, this directory must be writeable. This change was made
in Version 5.5 to correct a problem that could prevent successful
linking if the code for a template instantiation referenced a symbol in
an object library.
For example:
$ CXXLINK USER:[DIR]A,SYS$LOGIN:B,C
|
For the previous example, this command creates an options file in
the directory of the first file, USER:[DIR]. Thus, this directory must
be writeable.
- As noted in Section 13.1, portions of the ANSI C++ Standard
Library have been reimplemented for Version 5.6 to better satisfy the
requirements of the ANSI C++ standard. These changes generally increase
compilation times and virtual memory requirements for programs that use
the C++ standard library.
- Regarding automatic instantiation: dependency checking to ensure
that instantiations are up to date currently does not account for the
following command-line qualifiers:
/SHOW
/WARNINGS
- C++ does not support inserting template declaration or definition
files into text libraries.
- C and C++, like VAX C, does not point the debugger at the file
argument of the #line preprocessor directive. [56]
- The debugger does not recognize the members of an anonymous union
as members of the containing class. [333]
- The compiler does not recognize DECSPECIFIC.H. [376]
- The compiler does not pool string literals consistently. [841]
- Specifying /LIST/PREPROCESS_ONLY causes form feeds to appear in the
listing file [888]
- Recursive deletes cause a bugcheck in the VCG optimizer. [1351]
- Specifying /DBG with sources containing deeply nested pointers
causes the compiler to crash. [1432]
- The compiler exits with an ACCVIO within GENERATN.C. [2336] [4052]
- The compiler does not support VAXC builtin prototypes. [2339]
- The compiler generates a bugcheck when assigning a constant string
literal to a non-static variable (of the globalvalue extern model
type). [2512]
- The compiler does not validate on VAX systems. [2749]
- The compiler geerates a bugcheck during code binding under the
following conditions: [2816]
50 or more overloaded functions with the same name are defined
The /DEBUG qualifier is specified
- The compiler generates a
-RMS-W-RTB
warning message when readinh 81-byte records. [3016]
- Stepping through certain if/else constructs on VAX is somewhat
confusing. The C++ compiler feeds fewer line numbers to the VCG than
VAX C. [3256]
- The ?: conditionals of reference casts causes the compiler to
bugcheck. [3257]
- The following command generates an internal compiler error: [2853]
cxx/define=VMS/exceptions admnsess.cxx
|
- A bug in the Version 5.5 sanity kit causes failure on nonclustered
node. [4067]
- The compiler generates a bugcheck if
/TEMPLATE_DEFINE=FILE_DEFINITION_TYPE is specified. The correct
qualifier is /TEMPLATE_DEFINE=DEFINITION_FILE_TYPE. The documentation
has been corrected. [4202]
- The compiler generates a bugcheck during code binding. [4510]
- The debugger incorrectly displays
y_int
's value according to the compiler's instructions, which say that
y_int
has the constant value 3 only at a single instruction. [6083]
- C++ does not accept the last four productions in the syntax for
template type-parameters as specified in section 14.7 of the ANSI C++
Working Paper.
- The compiler does not accept a parameter-declaration (non-type
template parameters) for function templates.
- The C++ compiler reports an error when argument signatures of
overloaded functions differ from each other only in enumeration types
of the same name defined in different classes. For example:
void overloaded_function(class1::enum_name x) { }
void overloaded_function(class2::enum_name x) { }
|
To work around this problem, use different names for enumeration
types defined within different classes. [1940]
- Some restrictions that pertain when using STL with C++ are
documented in Section 13. [3145]
- The
/show=symbols
qualifier is not supported. To match the C++ mangled names with names
in the C++ source file, use CXXDEMANGLE. See Section 1.5 in
Using Compaq C++ for OpenVMS Systems for details. Also see Section 4.11. [75]
- Programs that declare a function parameter that is an array of an
incomplete type will not compile with the C++ compiler. [47]
- Currently, the compiler allows you to take the address of any
predefined built-in function. This is illegal and a compile time error
will eventually be generated. [3236]
- The functions
lib$establish
and
lib$revert
are recognized by the compiler as builtin functions. There is currently
a restriction that these built-ins do not return the previous condition
handler as their function result. [68]
- When examining a class which has an anonymous union as a member
from the debugger, the debugger displays the class as if the union and
its members did not exist. [333]
- C++ does not support the DEC Source Code Analyzer (SCA). [1612]
- C++ does not support the Common Data Dictionary (CDD). [1383]
- Because of a bug in the OpenVMS Linker utility,
extern_model relaxed_refdef
(the default), may fail under the following circumstances:
- An attempt to link an
extern_model common_block
reference or tentative definition against an
extern_model relaxed_refdef
definition will not cause the two modules to use the same runtime
storage for the variable if the relaxed_refdef definition was compiled
with C++ Version 1.1. For example:
Module 1:
#pragma __extern_model __common_block
extern int x; // or int x;
Module 2:
#pragma __extern_model __relaxed_refdef
int x = 2; // Fails if compiled with C++ Version 1.1
|
- Also, an attempt to link an
extern_model strict_refdef
declaration against an
extern_model relaxed_refdef
tentative definition will cause the linker to resolve the variable's
address as 0. This will result in an access violation at runtime if
your program tries to fetch from or store to the variable. For example:
Module 1:
#pragma __extern_model __strict_refdef
int x; // or extern int x; or int x = 3;
Module 2:
#pragma __extern_model __relaxed_refdef
int x; // Address resolved to 0
|
- Under
extern_model relaxed_refdef
, an attempt to link a definition against a tentative definition may
either cause the linker to resolve the variable's address as 0, or will
produce the following message:
%LINK-E-OUTSIMG, attempted store ... is outside image binary
|
If the variable's address resolves to 0, an access violation
results at runtime if your program tries to fetch from or store to the
variable. For example:
Module 1:
#pragma __extern_model __strict_refdef
int x = 5;
Module 2:
#pragma __extern_model __relaxed_refdef
int x; // Generates "%LINK-E-OUTSIMG ..."
|
You can work around these problems by using one of the following
techniques:
- When using
extern_model relaxed_refdef
(the default), declare all external references using the keyword
extern
and provide only one definition by either declaring the variable
without the keyword
extern
or by initializing the variable. For example:
#pragma __extern_model __relaxed_refdef
extern int x;
#pragma __extern_model __relaxed_refdef
int x;
#pragma __extern_model __relaxed_refdef
int x = 23; // or extern int x = 93;
|
You can also resolve this problem by recompiling all such modules
containing relaxed refdef definitions with Compaq C++ for OpenVMS VAX.
- Compile all modules with
/extern_model:strict_refdef
.
- Compile all modules with
/extern_model:common_block
. [388]
4.11 Other Restrictions
This section describes problems, of interest to C++ users, that Compaq
has no current plans to fix. Where feasible, a way to work around the
problem is provided.
- Generating a machine code listing of a reference to a function
whose name is exceptionally long may cause the compiler to report that
memory is exhausted or may cause the compiler to loop, generating
continuation lines in the listing file. You can work around the problem
by (1) shortening the name, or (2) not asking for a machine code
listing, or (3) if the function is static, make it
extern
instead. [329]
- C++ is subject to RMS-imposed constraints in terms of maximum
record sizes that can be written. This means that DECnet remote file
accesses of source lines that exceed 4096 characters are not allowed.
- Extremely large, sparse switch statements cause the compiler to
generate code that when linked is far larger than necessary. The
problem only seems to appear for switch statements whose range (the
difference between the highest case label and the lowest case label) is
in the tens of thousands and where the number of case labels is
slightly more than 5% of the range of the case. One workaround for this
problem is to add an extra case label that increases the range of the
switch so that the number of case labels falls below 5% of the range
(for example, add case 100000: just before the case that handles bad
switch indexes). This will cause the compiler to turn the switch
statement into a sequence of if-then else statements. The best
workaround is to rewrite the switch into a series of smaller, more
densely packed switch statements or to choose an alternate
implementation altogether (for example, a table search that returns an
index into an array of functions). [468]
5 Creating an OpenVMS Shareable Image from C++ Source Code
This section describes how to to create a shareable image on an OpenVMS
System. Before attempting this, you should review the section in the
OpenVMS Linker Utility manual that describes shareable images.
The steps described here are not intended to cover all of the details
of creating shareable images; they are instead intended to address the
unique problems related to performing this task for C++ code.
This section cites examples of code supplied with the compiler kit. You
will find the sources in SYS$COMMON:[SYSHLP.EXAMPLES.CXX]. Table 1
gives a short description of each of the files.
5.1 Determining Which Names to Export
The set of header files that contain class definitions for your product
determine what routines and data need to be be exported by your
shareable image. Any member function or data declared as public in a
class will need to be exported; the only exceptions to this rule are
inline functions whose code exists within the header file itself.
C++ encodes type information in function and data names, it is these
encoded names that need to be exported, not the function name that
appears in the code. For example:
class test {
public:
void show_it();
void show_it(int);
};
|
In this example, the function
show_it()
generates the encoded name
SHOW_IT__4TESTXV
. Similarly, the function
show_it(int)
generates the name
SHOW_IT__4TESTXI
.
5.2 Generating Symbols
Generating a list of symbols that must be exported is the single most
complicated part of creating a shareable image that supports a C++ code
base. The procedure involves several steps requiring human intervention
and a knowledge of the interface into the product.
Compaq strongly recommends that the
__extern_prefix
compiler directive be used to avoid name conflicts with other software
packages that may exist on the system. When using this directive, it is
easy to identify all global objects using a LIBRARY/LIST/NAMES command.
The following steps assume that the code makes use of the
__extern_prefix
directive.
5.2.1 OpenVMS Alpha
- Create an object library and put all object modules that will be
part of the shareable image into the library by issuing the following
command:
$ LIBRARY/CREATE sw.olb SW.OBJ,SW_VEC_ALPHA.OBJ
|
- Create a list of global names from the object library by executing
the following command:
$ LIBRARY/LIST=sw_shr_alpha.opt/NAMES sw.olb
|
- Process the SW_SHR_ALPHA.OPT file as follows:
- Remove any extra lines that are not global names and change the
remaining lines so they look as follows:
SYMBOL_VECTOR=(SW_G_SW = PROCEDURE)
SYMBOL_VECTOR=(SW_REAL__9STOPWATCHXV = PROCEDURE)
SYMBOL_VECTOR=(SW_RESET__9STOPWATCHXV = PROCEDURE)
|
- Include only names you know you want to export.
If you are
exporting a class instance, and you are using the macros similar to the
ones provided in the example code, the LIBRARY/LIST/NAMES listing will
contain both the global pointer from the macro source and the
_DATA
version from the C++ source. For example:
Module SW
SW_G_SW_DATA
[...]
Module SW_SHR_DATA
SW_G_SW
|
Only the global pointer from the macro source should be included in
the symbol vector (
SW_G_SW
), not
SW_G_SW_DATA
.
- Test link using the options file as follows:
$ LINK/SHARE/EXE=SW_SHR.EXE -
SW.OBJ,SW_VEC_ALPHA.OBJ, -
SW_SHR_ALPHA.OPT/opt
|
- Process the link errors (if any). This may be an iterative process:
expect to see several warnings in the following form:
%LINK-W-SYMVABNORMAL, Symbol SW_G_SW
defined in module SW as DATA
was declared in options as PROCEDURE
|
Re-edit the linker options file and change the
SYMBOL_VECTOR
line from
PROCEDURE
to
DATA
. For example:
SYMBOL_VECTOR=(SW_G_SW = PROCEDURE)
|
becomes:
SYMBOL_VECTOR=(SW_G_SW = DATA)
|
Try the link command again.
- Continue the process until the linker reports no more errors.
5.2.2 OpenVMS VAX Following OpenVMS Alpha
If you are creating both an OpenVMS VAX and an OpenVMS Alpha shareable
image, perform the OpenVMS Alpha procedure first. The OpenVMA Alpha
Linker Utility provides better warnings to help avoid confusing data
and procedure external data.
The steps to go from an OpenVMS Alpha linker options file to an OpenVMS
VAX transfer vector macro file are as follows:
- Copy the OpenVMS Alpha linker options file to create a macro source
file as follows:
$ COPY SW_SHR_ALPHA.OPT SW_VEC_VAX.MAR
|
- Remove all non SYMBOL_VECTOR lines from the file.
- Assuming the use of macros similar to the ones found in the
SW_DEFS.MAR file, modify each SYMBOL_VECTOR lines as follows (actual
names have been shortened):
OpenVMS Alpha |
OpenVMS VAX |
SYMBOL_VECTOR=(9STWATCHXV=
PROCEDURE)
|
$CALL 9STWATCHXV
|
SYMBOL_VECTOR=(G_SW =
DATA)
|
$GSYM G_SW SW_DATA
|
- See the comments below on adding $FUTURE to reserve space in the
symbol vector.
- Continue with the steps below on compiling, linking and testing the
shareable image.
5.2.3 OpenVMS VAX
- Create an object library and put all object modules that will be
part of the shareable image into the library by issuing the following
command:
$ LIBRARY/CREATE sw.olb SW.OBJ
|
A macro source file will be added to the code base later.
- Create a list of global names from the object library by executing
the following command:
$ LIBRARY/LIST=sw_vec_vax.mar/NAMES sw.olb
|
- Process the SW_VEC_VAX.MAR file as follows:
- Remove any extra lines that are not global names.
Take each
symbol listed and place it on a separate line. Thus:
Module SW
SW_G_SW_DATA SW_REAL__9STOPWATCHXV SW_RESET__9STOPWATCHXV SW_START__9STOPWATCHXV
|
Becomes:
SW_G_SW_DATA
SW_REAL__9STOPWATCHXV
SW_RESET__9STOPWATCHXV
SW_START__9STOPWATCHXV
|
- Using macros similar to the SW_DEFS.MAR example code, change each
line depending on its data type. For example:
Routines:
Change: |
To: |
SW_REAL__9STOPWATCHXV
|
$CALL SW_REAL__9STOPWATCHXV
|
Data:
Change: |
To: |
SW_G_SW_DATA
|
$GSYMSW_G_SW SW_G_SW_DATA
|
If you are exporting a class instance, and you are using the macros
similar to the ones provided in the example code, the
LIBRARY/LIST/NAMES of the SW.OBJ will list the
_DATA
version of your class instance. The MACRO code will create a pointer to
this
_DATA
version.
- Because OpenVMS VAX shareable images create a static transfer
entry table in the shareable image, the best course of action is to
extend the size of the transfer vector with spare space that can be
used for future entry points without having to break upward
compatibility. The SW_VEC_VAX.MAR example shows how to use the $FUTURE
macro to reserve some space in the transfer vector.
- Compile the macro source:
$ LIBRARY/CREATE/MACRO SW_DEFS.MLB SW_DEFS.MAR
$ MACRO SW_VEC_VAX+SW_DEFS/LIB
|
- Test link as follows:
$ LINK /SHARE/EXE=SW_SHR.EXE -
SW.OBJ,SW_VEC_VAX.OBJ, -
SW_SHR_VAX.OPT/OPT
|
- Process any link errors and review the above steps if necessary.
- Continue the process until the linker reports no more errors.
5.3 Verification
If you wish to verify the encoded names (and what they actually
reference) you can use the CXXDEMANGLE utility to view the translation.
5.4 Testing the Results
Once done, you should be able to link and run the test program using
the shareable image as follows:
$ DEFINE SW_SHR SYS$DISK:[]SW_SHR.EXE
$ LINK SW_TEST,SYS$INPUT:/opt
Sw_Shr/Share <ctrl/z>
$ RUN SW_TEST
|
The results should be the same as the test being linked against the
object modules used to create the shareable image.
If the test output differs or if the link fails, review the steps used
to create the entry points.
5.5 Additional Topics
The sections below describe some common topics that relate to OpenVMS
Shareable images and C++. They are provided to help C++ users on
OpenVMS systems better understand the extra steps required in creation
of a shareable image that provides a C++ interface.
5.5.1 Testing
A test that accesses all entry points should be written. The test needs
to be verified by hand to make sure it accesses each public class
member function (non-inlined) or public data item. Although inline
functions are not exported, the test should be verbose enough to
include a call to each and every method within a class.
The test should first be linked against the same set of objects that
were used to create the shareable image. It should then be relinked
using the shareable image. The two test images should have the same
results.
If you intend to provide an upward compatible shareable image, before
shipping out your first shareable image, you should verify that new
items can be added without breaking existing programs that are linked
against an existing shareable image.
Here are the steps to accomplish this:
- Link and test the verification test program against a pre-modified
shareable image.
- Make modifications to the shareable image code base (including
adding any new entry points).
- Run the same executable image created in step 1 using the new
shareable image. Do not relink the test image otherwise you are not
performing an test of link compatibility.
The test program should run without error. The program will not be able
to access any of the new items added to the shareable image but telling
a user (a customer) that they must recompile to get new features is
easier instructing a customer to relink because you made a coding
change.
Breaking upward compatibility can cause several different run time
errors to occur depending on what was changed. For example, changing
the order of
SYMBOL_VECTOR
entries or
$CALL
lines will cause the wrong routine to be called or the wrong data
element to be accessed at run time. This, more often than not, results
in a run time access violation.
5.5.2 Adding New Entry Points
If new classes or new member functions are added, you can use the
previously described $ LIB/LIST/NAMES step to determine the new encoded
names that must be exported. Existing names must remain if upward
compatibility of the shareable image is to be maintained. See the
OpenVMS Linker Utility manual for more details on extending a
shareable image's global entry point list.
5.5.3 Using __extern_prefix
Providers of shareable images need to ensure that users of their
shareable image do not experience name conflicts with other shareable
images and software packages that may be installed on the same system.
The recommended method of doing this in C++ is by using the
#pragma __extern_prefix
compiler directive. For example:
#pragma __extern_prefix sw_
|
The sw_ variable represents a name unique to your software
package.
The C++ Class Library uses
CXXL$
as the unique name to export all of its global entry points.
The result of using
#pragma __extern_prefix
is that all global data and global routines are prefixed with the
unique name as part of their encoded name.
For examples of how to use
__extern_prefix
, see the SW.HXX example, located in the
SYS$COMMON:[SYSHLP.EXAMPLES.CXX] directory..
5.5.4 Transfer Vectors and Symbol Vectors
A Transfer Vector is the term used to describe the area of a shareable
image in OpenVMS VAX that contains its public interface (or Entry
Points).
The only way to create this transfer vector is by using VAX MACRO.
A Symbol Vector is the term used to describe the entry points for an
OpenVMS Alpha shareable image. The symbol vector is created via the
SYMBOL_VECTOR directive in a linker options file.
5.5.5 Exporting Global Data
For a shareable image to export a global instance of a class (for
example:
cout
from CXXL$011_SHR) it must export a pointer to that instance. The
OpenVMS Linker Utility manual describes this type of export as
a "data cell".
Exporting a pointer allows the developer of the shareable image the
option of modifying the class definition in a future release. The
developer must take care to not effect the memory layout of the class.
The SW_SHR.HXX example file, located in the
SYS$COMMON:[SYSHLP.EXAMPLES.CXX] directory, shows how the exporting of
the pointer can be made somewhat invisible to the user.
5.5.6 Initilizing Global Data
The C++ compiler generates code in the LIB$INITIALIZE image program
section (psect), which calls every global objects's constructor routine
before the program executes its first statement.
This is also true for a shareable image's global data. The OpenVMS
image activator calls each LIB$INITIALIZE contribution for each
shareable image that is linked into a program. This means that, before
a program executes its first statement, all global classes in every
shareable image it references must have had their constructors called.
If you plan on providing an option of linking with an object library
form of your shareable image, refer to the section in Using Compaq C++ for OpenVMS Systems on
linking against the C++ Class Library Object Library. This section
shows how users of the object library should link their application.
5.5.7 Virtual Functions
Virtual functions can not be added to public classes without breaking
compatibility. This limitation is imposed by the method used to
implement virtual function tables in the C++ object model. See
Using Compaq C++ for OpenVMS Systems for more details on the C++ object model.
5.5.8 Using UNIVERSAL=
On OpenVMS VAX, you have the option of exporting global data and
routines by using the UNIVERSAL option in a linker options file. Using
this option requires any image linked against the shareable image to
relink every time the shareable image is rebuilt. Because of the need
to relink each time, Compaq does not recommend using this feature.
5.5.9 Description of Sample Code for Creating a Shareable Image Using C++
The SW_SHR sample code consists of several source modules, a command
procedure and this description. Table 1 lists of each of the
modules.
The code creates an OpenVMS shareable image called SW_SHR.EXE that
supplies a Stopwatch class identical to the C++ Class Library's
Stopwatch class. The Compaq C++ Class Library Reference Manual has details on the Stopwatch class.
SW_SHR also provides an instance of a Stopwatch class named
G_sw
that shows how to export a class instance from a shareable image. The
method used is the same method used to export
cout
,
cin
,
cerr
, and
clog
from the C++ Class Library shareable image.
The files listed in Table 1 are located in the
SYS$COMMON:[SYSHLP.EXAMPLES.CXX] directory.
Table 1 Shareable Image Example Files
Module Name |
Description |
SW_DEFS.MAR
|
Macro definitions for use by both the SW_VEC_ALPHA and SW_VEC_VAX macro
source files.
|
SW_DEFS_ALPHA.MAR
|
Macro definitions of globally accessible class objects defined within
the shareable image.
|
SW_DEFS_VAX.MAR
|
Entry point macro definitions and macro definitions of globally
accessible class objects defined within the shareable image.
|
SW_SHARE.HXX
|
General use macros to make exporting of global data (class instances)
from shareable images more transparent to the users of class objects.
|
SW.HXX
|
The definition of the Stopwatch class supplied by the shareable image.
|
SW.CXX
|
Source associated with the public functions defined in SW.HXX. The file
also contains the declaration of the global Stopwatch (G_sw) class
instance.
|
SW_TEST.CXX
|
A test of each of the Stopwatch's public access points and also the
G_sw class instance.
|
SW_BUILD.COM
|
A DCL command procedure used to build both the shareable image and the
program.
|
SW_SHR_ALPHA.OPT
|
An OpenVMS Linker options file, used on OpenVMS Alpha, that contains
the SYMBOL_VECTOR entry points and other shareable image linker
directives.
|
SW_SHR_VAX.OPT
|
An OpenVMS Linker options file, used on OpenVMS VAX, that contains
shareable image linker directives.
|
6 File Inclusion
To support processing of "prologue" and "epilogue"
file inclusion, the C++ compiler introduced substantial changes to the
processing of the
#include
directive prior to Version 5.3 that allowed for increased code
commonality between the OpenVMS Alpha and VAX versions of the compiler.
In Version 5.3, further changes were made to make the
#include
searching behavior of the VAX and Alpha OpenVMS compilers identical,
and to support new ANSI C++ requirements on header file naming
conventions. The following are some of the highlights of these
modifications:
- New qualifer option,
/assume=[no]header_type_default
This option disables the default file type mechanism for header
files, as required by the emerging ANSI C++ standard, and gives search
precedence to the ANSI C++ versions of the headers. For details see the
discussion of file inclusion in the
cxx
online help for the
/include_directory
qualifier.
- New text library
C++ Version ersion 5.3 has a new text library
named
SYS$LIBRARY:CXXL$ANSI_DEF.TLB
. For details on how the search algorithm affects the inclusion of
files in this text library, see the discussion in the
cxx
online help for the
/include_directory
qualifier.
- Meaning of empty string in /INCLUDE_DIRECTORY
The UNIX
convention of using -I without a pathname is now fully supported by the
/include_directory
qualifier. If an empty string occurs as any element in the list of
specifications supplied by this qualifier, the compiler does not search
any of its default directories, logical names, or text libraries and
uses only the specifications from the command line to find include
files.
- Kit changes for text library packaging of system headers
With
this release, the C++ kit for OpenVMS VAX has been changed to match the
OpenVMS Alpha kit with respect to header file installation and
searching. In Version 5.3, C++ directly searches text libraries for the
default runtime system header files just as the Alpha version of the
compiler has always done. Previously, the VAX compiler was limited to
searching a maximum of two default text libraries (CXX$TEXT_LIBRARY and
DECC$RTLDEF.TLB) in addition to any specified by the user on the
command line. This limitation has been removed, and as on Alpha the
compiler may search several additional default text libraries (see the
cxx
online help for details).
As on OpenVMS Alpha, the Version 5.3 C++
installation procedure for OpenVMS VAX will create header file
REFERENCE
directories containing plain text copies of the header files packaged
in the text libraries. This is as a user convenience for viewing and
using the
SEARCH
command; the compiler will not search these directories by default.
Therefore, the system startup procedure for the compiler no longer
defines the system logical name
CXX$LIBRARY_INCLUDE
, and the installation kit deassigns that logical name if it is already
defined as a system logical during the installation.
To maintain
functional compatibility with previous releases, the Version 5.3
compiler will still check for a definition of the logical name
CXX$LIBRARY_INCLUDE
. If this logical is defined, the compiler then uses it to search for
plain text copies of header files, and will avoid searching the default
text libraries for headers included with the quote or angle-bracket
#include
syntax. But by default, the logical name is undefined and the compiler
will search the default text libraries to find such headers.
The
Version 5.3 kit installation normally extracts reference copies of the
headers as mentioned above. The modules from each separate text library
file are extracted to a separate directory as shown in the following
list. The last component of each directory name matches the file name
of the .TLB library file whose modules it contains, and the default
file type for files in each directory is as shown:
SYS$COMMON:[CXX$LIB.REFERENCE.CXXL$DEF_HXX].HXX
SYS$COMMON:[CXX$LIB.REFERENCE.CXXL$DEF_H].H
SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF].H
SYS$COMMON:[DECC$LIB.REFERENCE.SYS$STARLET_C].H
SYS$COMMON:[CXX$LIB.REFERENCE.CXXL$ANSI_DEF].
|
Note
OpenVMS VAX systems through Version 7.0 do not supply a
SYS$STARLET_C.TLB as OpenVMS Alpha has always done. The starlet headers
are constructed by the compiler kit and placed in the SYS$STARLET_C
directory as well as in DECC$RTLDEF.TLB and its directory. A future
version of OpenVMS VAX is expected to ship SYS$STARLET_C.TLB as on
Alpha.
|
Although the Alpha compiler normally finds system headers in the
default text libraries, in the absence of a definition for the logical
names
CXX$LIBRARY_INCLUDE
or
CXX$SYSTEM_INCLUDE
it first searches directories with names the same as the reference
directories previously listed, but with
REFERENCE
changed to
INCLUDE
. Normally, no such directories exist on OpenVMS Alpha systems and so
the modules are found in the default text libraries. But if they do
exist, the files in them supercede modules of the same name in the
default text libraries. Previous versions of the VAX compiler have
behaved in a similar way except that they expected a single
"flat" structure for each language's include files:
SYS$COMMON:[CXX$LIB.INCLUDE].HXX
SYS$COMMON:[DECC$LIB.INCLUDE].H
|
In previous versions of the VAX compiler, these directories were
required to be fully populated because the compiler was unable to
search all of the default text libraries. The Version 5.3 compiler can
search all of the default text libraries, so these directories do not
need to exist. Therefore, the Version 5.3 kit installation looks for
preexisting SYS$COMMON:[DECC$LIB]INCLUDE.DIR and
SYS$COMMON:[CXX$LIB]INCLUDE.DIR, and renames them to OLD_INCLUDE.DIR.
It does not create and popluate new [*$LIB.INCLUDE.*] directories. But,
to match the C++ compiler's behavior on OpenVMS Alpha, the C++ compiler
on OpenVMS VAX does search these directories if they exist and neither
CXX$LIBRARY_INCLUDE
nor
CXX$SYSTEM_INCLUDE
are defined as logical names; so, the files in them will supercede
modules of the same name in the default text libraries just as on
OpenVMS Alpha systems.
- Restriction on total number of text libraries searched
There
remains a VAX-only restriction that the total number of text libraries
searched, including user-specified libraries using the
/LIBRARY
qualifier, cannot exceed 16. If the limit of 16 total text libraries is
exceeded in a compilation, the following warning message occurs:
%CC-W-TOOMANYTXTLIB, Too many text libraries.
Library 17th-library-name and subsequent will not
be searched.
|
If no errors are caused by missing include files, you can disable
this warning with the
/warn=disable=TOOMANYTXTLIB
qualifier.
If errors are caused by missing system header files and
17th-library-name is CXX$TEXT_LIBRARY or one of the compiler
default text libraries from SYS$LIBRARY, then the solution is to reduce
the number of user-specified command-line libraries. An alternative is
for the compiler to get system headers from ordinary files in
directories. This requires that the
#include
directives for system headers in user source code have the standard
#include
syntax rather than the DIGITAL-specific module-name syntax. If
reference copies of headers were extracted at installation time, you
can specify the installed
[.REFERENCE.*]
subdirectories in a search list logical used in a
/include
qualifier or in the
CXX$SYSTEM_INCLUDE
logical as appropriate.
If several users on a system encounter the
problem of missing system header files because they use too many text
libraries, then the system manager may want to install the reference
copies of system headers and then rename (or copy) the
[.REFERENCE.*]
subdirectories to
[.INCLUDE.*]
. The compiler searches the
[.INCLUDE.*]
directories by default, so it would not then be necessary for
individual users to modify build procedures to look for plain text
copies. It would still, however, be necessary to suppress the
TOOMANYTXTLIB
warning message.
- Interaction with older versions of C
The C and C++ compilers
both ship copies of the C RTL header files and arrange for starlet
header files to be constructed and made available during installation.
The two compilers have traditionally accessed these headers from the
same locations, so that upgrading one of the compilers would upgrade
the CRTL and starlet headers accessed by the other compiler even if the
other compiler was not upgraded. The Version 5.3 compilers continue in
this fashion, but the interaction with the header files is more complex
given the change in the way the new compilers find them. It is
generally recommended that if you have both C and C++ installed, that
you upgrade them to the same version at the same time, and especially
so for upgrading to Version 5.3.
Nevertheless, the Version 5.3 C++
Version AX kit attempts to upgrade the headers without damaging the
operation of an earlier installed version of Compq C. The kit checks
for existence and version of SYS$SYSTEM:DECC$COMPILER.EXE. If it exists
and is earlier than Version 5.3, the kit generates a common compiler
startup procedure to define a system logical DECC$LIBRARY_INCLUDE as
the following search list:
SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF],
SYS$COMMON:[DECC$LIB.REFERENCE.SYS$STARLET_C],
SYS$LIBRARY
|
This will cause the older C compiler to search the new
REFERENCE
copies of the C headers provided by the C++ installation. While the
Version 5.3 compilers themselves never implicitly search the
REFERENCE
copies of header files, a Version 5.3 installation may cause an older
compiler to search the
REFERENCE
copies. So if you are upgrading C++ to Version 5.3 and are not planning
to upgrade C right away, you should accept the default of installing
reference copies; otherwise, the C compiler will be unable to find the
updated headers and you will need to define
DECC$LIBRARY_INCLUDE
(manually) to access the old header files. The installation displays
the current definitions for all
DECC$
and
CXX$
logical names before making any changes. Note that the old headers may
have been renamed to [.OLD_INCLUDE], depending on whether or not they
were previously installed in the default location. The Version 5.3 kits
do not directly support installation of the REFERENCE headers in other
than the default location.
Note that when the C compiler is
upgraded to Version 5.3, it will deassign the system logical
DECC$LIBRARY_INCLUDE
and generate a startup procedure without a definition for it. With both
C and C++ compilers at Version 5.3, the
REFERENCE
copies are for human convenience only.
Under no circumstances does
the Version 5.3 C++ kit define the logical name
CXX$LIBRARY_INCLUDE
. However, the Version 5.3 C kit will define this logical name if its
installation kit detects a version of C++ older than Version 5.3.
7 Improving Build Performance
This section contains suggestions for improving the performance of C++
on your system.
7.1 Template Instantiation
The
cxxlink
command automatically instantiates templates by prelinking to find
unresolved symbols due to uninstantiated templates. Instantiations are
completed by compiling instantiation source files in the repository.
The prelinking and compiling process is repeated until all template
instantiations have been compiled.
For some applications, the link-time automatic instantiation process
can be time consuming. The following approaches may be helpful in
reducing the amount of time it takes to build your application:
- Selectively use compile-time instantiation options for some
modules. These options can improve build performance because templates
are instantiated when the original C++ sources files are compiled
without the need to reprocess large header files. See Section 9 for
more information concerning the the
local
and
used
compile-time instantiation options for the
/template_define
command line qualifier.
- Build a reusable library of instantiations. With this approach,
stable and common instantiations are compiled, and the resulting object
files are put in a library. When building your program, you link with
this library rather than redoing all instantiations every time you
build. At the end of Section 5.2 in Using Compaq C++ for OpenVMS Systems is a step by step
example on how to create a library of common instantiations.
8 Namespaces Support
C++ Version 5.6 has added support for namespaces, as specified in the
draft ANSI C++ Standard. Section 8.6 describes restrictions that
pertain to namespaces support.
A namespace is an optionally named region in which you can place
declarations. They are useful for avoiding name clashes. For example,
namespace N {
int x;
}
namespace M {
double x;
}
|
Placing these conflicting declarations of
x
into differently-named namespaces, lets you use both variables safely
in your program; you can use the appropriate qualified names (
N::x, M::x
), or use one of the other means described in this section.
You can split the definition of a namespace into separate parts that
can appear in one or more translation units. A translation unit can be
thought of as a single source file together with any header files that
the source file pulls in.
8.1 Namespace definition and namespace extension
A namespace is defined as follows:
namespace identifier { namespace-body }
namespace-body
Is a sequence of declarations.
Defining another namespace using the same name constitutes an extension
namespace definition. For example:
namespace N {
int n;
}
...
namespace N { // extend namespace N
void func(void);
}
|
The identifier used to name a namespace must be unique in the region
where it appears.
Every namespace definition must appear in the global scope or in a
namespace scope. Namespaces can be nested.
8.2 Unnamed namespaces
You may omit the identifier in a namespace definition:
namespace { namespace-body }
An unnamed namespace definition behaves as though it was written as:
namespace unique {}
using namespace unique;
namespace unique { namespace-body }
C++ replaces all occurrences of unique in a translation unit
with the same identifier, and this identifier is different from all
other identifiers
Unnamed namespaces are intended to be the preferred alternative to
using the
static
keyword in namespace scope. Unnamed namespaces allow items to be
visible within an entire compilation unit, but not visible in other
translation units.
8.3 Namespace Alias
A namespace alias declares an alternate name for an existing namespace,
according to the following syntax:
namespace-alias-definition:
namespace identifier = qualified-namespace-specifier ;
qualified-namespace-specifier:
::opt nested-name-specifier opt namespace-name
The identifier in a namespace alias definition becomes a synonym for
the qualified namespace specifier. For example:
namespace Outer {
namespace A_Long_Inner_Name {
int x;
}
}
namespace N = Outer::A_Long_Inner_Name;
N::x = 0; // same as Outer::A_Long_Inner_Name::x = 0;
|
8.4 using Declaration
A
using
declaration introduces a name into a declarative region. That name is a
synonym for a name declared somewhere else. The name specified in a
using declaration in a class or namespace scope shall not already be a
member of that scope. The syntax of a using declaration is as follows:
using-declaration:
using ::opt nested-name-specifier unqualified-id ;
using :: unqualified-id ;
Using declarations can result in function overloading. For example:
namespace M {
void f(double);
}
namespace N {
void f(int);
}
void sub(void)
{
using M::f;
using N::f;
f('a'); // calls N::f(int)
f(1); // calls N::f(int)
f(1.2); // calls M::f(double)
}
|
A using declaration that declares a class member, must refer to a
member of a base class. Using declarations in classes are similar to
access declarations.
8.5 using Directive
A
using
directive specifies that the names in the nominated namespace can be
used in the scope where the directive appears, after the directive. A
using
directive cannot be used in class scope, but only in namespace scope or
block scope. Further, a
using
directive does not declare names in the scope where the directive
appears, it merely allows access to the names declared in the nominated
namespace.
Using directives are transitive, for example:
namespace M {
int i;
int j;
}
namespace N {
int i;
using namespace M;
}
void f()
{
using namespace N;
j = 0; // assigns 0 to M::j
i = 1; // ambiguous, both M::i and N::i are visible
}
|
If a namespace is extended after a
using
directive for that namespace, the additional members can be used after
the extension namespace definition.
8.5.1 Unqualified Name Lookup With using Directives
For unqualified name lookup, names appear in the nearest scope that
contains both the using directive and the namespace definition. For
example:
namespace N {
int n = 1;
}
namespace A {
int n = 2;
namespace B {
using namespace N;
void f() { cout << n; }
}
}
...
A::B::f(); // prints out the value 2 from A::n
|
This example shows that a using directive does not insert the
declarations from a namespace into the region where the using directive
apprears. The name lookup would look in the following scopes, in the
following order:
Namespace
B
Namespace
A
File scope, including
namespace N
Because name
n
is not locally declared in
B
, a unqualified name lookup must proceed upward through various scopes.
The
using namespace N
directive signifies that looking in namespace
N
to resolve names is permitted. However, the definition of
namespace N
is at file scope, so any names from
N
are not available until the lookup has walked through scope all the way
to file scope. Thus, in this example, the name from
namespace A
is found and used.
8.5.2 Qualified Name Lookup with using Directives
Given a qualified name,
X::m
, the compiler creates a set of all declarations of
m
in
namespace X
, and in all the namespaces nominated by using directives in
X
. Recall that
using
directives are transitive. Also, if any namespace directly contains a
declaration of
m
, then any
using
directives in that namespace are not followed. The following is an
example:
int x;
namespace Y {
void f(float);
void h(int);
}
namespace Z {
void h(double);
}
namespace A {
using namespace Y;
void f(int);
void g(int);
int i;
}
namespace B {
using namespace Z;
void f(char);
int i;
}
namespace AB {
using namespace A;
using namespace B;
void g();
}
void h()
{
AB::g(); // g is declared directly in AB,
// therefore S is { AB::g() } and AB::g() is chosen
AB::f(1); // f is not declared directly in AB so the rules are
// applied recursively to A and B;
// namespace Y is not searched and Y::f(float)
// is not considered;
// S is { A::f(int), B::f(char) } and overload
// resolution chooses A::f(int)
AB::f('c'); // as above but resolution chooses B::f(char)
AB::f(1.0f); // no best match between A::f(int) and B::f(char)
AB::x++; // x is not declared directly in AB, and
// is not declared in A or B, so the rules are
// applied recursively to Y and Z,
// S is { } so no x is found
AB::i++; // i is not declared directly in AB so the rules are
// applied recursively to A and B,
// S is { A::i, B::i } so the use is ambiguous
// and the program is ill-formed
AB::h(16.8); // h is not declared directly in AB and
// not declared directly in A or B so the rules are
// applied recursively to Y and Z,
// S is { Y::h(int), Z::h(double) } and overload
// resolution chooses Z::h(double)
}
|
8.6 Restrictions
This section describes restrictions to namespace support in C++.
8.6.1 Restrictions in the Current Implementation
- C++ Version ersion 5.6 does not allow a forward declaration of a
class in a namespace followed by the definition of the class outside of
the namespace. For example:
namespace N {
class C;
}
...
class N::C { ... };
|
If a forward class declaration is needed, the workaround is to
define the class in a namespace extension:
namespace N {
class C;
}
...
namespace N {
class C { ... };
}
|
- When a using declaration brings a name from a base class into a
derived class, a member function in the derived class should override
the function (with the same name and parameters) from the base class.
This currently does not work correctly.
- Version 5.6 does not support automatic instantiation of templates
that are defined within a namespace. Manual instantiation is supported
for these templates.
- Version 5.6 does not support the dependent name lookup rules for
templates defined inside namespaces. An example of this is:
namespace A {
int f(char) {return 1;}
template <class T> int g(T) {return f(0);}
}
int i = A::g(12.34);
int f(int) {return 2;}
|
The correct value for
i
is 2. When
A::g
is called, it should see
f
as an overloaded function, for all versions of
f
visible at the scope where
A::g
is defined, and the scope where
A::g
is being instantiated, that is: the file scope. Version 5.6 currently
uses the versions of
f
visible from the scope where
A::g
is defined, namely the scope of namespace
A
.
- C++ Version ersion 5.6 does not provide debugging support for
namespaces.
9 Additional Template Instantiation Options with Version 5.5
In addition to link-time automatic instantiation (the default) and
compile-time instantiation using the
/template_define
command line qualifier, C++ Version ersion 5.5 provides two additional
compile-time instantiation options for the
/template_define
command line qualifier, as follows:
local
|
Instantiate only the template entities that are used in this
compilation, and force those entities to be local to this compilation.
|
used
|
Instantiate only the template entities that are used in this
compilation. The template entities are instantiated with external
linkage.
|
Similarities and differences between the three compile-time
instantiation options are as follows:
- With all three options, if a module contains a call to a function
template (or takes its address), an instance of the template is
generated.
- The options differ when a class template is used within a module.
With the
/template_define=all
option, all member functions within a class template are instantiated,
whether or not they are used. With the
used
and
local
options, only the member functions that are actually used in the module
are instantiated.
- The options differ with regard to the linkage chosen for the
instantiated functions and static data members.
With the
/template_define=all
and
/template_define=used
options, functions and static data members are instantiated with
external linkage. This can lead to multiply defined symbol errors at
link time, if the same template entities are instantiated in different
modules. Thus, these options generally should not be specified for all
modules in an application.
With the
/template_define=local
option, functions and static data members are instantiated with
internal linkage and are thus local to the module that generates the
instantiation. This avoids the problem of multiply defined symbol
errors that can occur at link time when you specify either the
all
or
used
option for more than one module in an application.
- With all three options, static members of a requested class
template are instantiated, whether or not they are used.
When you
specify the
local
option, each module contains an instance of any static data members
instantiated from a requested class template. If the initializers for
such static data members cause side-effects at runtime, note that the
side-effects will occur for each instantiation in each module.
- With all three instantiation options, instantiations for requested
template entities are generated at compile time when the template is
used. This implies that the module requesting the template entity must
contain the corresponding template definition for that particular
template and any dependencies that the template definition contains,
prior to the template's point of use. If the template definition is not
present within the compilation prior to the instantiation request, C++
will be unable to materialize the requested template entity.
Determining When to Use the Compile-time Instantiation
Options
The compile-time instantiation options are primarily useful for
reducing the time required to build an application.
One approach to reduce build times, would be to identify within your
application the one module that contains the most uses of template
entities. Once identified, this module can be compiled with either the
all
or
used
option and the remaining modules compiled with automatic instantiation.
This approach avoids the problem of multiply defined symbols at link
time that can occur when using these options; this approach also offers
the convenience of automatic instantiation.
You can also use the
local
option to improve build times, provided that any redundant initializers
for static data members do not have unwanted side effects. You can
specify the
local
option for all modules in your application, something you cannot do
with the
all
and
used
options. With the
local
option, instantiations are local to each module. These local
instantiations are not shared across the various modules within an
application. For some applications, multiple copies of the same
instance can greatly increase the size of executables.
10 Explicit Instantiation
The new ANSI syntax for explicit instantiation has been implemented in
the C++ compiler. The syntax for this (as of the January 26th, ANSI C++
working paper) is as follows:
Currently, C++ accepts only template function declarations and template
class declarations. C++ does not yet support explicitly instantiating
template member functions or template static data members.
Note that because explicit specification of function template arguments
is not yet implemented, a template argument list may not be specified
in an explicit instantiation.
Examples of use:
template <class T> class X { public:
// stuff;
};
template <class T> void f(const T &t) { printf("f(const T&) called\n"); }
template class X<int>; // instantiate template class X with T=int
template void f(int &); // instantiate template function f with T=int
template void f<int>(int &); // not yet implemented
|
The ANSI syntax is unambiguous regarding template functions. Only the
template function that matches the declaration in the explicit
instantiation will be instantiated. The C++
#pragma define_template
directive is ambiguous, and instantiates all the template functions
that have the same number of template parameters as specified in the
pragma.
To explicitly instantiate templates, Compaq now recommends that you use
the new ANSI syntax instead of the
#pragma define_template
directive because the new syntax is more portable, as other compiler
vendors implement the ANSI standard.
Note that the ANSI syntax for explicit instantiation uses a semicolon
at the end of the declaration, while the syntax for the
#pragma define_template
directive does not. Omitting the semicolon can lead to obtuse error
messages, because the code that follows may look like part of the
declaration in the explicit instantiation.
Explicit instantiation currently has the same restrictions on code
ordering as does the
#pragma define_template
directive. The explicit instantiation must appear in the code after the
definitions of a class and its member functions or after the definition
of the template function.
11 Release Notes for the C++ Class Library
This section describes the problems fixed, known problems, and
restrictions for the C++ Class Library. See Section 13 for
information on the C++ Standard Library. Please note that String
Package, which is part of the C++ Class Library, is entirely
different from the String class that is part of the newly-implemented
C++ Standard Library and known as the String Library.
Do not confuse these two contrasting implementations.
11.1 Restrictions
- Conflict with redefinition of
clear()
If your program includes both <curses.h> and
<iostream.hxx>, C++ may fail to compile your program because
clear()
is defined by both header files. In <curses.h>,
clear()
is defined as a macro whereas in <iostream.hxx>
clear()
is defined as a member function.
Workarounds:
If your program
does not use either
clear()
or uses the <curses.h>
clear()
, include the <iostream.hxx> header first, followed by
<curses.h>.
If your program uses the
ios::clear()
function, undefine the
clear()
macro directly after the
#include <curses.h>
statement.
- The iostream Package supports the use of stream files and
fixed-length record files. Support for variable-length record files is
limited to reading an existing file sequentially and writing to a new
file sequentially.
- As of OpenVMS VAX Version 7.0, there is a new String class
operator+= function with an argument list of
(const char *)
.
- As of OpenVMS Version 7.0, there are new String class operator+
functions with argument lists of
(const char*, const String&)
and
(const String&, const char*)
.
- Within the String class, two versions of the
operator[]
member function have been added.
- Within the
ios
class, the following member functions are now declared
const
:
bad() eof() fail() fill()
flags() good() precision() rdstate()
*tie() width()
|
- For OpenVMS Version 7.0 and later, within the
String
class, the following member functions are now declared
const
:
index() lower() match() operator()
upper()
|
The non
const
versions of these routines are retained for compatibility.
- For OpenVMS Version 7.0 and later, within the
complex
class, the following operator routines now return a reference to the
complex object:
/=
*=
+=
--=
Previously, these routines had no return value.
12 Thread Safety for the C++ Class Library
The Class Library is now threadsafe on OpenVMS Version 7.0 systems: the
predefined stream objects and internal library data are protected
against simultaneous access from multiple threads. The Class Library
also provides a new Mutex class for use in synchronizing access to
user-defined objects. For more information about this support, see the
Compaq C++ Class Library Reference Manual.
To take advantage of this thread safety support, you need to compile
your application with the threadsafe header files and link and run your
application with the threadsafe run-time library.
- Threadsafe Header Files
Threadsafe versions of the Class
Library header files are supplied when you install this compiler on
OpenVMS Version 7.0 or later system. If you install this compiler on an
earlier version of OpenVMS, the installation provides older versions of
the header files that do not contain the threadsafe support.
- Threadsafe Run-Time Library
The threadsafe version of the Class
Library run-time library is supplied with OpenVMS Version 7.0 and later
systems.
If your application is not compiled with the threadsafe header files,
your application will continue to work on OpenVMS Version 7.0 and later
systems. However your application will not be threadsafe.
13 Release Notes for the C++ Standard Library
This section describes the enhancements, problems fixed, known
problems, and restrictions for the C++ Standard Library. See
Section 11 for information on the C++ Class Library. Please note that
the current version of C++ implements the new standard string class,
known as the String Library. Do not confuse this with
the String Package, which is part of the C++ Class Library
implemented in earlier versions of C++.
13.1 Enhancements and Changes in Version 5.6
- Version 5.6 of the compiler includes a subset of the C++ Standard
Library. The set includes components supplied with 5.5, plus
the Complex Math library.
Note that portions of the ANSI C++
Standard Library have been implemented in C++ using source licensed
from and copyrighted by Rogue Wave Software, Inc. Information
pertaining to the C++ Standard Library has been edited and incorporated
into C++ documentation with permission of Rogue Wave Software, Inc. All
rights reserved.
Portions copyright 1994-1996 Rogue Wave Software,
Inc.
- The default allocator type parameter for the map and multimap
containers has changed to accurately reflect the ANSI draft standard.
In Version 5.5, the template parameters looked like:
template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator< pair<const Key, T> > >
class map {};
|
In Version 5.6, they appear as follows:
template <class Key, class T, class Compare =less<Key>,
class Allocator = allocator<T> >
class map {};
|
13.2 Differences between Version 5.5 and Version 5.6
- The function object "times" has been renamed to
"multiplies". This helps avoid conflict with the name
times
in sys/times.h.
- The ostream_iterator and istream_iterator classes have two
additional template arguments. Instead of ostream_iterator<T>
they are now also templatized on character type and traits type; that
is, they are now declared as:
class ostream_iterator<T, charT, traits>;
class istream_iterator<T, charT, traits, Distance>;
|
- The <stl_macros> file no longer contains workarounds for
missing compiler features. They are now in <stdcomp> and have
different names.
- The select1st function object, which used to be in the header file
<functional>, has been moved to <map>. This was never in
the ANSI draft standard, and is meant to be used only in the
implementation of the map container.
- The basic_string class now is implemented using copy-on-write
reference semantics. This should make the class much more efficient.
- The buffer used by rb_tree (and hence by map and set) to store
container elements has been reduced from 4028 to 1024 bytes.
- The allocator now allocates raw bytes of storage rather than typed
storage. The allocator uses an allocator_interface class to provide its
"typed" implementation. This change is to work around the
lack of support for member templates. For details, see the section on
allocators in Using Compaq C++ for OpenVMS Systems.
- Strings now have support for wide characters.
13.3 Problems Fixed in Version 5.6
- Prior to C++ V5.6, the following overloaded function templates
found in <iterator> and <algorithm> made use of the
SL_INLINE_FCTS macro to force their code to be inlined.
__advance
__equal_range
__distance
__lower_bound
__reverse
__rotate
__unique_copy
__upper_bound
|
This worked around the lack of compiler support for manually
instantiating overloaded function templates. Inlining was the only way
to manually instantiate overloaded function templates. For example, the
following would not work:
class C {
public:
C operator++(int) { return *this; }
};
class D {
};
class D_tag {};
class C_tag {};
template <class T>
void __distance(T iter, D_tag) {}
template <class T>
void __distance(T iter, C_tag) {iter++;}
//Generates an error because the compiler instantiates all
//occurrences of __distance and operator++ is not supported
//for class D.
#pragma define_template __distance<D>
int main() {
__distance(D(),D_tag());
return 0;
}
|
The current compiler supports explicit instantiation, which can be
used to manually instantiate overloaded function templates. Therefore
SL_INLINE_FCTS is obsolete and has been removed from <iterator>
and <algorithm>. If you want to use one of the function templates
in <iterator> and <algorithm>, you must change your sources
to use explicit instantiation directly. The following example
illustrates use of the new explicit instantiation syntax:
class C {
public:
C operator++(int) { return *this; }
};
class D {
};
class D_tag {};
class C_tag {};
template <class T>
void __distance(T iter, D_tag) {}
template <class T>
void __distance(T iter, C_tag) {iter++;}
//Use explicit instantiation syntax to force instantiation of
//void __distance(D,D_tag) when using manual instantiation.
template void __distance(D, D_tag);
int main() {
__distance(D(),D_tag());
return 0;
}
|
13.4 Enhancements and Changes in 5.5
Version 5.5 of the compiler included a subset of the C++ Standard
Library. The set included:
The Standard Template Library (STL)
The String library
The Numeric Limits class
The auto_ptr class
The Standard exception classes
13.5 Problems Fixed in 5.5
- When compiled with the
/DEBUG
command line qualfier, many programs that used the STL classes: set,
multiset, map, and multimap caused C++ Version 5.4 fail with the error
%VCG-F-BUGCHECK
during code binding. These problems are now fixed. [3383]
- A memory leak has been found and fixed in the
map()
utility.
The memory leak was obvious if
map()
was used within a loop.
- The binary_compose and unary_compose functions are no longer in
the <functional> header. These functions were part of the
original Hewlett-Packard C++ Standard Library implementation but they
do not exist in the ANSI C++ draft.
- The Standard Library no longer uses the
new
operator during initialization.
13.6 Problems Fixed in Version 5.4
- The C++ Standard Library is now threadsafe on all versions of the
operating system. No /DEFINE flag is necessary.
Note
If you used the threadsafe STL with Version 5.3, you must recompile
your modules that use the STL before linking with the new STL run-time
provided with Version 5.4 or later. Otherwise you may encounter link
errors or unpredictable run-time results.
|
- The
allocate()
functions in
<memory>
use the current
new_handler
flag; they no longer clear the
new_handler
flag by calling
set_new_handler(0)
.
- When you instantiate an STL container with a user-defined type and
operate on your container using an algorithm from the
<algorithm>
header, you will no longer receive compilation errors in
<algorithm>
stating that
T
is a struct type but is supposed to be scalar.
- Manual Instantiation of Overloaded Function Templates
Prior to
Version 5.4, the only way to manually instantiate a template function
was to use the
#pragma define_template
directive. However, this directive does not allow you to specify which
of a set of overloaded functions to instantiate. This can cause
problems, for example, if you try to manually instantiate a
map
object and compile the following code without automatic instantiation:
#include <map>
#pragma define_template map<int, int, less<int> >
#pragma define_template rb_tree<int, pair<const int, int>,
select1st<pair<const int, int>, int>, less<int> >
int main(void)
{
map<int, int, less<int> > m;
return 0;
}
|
Without automatic instantiation, the compiler generates undefined
symbols for the
__distance
function.
The
__distance
function is overloaded, so you cannot add a
#pragma define_template
directive for it because the compiler tries to instantiate all of the
__distance
functions and reports compilation errors. This problem occurs for the
following template functions in the STL:
__advance
__equal_range
__distance
__lower_bound
__reverse
__rotate
__unique_copy
__upper_bound
|
This problem can now be solved using the explicit instantiation
syntax described in Section 10. The example code from above now
looks like the following:
#include <map>
#pragma define_template map<int, int, less<int> >
#pragma define_template rb_tree<int, pair<const int, int>,
select1st<pair<const int, int>, int>, less<int>,
allocator<int> >
template void __distance(
rb_tree<int, pair<const int, int>, select1st<pair<const int, int>,int>,
less<int>, allocator<int> >::iterator,
rb_tree<int, pair<const int, int>, select1st<pair<const int, int>,int>,
less<int>, allocator<int> >::iterator,
unsigned int&, bidirectional_iterator_tag);
template void __distance(
rb_tree<int, pair<const int, int>, select1st<pair<const int, int>,int>,
less<int>, allocator<int> >::const_iterator,
rb_tree<int, pair<const int, int>, select1st<pair<const int, int>,int>,
less<int>, allocator<int> >::const_iterator,
unsigned int&, bidirectional_iterator_tag);
int main(void)
{
map<int, int, less<int> > m;
return 0;
}
|
- Specialization of
destroy
Functions
You no longer need to define specializations for the
destroy
functions. For example, if your program builds a container of pointers
to a user-defined class,
my_xxx
, then you no longer need to provide the following two specializations
for
my_xxx
:
void destroy (my_xxx**) {}
void destroy (my_xxx**, my_xxx**) {}
|
- Template Function Matching on String Literals of Different Lengths
The latest ANSI C++ draft no longer considers the following code
valid:
template <class T>
inline const T& max(const T& a, const T& b) {
return 0;
}
int main ()
{
max ("Joe", "Smith"); // Joe and Smith are different lengths
return 0;
}
|
The Version 5.3 compiler did not accept this code and previously
Compaq had recommended a workaround, specifically to cast the arguments
as follows:
max((const char*) "Joe", (const char*) "Smith");
|
Now Compaq recommends that you remove such code from your program.
13.7 Known Problems
The following are known problems when using the current release of the
STL with the compiler. Where appropriate, workarounds are suggested.
- Ambiguity error with wide character append, assign, insert and
replace
Version 5.6 includes support for wide character strings. In
this release, wchar_t is not a built-in type supported by the compiler
but is a typedef defined in <wchar.h> as an
unsigned int
. The wchar_t typedef is therefore the same type as
size_t
defined in <stddef.h> to be an
unsigned int
. This causes an ambiguity error when calling one of the following
versions of the string member functions for append, assign, insert and
replace:
basic_string<charT, traits, Allocator>& append (const charT*, size_type);
basic_string<charT, traits, Allocator>& append (size_type, charT);
basic_string<charT, traits, Allocator>& assign (const charT*, size_type);
basic_string<charT, traits, Allocator>& assign (size_type, charT);
basic_string<charT, traits, Allocator>& insert (
size_type, const charT*, size_type);
basic_string<charT, traits, Allocator>& insert (
size_type,size_type,charT);
basic_string<charT, traits, Allocator>& replace (
size_type, size_type, const charT*, size_type);
basic_string<charT, traits, Allocator>& replace (
size_type, size_type, size_type, charT);
|
You only get an ambiguity error when instantiating one of these
functions with a wchar_t typedef and passing a zero for the input
parameter in each function that can be either a
const charT*
or a
size_type
. Thus, when instantiating on a wchar_t typedef, you need to call
append or assign with a zero as the first parameter, insert with a zero
as the second parameter, and replace with a zero as the third
parameter. The ambiguity arises from determining whether an input
parameter of type
const charT*
(that is:
const wchar_t*
) or type
size_type
(that is:
size_t
, that is:
unsigned int
) is the better match for zero. The following example shows calls to
the four string member functions that each cause an ambiguity error:
#include <string>
main() {
wstring ws;
size_t elem;
ws.append(0,elem);
ws.assign(0,elem);
ws.insert (5,0,elem);
ws.replace (5,5,0,elem);
}
|
The specific compilation message indicates an OVERLDAMBIG error and
OVERMATCHTRY informational.
Workaround these errors by casting the
zero parameter to a
size_t
as follows:
#include <string>
main() {
wstring ws;
size_t elem;
ws.append((size_t)0,elem);
ws.assign((size_t)0,elem);
ws.insert (5,(size_t)0,elem);
ws.replace (5,5,(size_t)0,elem);
}
|
The workaround will be unnecessary in Version 6.0 where wchar_t is
a built-in type.
- When creating very complicated instantiations (for example, a map
of a map of string), you may get a link error when using automatic
instantiation (the name of the undefined symbol will be longer than
1022 chars).
To workaround this, you can use manual instantiation
or local instantiation (see Section 10).
- The mem_fun classes are now implemented in <functional>.
Unfortunately they will not work with any member functions that return
void (Most of the member functions that are currently in the containers
return void). The ANSI standards committee will decide how best to fix
this at a future meeting; the committee will either relax the language
rules for use of void types in templates or mandate that all these
classes have partial specializations for the return type void.
The
same applies to the adaptors for pointers to the functions
pointer_to_unary_function and pointer_to_binary_function.
- Although the following basic_string::compare function should throw
out_of_range
if the input argument pos1 is greater than str.size(), it does
not:
int compare(size_type pos1, size_type n1,
const basic_string<charT, traits, Allocator>& str) const;
|
For example, the following does not throw
out_of_range
but should:
string s1("long");
string s2;
s1.compare(5, 4, s2);
|
- Although the following basic_string constructor should throw
out_of_range
if n == npos, it does not:
basic_string(const charT *s, size_type n,
const Allocator& a = Allocator());
|
For example, the following does not throw
out_of_range
but should:
string s1("a",string::npos)
|
- The following basic_string::compare function does not return a
correct result if the input argument n1 is npos:
int compare(size_type pos, size_type n1,
charT *s, size_type n2 = npos) const;
|
For example, the following does not return 0 but should:
string a("abcd");
// this comparison doesn't work.
if (a.compare(0, string::npos, "abcd",4)==0)
cout << "comparison worked" << endl;
|
- The following is the string typedef defined in <string>:
typedef basic_string<char, char_traits<char>, allocator<void> > string;
|
Compare this with the following string typedef, as defined by the
24 September 1996 draft:
typedef basic_string<char, char_traits<char>, allocator<char> > string;
|
The difference provides bug fixes and will be corrected in a future
release of the compiler. Be aware that this deviation from the draft
standard may effect how you would declare a common instantiation for
string and how you would use the string allocator_type typedef.
- The C++ V5.6 allocator class does not conform to the 24 September
1996 draft standard. For details, see the Allocator Class section in
Using Compaq C++ for OpenVMS Systems.
- The allocate member function of the allocator class allocates
memory for n objects of type T but does not construct them.
Until the compiler supports member function template arguments, the
allocate member function will return a void* rather than a T* as
specified by the ANSI C++ Working Paper. To workaround this problem you
need to make use of the allocator_interface class. For example, if you
declare the following:
The following will give an error message:
allocator<X>::pointer p = a.allocate (5);
........................1
%CXX-E-PTRMISMATCH, (1) In the initializer for p, the referenced
type of the pointer value "a.allocate(5)" is "void", which is not
compatible with "X".
|
Workaround this by using the allocator_interface class as follows:
typedef allocator<X> allocator_type;
typedef allocator_interface<allocator_type,X> value_alloc_type;
allocator_type a;
allocator_type::pointer p = value_alloc_type(a).allocate(5,0);
|
- The pow() function defined in <complex> may give incorrect
results. For example, the following should return 0 but does not:
#include <iostream.h>
#include <complex>
main() {
complex<double> c1(-1,0);
complex<double> c3 = pow(c1,-1);
double d = c3.imag();
cout << "d: " << d << endl;
}
|
- The complex operator<< does not respect precision or ios
flags.
- Problems with the
/standard=cfront
and
/standard=ms
command line options.
To preserve existing semantics with cfront or
MSVC++, DIGITAL loosened access protection in many places in the
Standard Library. If you are compiling with either of these options,
consult the ANSI C++ draft to make sure you are not accessing member
data or member functions to which you should not have access.
- Problem with automatic instantiation and template function
matching a string literal to a template argument that expects a
const T &
.
Consider the following code, which generates the following link
error:
%LINK-W-NUDFSYMS, 1 undefined symbol:
%LINK-I-UDFSYM, FOO__XNKA3_C
%LINK-W-USEUNDEF, undefined symbol FOO__XNKA3_C referenced
in psect $LINK$ offset %X00000020
in module BUG file WORK$:[ACCT.STL.MYTEST]BUG.OBJ;1
|
//b.h
template <class T>
void foo(const T& value) {}
//main.cxx
#include "b.h"
int main ()
{
foo("ff");
return 0;
}
|
You may encounter this error when using the following STL
algorithms:
binary_search() count() fill() fill_n()
find() find_if() lower_bound() max()
min() remove() remove_copy() replace()
replace_copy() replace_copy_if() replace_if() upper_bound()
|
Workaround: Cast
ff
to a
const char *
. In the previous example, change the call to
foo
to the following:
- Problem inserting pairs into maps and multimaps.
Calling the
pair constructor or using the
make_pair()
function will not return a pair that can be inserted into a map or
multimap. This is because the template instantiation will not infer a
const
Key type.
Workaround: Instead of using these
functions, create a pair using the
value_type
typedefs. For example, in place of the following code:
map<int,double> mymap;
mymap.insert(make_pair(10,20));
|
Substitute the following code:
map<int,double> mymap;
map<int,double>::value_type mvt(10,20);
mymap.insert(mvt);
|
13.8 Restrictions
This section describes problems of interest to Standard Library users
that Compaq has no current plans to fix. Where feasible, a way to work
around the problem is suggested.
- If you compile a program that performs many complicated template
instantiations you may receive the following message:
Fatal: Insufficient virtual memory to continue compilation.
%LIB-F-INSVIRMEM, insufficient virtual memory
|
To work around this problem ,try the following:
- Raising your paging file quota
To see your current paging file
quota enter:
- Separating the instantiations into different files that can be
compiled independently. This may reduce the amount of paging file quota
required by each compilation unit.
- C++ ships the following non-Standard headers which are for
internal use only. Their contents are subject to change and can not be
relied on.
<stdcomp>
<stl_macros>
<stddefs>
<compnent>
<stdmutex>
<stdexcept>
|
- Because of a compiler bug, taking the address of a
static const
data member may produce either a link-time or run-time error. The
effect of this bug on the numeric_limits class follows. A link-time
error occurs if you take the address of a numeric_limits
static const
data member for which a specialization is not provided. For example,
consider the following program:
#include <limits>
#include <iostream.h>
main() {
numeric_limits<int*> NL;
const int* ip = &NL.digits10;
cout << *ip << endl;
}
|
When compiled, this code generates an unresolved symbol link error
for
numeric_limits<int*>::digits10
.
If you take the address of a
static const
numeric_limits data member for which a specialization is provided,
dereferencing the address yields invalid run-time results. For example,
consider the following program:
#include <limits>
#include <iostream.h>
main() {
numeric_limits<int> NL;
const int* ip = &NL.digits10;
cout << *ip << endl;
}
|
When executed, a program containing this code should print the
number nine, instead it prints a zero. [1680]
- Defining non-local static objects
If you define a non-local
static object of type map, multimap, set, or multiset, or if you define
a non-local static object that constructs one of those types, you must
modify your
cxxlink
step as follows:
- Create an options file,
image_name.opt
, whose content is:
SYS$SHARE:LIBCXXSTD/INCLUDE=CXXL_STD_INIT
|
- Modify your
cxxlink
command to be:
CXXLINK image_name.opt/opt,[rest of command]
|
If you fail to do this, running your application may result in an
access violation during image activation. The reason for this is that
map, multimap, set, and multiset objects may make use of data that is
constructed when the Class library is initialized. The Class library is
not initialized before objects at file scope. The previous
cxxlink
command actions, force the library initialization for map, multimap,
set and multiset objects to occur before their construction requires it.
- Auto-instantiation does not work correctly when declarations of
types that are used to instantiate a particular template are defined in
the source file.
To avoid this problem, use pragmas or explicit
instantiation (see Section 10) to force manual instantiation (see
Chapter 5 of Using Compaq C++ for OpenVMS Systems), or move the type declarations into a
template declaration file.
- Within an application, any modules that instantiate STL containers
or algorithms with floating point data types must be compiled using the
same floating point format.
You must compile using the same
floating point format because the compiler does not include the
floating point format in the external name encoding scheme. For
example, if you were to compile two modules using different floating
point formats as follows:
// module1.cxx
void foo(double arg) {...};
// module2.cxx
void foo(double arg) {...};
$ cxx module1/float=d_float
$ cxx module2/float=g_float
|
The resulting object modules would contain the same external symbol
name for the
foo
function.
14 About This Product
Compaq Computer Corporation makes no representations that the use of
its products in the manner described in this publication will not
infringe on existing or future patent rights, nor do the descriptions
contained in this publication imply the granting of licenses to make,
use, or sell equipment or software in accordance with the description.
Possession, use, or copying of the software described in this
publication is authorized only pursuant to a valid written license from
Compaq or an authorized sublicensor.
privacy and legal statement