[an error occurred while processing this directive]

HP OpenVMS Systems

C++ Programming Language
Content starts here

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.

Contents

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:
    1. Raising your paging file quota: to see your current paging file quota, enter show process/quota on the command line.
    2. 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:
    1. 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
      
    2. 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
      
    3. 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:
    1. 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.
    2. Compile all modules with /extern_model:strict_refdef .
    3. 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

  1. 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
    
  2. Create a list of global names from the object library by executing the following command:


    $ LIBRARY/LIST=sw_shr_alpha.opt/NAMES sw.olb
    
  3. Process the SW_SHR_ALPHA.OPT file as follows:
    1. 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)
      
    2. 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 .
  4. 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
    
  5. 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.
  6. 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:

  1. Copy the OpenVMS Alpha linker options file to create a macro source file as follows:


    $ COPY SW_SHR_ALPHA.OPT SW_VEC_VAX.MAR
    
  2. Remove all non SYMBOL_VECTOR lines from the file.
  3. 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
  4. See the comments below on adding $FUTURE to reserve space in the symbol vector.
  5. Continue with the steps below on compiling, linking and testing the shareable image.

5.2.3 OpenVMS VAX

  1. 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.
  2. Create a list of global names from the object library by executing the following command:


    $ LIBRARY/LIST=sw_vec_vax.mar/NAMES sw.olb
    
  3. Process the SW_VEC_VAX.MAR file as follows:
    1. 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
      
    2. 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.
    3. 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.
  4. Compile the macro source:


    $ LIBRARY/CREATE/MACRO SW_DEFS.MLB SW_DEFS.MAR
    $ MACRO SW_VEC_VAX+SW_DEFS/LIB
    
  5. Test link as follows:


    $ LINK /SHARE/EXE=SW_SHR.EXE -
            SW.OBJ,SW_VEC_VAX.OBJ, -
            SW_SHR_VAX.OPT/OPT
    
  6. Process any link errors and review the above steps if necessary.
  7. 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:

  1. Link and test the verification test program against a pre-modified shareable image.
  2. Make modifications to the shareable image code base (including adding any new entry points).
  3. 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:


template declaration

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:


      allocator<X> a;
    

    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:


    foo((const char*) "ff");
    
  • 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:


      show process/quota
      
    • 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:
    1. Create an options file, image_name.opt , whose content is:


      SYS$SHARE:LIBCXXSTD/INCLUDE=CXXL_STD_INIT
      
      
    2. 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.

Contents