 
















                     Compaq_C++____________________________________
                     Using Compaq C++ for Tru64 UNIX and Linux
                     Alpha

                     Order Number: AA-PX2BL-TE


                     February 2002

                     This manual contains information about developing
                     Compaq C++ programs on Compaq Tru64 UNIX and Linux
                     Alpha systems.






                     Revision/Update Information: This is a revised
                                                  manual, replacing
                                                  AA-PX2BK-TE

                     Software Version:            Compaq C++ Version
                                                  6.5 for Tru64 UNIX
                                                  Compaq C++ Version
                                                  6.5 for Linux Alpha





                     Compaq Computer Corporation
                     Houston, Texas

 






           __________________________________________________________
           First Printing, March 1993
           Tenth Revision, February 2002

            2001 Compaq Computer Corporation.

           COMPAQ, the Compaq logo, and Alpha, DEC, Ladebug, OpenVMS,
           and VMS are registered in the U.S. Patent and Trademark
           Office. Tru64 is a trademark of Compaq Information
           Technologies Group, L.P. in the United States and other
           countries. UNIX is a trademark of The Open Group in the
           United States and other countries. All other product names
           mentioned herein may be trademarks of their respective
           companies.

           Portions of the ANSI C++ Standard Library have been
           implemented using source licensed from and copyrighted
           by Rogue Wave Software, Inc.

           Information pertaining to the C++ Standard Library has
           been edited and reprinted with permission of Rogue Wave
           Software, Inc. All rights reserved.

           Portions copyright 1994-2001 Rogue Wave Software, Inc.

           Compaq shall not be liable for technical or editorial
           errors or omissions contained herein. The information
           in this document is provided as is without warranty
           of any kind and is subject to change without notice.
           The warranties for Compaq products are set forth in
           the express limited warranty statements accompanying
           such products. Nothing herein should be construed as
           constituting an additional warranty.

           Confidential computer software. Valid license from Compaq
           required for possession, use or copying. Consistent with
           FAR 12.211 and 12.212, Commercial Computer Software,
           Computer Software Documentation, and Technical Data for
           Commercial Items are licensed to the U.S. Government under
           vendor's standard commercial license.

           This document is available on CD-ROM.

                                                               ZK6388

           This document was prepared using DECdocument, Version
           3.3-1n.

 













   ________________________________________________________________

                                                           Contents


   Preface..................................................     xi


   1  Building and Running C++ Programs

         1.1   Compiling a Program..........................    1-1
         1.2   Linking a Program............................    1-2
         1.3   Name Demangling..............................    1-2
         1.4   C++ Standard Library.........................    1-4
         1.5   C++ Class Library............................    1-4
         1.6   Debugging....................................    1-5
         1.7   Improving Build Performance..................    1-5
         1.7.1     Object File Compression [Tru64]..........    1-6
         1.7.2     Using Shared Libraries...................    1-6
         1.7.3     Using Precompiled Headers................    1-6
         1.7.4     Performance Optimization Options.........    1-6
         1.8   Deploying Your Application [Tru64]...........    1-6
         1.8.1     Redistributing the C++ Run-Time
                   Library..................................    1-8
         1.8.2     Instructions for Installing
                   Redistribution Kit.......................    1-9
         1.9   Using OpenMP.................................    1-9

   2  Compaq C++ Implementation

         2.1   Implementation-Specific Attributes...........    2-1
         2.1.1     #pragma Preprocessor Directive...........    2-1
         2.1.1.1     #pragma define_template Directive......    2-2
         2.1.1.2     #pragma instantiate Directive..........    2-2
         2.1.1.3     #pragma environment Directive..........    2-3
         2.1.1.4     #pragma extern_prefix Directive........    2-5
         2.1.1.5     #pragma ident Directive................    2-5
         2.1.1.6     #pragma [no]inline Directive...........    2-6

                                                                iii

 






           2.1.1.7     #pragma intrinsic Directive............    2-6
           2.1.1.8     #pragma [no]member_alignment
                       Directive..............................    2-7
           2.1.1.9     #pragma message Directive .............    2-9
           2.1.1.10    #pragma module Directive...............   2-10
           2.1.1.11    #pragma once Directive.................   2-11
           2.1.1.12    #pragma pack Directive.................   2-11
           2.1.1.13    #pragma pointer_size Directive
                       [Tru64]................................   2-13
           2.1.1.14    #pragma required_pointer_size Directive
                       [Tru64]................................   2-15
           2.1.1.15    #pragma required_vptr_size Directive
                       [Tru64]................................   2-15
           2.1.1.16    #pragma [no]standard Directive.........   2-16
           2.1.1.17    #pragma weak Directive.................   2-16
           2.1.2     Protecting System Header Files...........   2-16
           2.1.2.1     Using the Compiler's Header File
                       Protection Option......................   2-17
           2.1.2.2     Modifying Each Header File.............   2-17
           2.1.3     Predefined Macro Names...................   2-18
           2.1.4     Translation Limits.......................   2-24
           2.1.5     Numerical Limits.........................   2-24
           2.1.6     Argument-Passing and Return Mechanisms...   2-25
           2.2   Implementation Extensions and Features.......   2-25
           2.2.1     Identifiers..............................   2-26
           2.2.1.1     Character Limit for Long Names.........   2-26
           2.2.2     Order of Static Object Initialization....   2-26
           2.2.3     Integral Conversions.....................   2-26
           2.2.4     Floating-Point Conversions...............   2-26
           2.2.5     Explicit Type Conversion.................   2-27
           2.2.6     The sizeof Operator......................   2-27
           2.2.7     Explicit Type Conversion.................   2-27
           2.2.8     Multiplicative Operators.................   2-28
           2.2.9     Additive Operators.......................   2-28
           2.2.10    Shift Operators..........................   2-28
           2.2.11    Equality Operators.......................   2-29
           2.2.12    volatile Type Specifier..................   2-29
           2.2.13    __unaligned Type Specifier ..............   2-31
           2.2.14    Linkage Specifications...................   2-32
           2.2.15    Temporary Objects........................   2-32
           2.2.15.1    Nonconstant Reference Initialization
                       with a Temporary Object................   2-33
           2.2.16    Exception Handling.......................   2-33


     iv

 






              2.2.17    File Inclusion...........................   2-34
              2.2.18    Inheritance and Header Files.............   2-35
              2.2.19    Nested Enums and Overloading.............   2-36
              2.2.20    Guiding Declarations.....................   2-38
              2.3   Run-time Type Identification.................   2-39
              2.4   Implementation of Polymorphism During Object
                    Construction.................................   2-39
              2.5   Message Control Options......................   2-41
              2.6   Message Information Options..................   2-42


        3  Compaq C++ Language Environment

              3.1   Using Existing C Header Files................    3-1
              3.1.1     Providing C and C++ Linkage..............    3-1
              3.1.2     Resolving C++ Keyword Conflicts..........    3-2
              3.2   Using Compaq C++ with Other Languages........    3-2
              3.3   Linkage to Non-C++ Code and Data.............    3-4
              3.4   How to Organize Your C++ Code................    3-4
              3.4.1     Code That Does Not Use Templates.........    3-4
              3.4.2     Code That Uses Templates.................    3-6
              3.4.3     Creating Libraries.......................    3-8
              3.5   Using 32-bit Pointers (xtaso)................    3-9
              3.6   Hints for Designing Upwardly Compatible C++
                    Classes......................................   3-13
              3.6.1     Source Compatibility.....................   3-14
              3.6.2     Link Compatibility.......................   3-15
              3.6.3     Run Compatibility........................   3-16
              3.6.4     Additional Reading.......................   3-16

        4  Porting to Compaq C++

              4.1   Compatibility with Other C++ Compilers.......    4-1
              4.2   Compatibility With Version 5.n Compilers
                    [Tru64]......................................    4-4
              4.2.1     Compiler Version Options [Tru64].........    4-4
              4.2.2     Language Differences [Tru64].............    4-5
              4.2.3     Implementation Differences [Tru64].......    4-7
              4.2.4     Library Differences [Tru64]..............    4-8
              4.3   Using Classes................................    4-8
              4.3.1     Friend Declarations......................    4-9
              4.3.2     Member Access............................    4-9
              4.3.3     Base Class Initializers..................    4-9


                                                                       v

 






           4.4   Undefined Global Symbols for Static Data
                 Members......................................   4-10
           4.5   Functions and Function Declaration
                 Considerations...............................   4-10
           4.6   Using Pointers...............................   4-11
           4.6.1     Pointer Conversions......................   4-11
           4.6.2     Bound Pointers...........................   4-11
           4.6.3     Constants in Function Returns............   4-11
           4.6.4     Pointers to Constants....................   4-12
           4.7   Using typedefs...............................   4-12
           4.8   Initializing References......................   4-13
           4.9   Using the switch and goto Statements.........   4-13
           4.10  Using Volatile Objects.......................   4-14
           4.11  Preprocessing................................   4-14
           4.12  Managing Memory..............................   4-15
           4.13  Size-of-Array Argument to delete Operator....   4-15
           4.14  Flushing the Output Buffer...................   4-15
           4.15  Missing Parenthesis Error Message............   4-16
           4.16  Link Using cxx...............................   4-16
           4.17  Source File Extensions.......................   4-17
           4.18  Incrementing Enumerations....................   4-17
           4.19  Scope of Variables Declared on a for
                 Statement....................................   4-17
           4.20  Guidelines for Writing Clean 64-Bit Code.....   4-18


     5  Using Templates

           5.1   Overview.....................................    5-1
           5.2   Automatic Template Instantiation.............    5-2
           5.2.1     Specifying Alternate Repositories........    5-2
           5.2.2     Reducing Compilation Time with the
                     -ttimestamp Option.......................    5-3
           5.3   Implicit Inclusion...........................    5-4
           5.3.1     Compiling Programs with Automatic
                     Instantiation............................    5-5
           5.3.2     Linking Programs with Automatic
                     Instantiation............................    5-6
           5.4   Manual Template Instantiation................    5-8
           5.4.1     Instantiation Directives.................    5-9
           5.4.1.1     #pragma define_template................    5-9
           5.4.1.2     #pragma instantiate and #pragma
                       do_not_instantiate.....................   5-13
           5.5   Advanced Program Development and Templates...   5-15

     vi

 






              5.5.1     Dependency Management....................   5-15
              5.5.2     Mixing Automatic and Manual
                        Instantiation............................   5-15
              5.5.3     Creating Libraries.......................   5-16
              5.5.4     Creating A Common Instantiation
                        Library..................................   5-17
              5.5.5     Multiple Repositories....................   5-20
              5.6   Template Options.............................   5-21
              5.7   Compatibility with Earlier Versions of C++...   5-24
              5.7.1     Linking with Version 5.n
                        Instantiations...........................   5-25
              5.8   Linking Version 5.n Applications Against
                    Version 6.n Repositories.....................   5-26


        6  Precompiled Headers

              6.1   Automatic Precompiled Header Processing......    6-2
              6.2   Manual Precompiled Header Processing.........    6-6
              6.3   Other Ways for Users To Control Precompiled
                    Headers......................................    6-7
              6.4   Performance Issues...........................    6-7
              6.5   Command-Line Options for Precompiled
                    Headers......................................    6-8

        7  The C++ Standard Library

              7.1   Important Compatibility Information..........    7-3
              7.1.1     -[no]using_std Compiler Compatibility
                        Switch...................................    7-3
              7.1.2     Pre-ANSI/ANSI Iostreams Compatibility....    7-4
              7.1.3     Support for pre-ANSI and ANSI operator
                        new() ...................................    7-6
              7.1.4     Overriding operator new() ...............    7-8
              7.1.5     Support for Global array new and delete
                        Operators................................   7-10
              7.2   How to Build Programs Using the C++ Standard
                    Library......................................   7-11
              7.3   Optional Switch to Control Buffering.........   7-12
              7.4   Enhanced Compile-time Performance of ANSI
                    Iostreams....................................   7-13
              7.5   Upgrading from the Class Library to the
                    Version 6.n Standard Library.................   7-13


                                                                     vii

 






           7.5.1     Upgrading from the Class Library Vector
                     to the Standard Library Vector...........   7-13
           7.5.2     Upgrading from the Class Library Stack to
                     the Standard Library Stack...............   7-15
           7.5.3     Upgrading from the Class Library String
                     Package Code.............................   7-16
           7.5.4     Upgrading from the Class Library Complex
                     to the ANSI Complex Class................   7-18
           7.5.5     Upgrading from the Pre-ANSI iostream
                     library to the Standard Library..........   7-21


     8  Handling Exceptions

           8.1   Structure....................................    8-1
           8.2   Run-Time Considerations......................    8-3
           8.3   Coding Recommendations.......................    8-3
           8.4   Mixed-Language Applications..................    8-4
           8.5   Finding Information about Exceptions.........    8-4
           8.6   Using the dlclose Routine....................    8-4
           8.7   Catching Signals and C Exceptions............    8-5
           8.8   C++ Exceptions and Threads [Tru64]...........    8-6

     9  Using the Ladebug Debugger

           9.1   Debugging C++ Programs.......................    9-2
           9.2   Using Absolute and Relative Path Names.......    9-3
           9.3   Debugging Programs Containing C and C++
                 Code.........................................    9-4
           9.4   Setting the Class Scope......................    9-5
           9.5   Displaying Class Information.................    9-7
           9.6   Displaying Object Information................    9-8
           9.7   Displaying Virtual and Inherited Class
                 Information..................................   9-10
           9.8   Modifying Class and Object Data Members......   9-14
           9.9   Member Functions on the Stack Trace..........   9-15
           9.10  Resolving Ambiguous References to Overloaded
                 Functions....................................   9-15
           9.11  Setting Breakpoints in Member Functions......   9-19
           9.11.1    Setting Breakpoints in Overloaded
                     Functions................................   9-22
           9.11.2    Setting Breakpoints in Constructors and
                     Destructors..............................   9-26
           9.12  Calling Overloaded Functions.................   9-27

     viii

 






              9.13  Using Typecasts to Display Program
                    Expressions..................................   9-28
              9.14  Class Templates and Function Templates.......   9-31
              9.15  Debugging C++ Exception Handlers.............   9-36
              9.15.1    Setting Breakpoints in Exception
                        Handlers.................................   9-36
              9.15.2    Examining and Modifying Variables in
                        Exception Handlers.......................   9-38
              9.16  Advanced Program Information: Verbose Mode...   9-38
              9.17  Reducing Object File Size During Debugging...   9-43
              9.17.1    Using the -gall and -gall_pattern
                        Options..................................   9-44
              9.17.2    Hints for Using the -gall Option
                        Effectively..............................   9-46


        A  Class Library Restrictions

        B  Built-In Functions


        C  Third Degree Messages

        Index


        Examples

              9-1       Switching Between C++ and C Debugging
                        Modes....................................    9-5

              9-2       Setting the Class Scope..................    9-6

              9-3       Displaying Class Information.............    9-7

              9-4       Displaying Object Information............    9-9

              9-5       Printing Information on a Derived
                        Class....................................   9-10

              9-6       Resolving References to Objects of
                        Multiple Inherited Classes...............   9-13

              9-7       Resolving Overloaded Functions by
                        Selection Menu...........................   9-16

              9-8       Resolving Overloaded Functions by Type
                        Signature................................   9-18

                                                                      ix

 






           9-9       Setting Breakpoints in Member
                     Functions................................   9-20

           9-10      Setting Breakpoints in Virtual Member
                     Functions................................   9-21

           9-11      Setting Breakpoints in Member Functions
                     for a Specific Object....................   9-22

           9-12      Setting Breakpoints in Specific
                     Overloaded Functions.....................   9-23

           9-13      Setting Breakpoints in All Versions of an
                     Overloaded Function......................   9-25

           9-14      Setting Breakpoints in Overloaded
                     Functions by Line Number.................   9-26

           9-15      Setting Breakpoints in Constructors......   9-26

           9-16      Setting Breakpoints in Destructors.......   9-27

           9-17      Calling an Overloaded Function...........   9-27

           9-18      Using a Cast to Perform Data Coercion....   9-29

           9-19      Using Casts on a Derived Class Object....   9-29

           9-20      Using a Cast with Pointer Notation to
                     Perform a Type Transfer..................   9-30

           9-21      Using a Cast with Reference Type Notation
                     to Perform a Type Transfer...............   9-30

           9-22      Example of a Function Template...........   9-31

           9-23      Setting a Breakpoint in the Template
                     Function.................................   9-31

           9-24      Displaying the Current Function Context
                     for a Function Template..................   9-32

           9-25      Displaying an Instantiated Class
                     Template.................................   9-32

           9-26      Displaying an Instantiated Class
                     Template.................................   9-34

           9-27      Setting Breakpoints in an Instantiated
                     Class Function...........................   9-34

           9-28      Setting Current Class Scope to an
                     Instantiated Class.......................   9-34

           9-29      Alternate Method of Setting Current Class
                     Scope....................................   9-35

           9-30      Setting Breakpoints in Exception
                     Handlers.................................   9-37

     x

 






              9-31      Printing a Class Description in Verbose
                        Mode.....................................   9-39

              9-32      Printing Base Pointer Information........   9-40

              9-33      Printing a Stack Trace in Verbose Mode...   9-42

        Figures

              9-1       A Stack Trace Displaying a Member
                        Function.................................   9-15

        Tables

              1         Conventions Used in this Manual..........    xiv

              2-1       Standard Macro Names.....................   2-18

              2-2       System Identification Macro Names........   2-18

              2-3       Other Predefined Macro Names.............   2-19

              2-4       Language Dialect Macro Names.............   2-21

              2-5       Implementation Compatibility Macro
                        Names....................................   2-21

              2-6       __DECC_VER Version-Type Encodings .......   2-23

















                                                                      xi

 











        ________________________________________________________________

                                                                 Preface



              This manual contains information for developing and
              debugging Compaq C++ programs on Tru64 UNIX and Linux
              Alpha systems, and includes information on other Tru64
              UNIX and Linux Alpha features and tools that work with
              Compaq C++.

                ________________________Note  ________________________

                Most information in this manual applies to both the
                Tru64 UNIX and Linux Alpha platforms. The notation
                [Tru64] introduces information that applies only
                to Tru64 UNIX; the notation [Linux] introductes
                information that applies only to Linux Alpha.

                _____________________________________________________

        Intended Audience

              This manual is intended for experienced programmers
              who need to develop Compaq C++ programs on Tru64 UNIX
              and Linux Alpha systems. Users of this manual should
              have a basic understanding of the C++ language and some
              familiarity with the Tru64 UNIX and Linux Alpha operating
              systems.

        Structure of this Document

              This manual is organized as follows:

              o  Chapter 1 shows how to create, compile, link, and run
                 Compaq C++ programs.

              o  Chapter 2 describes features and characteristics that
                 are specific to the Compaq C++ implementation.

                                                                      xi

 






           o  Chapter 3 describes how to modify existing C header
              files to be accepted by Compaq C++.

           o  Chapter 4 contains tips for moving applications built
              with other C++ implementations to Compaq C++.

           o  Chapter 5 describes how to use templates with Compaq
              C++.

           o  Chapter 6 describes how to use precompiled headers with
              Compaq C++.

           o  Chapter 7 describes the Compaq C++ implementation of
              the C++ Standard Library.

           o  Chapter 8 explains how to use C++ exception handling.

           o  Chapter 9 describes how to use the Ladebug debugger.

           o  Appendix A describes Class Library restrictions.

           o  Appendix B describes built-in functions.

           o  Appendix C describes Third Degree messages generated by
              the C++ Class and Standard Libraries.

           o  The cxx(1) reference page describes command line
              options.

     Associated Documents

           The following documents contain information associated
           with topics in this manual:

           o  Stroustrup, Bjarne. The C++ Programming Language, 3rd
              Edition. Reading, Massachusetts: Addison-Wesley, 1997.

              Provides an exhaustive introduction to the C++
              programming language, including sophisticated language
              features. This book also includes the text but not the
              annotations of The Annotated C++ Reference Manual.

           o  C++ Class Library Reference Manual

              This manual describes the class library packages
              supplied with Compaq C++.

           o  Compaq C++ Installation Guide for Tru64 UNIX

     xii

 






                 This document supplies the information necessary
                 to install Compaq C++. on Tru64 UNIX  systems.
                 Instructions for installing Compaq C++ on Linux Alpha
                 systems are provided in a README document supplied with
                 the C++ for Linux Alpha kit.

              o  The AT&T C++ Language System, Release 2.0, Library
                 Manual

                 This document describes the AT&T class library package.

        Related Documents

              The following documents are not included in the Compaq
              C++ documentation set. Refer to them for additional
              information on the C++ programming language, Compaq C,
              or Tru64 UNIX and Linux Alpha programming.

              o  Stroustrup, Bjarne and Margaret Ellis. The Annotated
                 C++ Reference Manual. Reading, Massachusetts: Addison-
                 Wesley, 1990.

                 This text contains the current language definition of
                 C++.

              o  Carroll, Martin D. and Margaret E. Ellis. Designing and
                 Coding Reusable C++. Reading, Massachusetts: Addison-
                 Wesley, 1995.

                 This text provides practical information for designing
                 and implementing C++ programs.

              o  Myers, Scott. Effective C++: 50 Specific Ways to
                 Improve Your Programs and Designs, 3rd edition.
                 Reading, Massachusetts: Addison-Wesley, 1997.

              o  Myers, Scott. More Effective C++: 35 New Ways
                 to Improve Your Programs and Designs. Reading,
                 Massachusetts: Addison-Wesley, 1995.

                 These texts provide practical information for designing
                 and implementing C++ programs.

              o  Tru64 UNIX Programmer's Guide

                 This guide describes the programming environment on
                 the Tru64 UNIX operating system, emphasizing the C
                 programming language.

              o  Compaq C Language Reference Manual

                                                                    xiii

 






              Provides a complete technical description of the C
              language as specified by the ANSI X3J11 committee.
              This manual also fully describes all extensions to this
              standard implemented in Compaq C.

           o  ULTRIX to Tru64 UNIX Migration Guide

              Describes how to migrate from an ULTRIX system to a
              Tru64 UNIX system. This book includes information on
              porting applications from ULTRIX to Tru64 UNIX systems.

           o  International Standard ISO/IEC 14882

              Defines the C++ International Standard. The document is
              available for downloading at the ANSI Electronic Store
              (start at

              The printed version is also available for purchase
              from the same web site. Choose "Catalogs/Standards
              Information", then "ANSI-ISO-IEC Online Catalog", then
              search for "14882".

     Conventions Used in this Manual

           Table 1 lists the conventions used in this manual.

           Table_1_Conventions_Used_in_this_Manual___________________

           Convention____________Meaning_____________________________

           %                     A percent sign (%) is the default
                                 user prompt.

           class complex {       A vertical ellipsis indicates that
                 .               some intervening program code or
                 .               output is not shown. Only the more
                 .               pertinent material is shown in the
           };                    example.

                                             (continued on next page)





     xiv

 






              Table_1_(Cont.)_Conventions_Used_in_this_Manual___________

              Convention____________Meaning_____________________________

              , . . .               A horizontal ellipsis in a syntax
                                    description indicates that you
                                    can enter additional parameters,
                                    options, or values. A comma
                                    preceding the ellipsis indicates
                                    that successive items must be
                                    separated by commas.

              The generic           Monospaced type denotes the names of
              class . . .           Compaq C++ language elements, and
              The get() func-       also the names of classes, members,
              tion . . .            and nonmembers. Monospaced type is
                                    also used in text to reference code
                                    elements displayed in examples and
                                    file-name extensions.

              italic                Italic type denotes the names of
                                    variables that appear as parameters
                                    or in arguments to functions, and
                                    also denotes book titles.

              boldface              Boldface type in text indicates the
                                    first instance of terms defined in
                                    text.

              UPPERCASE             The Tru64 UNIX and Linux Alpha
              lowercase             operating systems distinquish
                                    between uppercase and lowercase
                                    characters. Literal strings
                                    that appear in text, examples,
                                    syntax descriptions, and function
                                    definitions must be entered exactly
                                    as shown.

              cxx(1)                Cross-references to reference pages
                                    include the appropriate section
              ______________________number_in_parentheses.______________




                                                                      xv

 






     Reader's Comments

           You may send comments or suggestions regarding this
           manual, or any Compaq C++ document, by electronic mail
           to the following Internet address:

           compaq_cxx@compaq.com.

           Include the title of the document, section and page number
           where the error occurred.

     Product Support

           Customers with support contracts should seek support for
           problems through local customer support centers.

           Customers who do not have support contracts are encouraged
           to mail problem reports to compaq_cxx.bugs@compaq.com.
           Although these reports will certainly be used as a
           source of input for fixing problems for new releases,
           we cannot give the reports individual attention. We can
           take remedial action only on a best-effort basis.

           If you have questions, suggestions, or comments, please
           send mail to compaq_cxx@compaq.com.

           When reporting problems to Compaq, please provide the
           following information:

           o  Name and version of compiler (from a listing file or by
              specify the -V command-line option).

           o  Name and version of operating system

           o  Smallest possible complete source and commands needed
              to reproduce the problem.

           o  An example of the incorrect results and the desired
              results






     xvi

 









                                                                       1
        ________________________________________________________________

                                       Building and Running C++ Programs



              This chapter provides information about the basic steps
              involved in developing a Compaq C++ program. It explains
              how to compile, link, and debug programs.

              Compaq C++ is an implementation of the C++ programming
              language. The compiler is part of the Compaq Tru64 UNIX
              and Linux Alpha compiler systems. See the Compaq Tru64
              UNIX and Linux Alpha Programmer's Guide for program
              development information that applies to all Compaq
              Tru64 UNIX and Linux Alpha languages, such as using the
              compiler system, creating shared libraries, profiling, and
              optimization.

        1.1 Compiling a Program

              The cxx command invokes the compiler. For information
              about using the cxx (Compaq C++ compiler) command,
              including a description of command options, refer to the
              cxx(1) reference page. For information about this release,
              see the online release notes in:

              /usr/lib/cmplrs/cxx/CompaqCXXversion.release-notes

              or

              /usr/lib/compaq/cxx-version/alpha-linux/doc/readme.ps | .txt

              You can compile a mixture of C++ and C source code by
              entering a single cxx compile command. The compiler
              distinguishes between C++ source files (for example, .cxx)
              and C source files (for example, .c) based on their file
              extensions, and it compiles the modules appropriately.

              Unless you use the -x option to direct the compiler to
              ignore file-name extensions, passing a file with a .c
              extension to the cxx command causes the compiler driver
              to treat the file as a C file and pass it on to the cc

                                   Building and Running C++ Programs 1-1

 



     Building and Running C++ Programs
     1.1 Compiling a Program

           command on Tru64 UNIX or the ccc command on Linux Alpha
           . If the file contains C++ code instead of C code, the
           compilation might produce errors.

     1.2 Linking a Program

           Always use the cxx command to link your programs. Linking
           through the cxx command ensures that all the necessary
           link options are passed to the ld linker. If your program
           is not linked properly, some static objects will not be
           initialized at program startup. If a module is built
           using Version 6.n, it must be linked with the Version
           6.n library.

           If you choose to use the ld linker directly, you might
           need to modify your ld command whenever you install a new
           version of the compiler or the Compaq Tru64 UNIX and Linux
           Alpha operating system. After the installation, follow
           these steps:

           1. Invoke the cxx command and specify the -v option to
              display the ld command in use.

           2. Compare this ld command with your ld command and make
              any necessary changes.

           If you are using templates, you must modify the ld command
           by replacing the -input argument with a list of your
           template instantiation object files. The replacement
           string is normally cxx_repository/*.o.

           To use automatic template instantiation, you must link
           with cxx.

           See the cxx(1) and the ld(1) reference pages for more
           information.

     1.3 Name Demangling

           The C++ compiler encodes type information in function
           names to enable type-safe linkage. This encoding is called
           name mangling. Function name mangling allows object code
           to have distinct names for functions that share the same
           name in the C++ source code and enables type-safe linkage.

     1-2 Building and Running C++ Programs

 



                                       Building and Running C++ Programs
                                                     1.3 Name Demangling

              It is often difficult to decipher mangled names that might
              appear in diagnostic messages from system tools such as
              the ld linker. A name demangler is provided to translate
              such mangled names into the function names that appear
              in the source code, so that they are recognizable by the
              user.

              You can use either the cxx command or the demangle command
              to help interpret mangled messages from the linker. If
              you use the cxx command to invoke the linker, the compiler
              pipes any linker output to the name demangler unless you
              specify the -nodemangle option.

              The demangle command reads each file in sequence,
              demangles any names encoded by the compiler, and displays
              the results on the standard output device. See the
              demangle(1) reference page for more information.

              Syntax

              demangle [-show_mangled_name][-no_vtable_info][-
        ][file . . . ]

              If no input file is given, or if a minus sign is
              encountered as an argument (for example, demangle -),
              the demangle command reads from the standard input file.
              The demangle utility supports the processing of 8-bit
              characters.

              Options

              -               Read from the standard input file.

              -show_mangled_namesplay encoded name in parentheses after
                              demangled name.

              -no_vtable_     Suppress the display of information
              info            concerning internal symbols (specifically
                              __vtbl and __btbl).

              Example

              demangle file

              This command demangles a file containing Compaq C++
              encoded names.

              ld main.o foo.o |& demangle

              This command (from the C shell) demangles the output from
              the linker (ld) when linking the main.o and foo.o files.

                                   Building and Running C++ Programs 1-3

 



     Building and Running C++ Programs
     1.4 C++ Standard Library

     1.4 C++ Standard Library

           The C++ Standard Library defines a complete specification
           of the International C++ Standard, with some differences,
           as described in the online release notes in:

           /usr/lib/cmplrs/cxx/CompaqCXXversion.release-notes

           or

           /usr/lib/compaq/cxx-version/alpha-linux/doc/readme.ps | .txt

           Some of the components in the C++ Standard Library are
           designed to replace nonstandard components that are
           currently distributed in the C++ Class Library. However,
           Compaq will continue to provide the C++ Class Library.
           Note that on Linux Alpha, the Class Library task package
           in not supported.

           On Tru64 UNIX, the Class Library task package will
           gradually be retired. Starting with Version 6.3 of the
           compiler, the task library is no longer distributed in the
           shared format.

           Linking to the Standard Library

           When you use the cxx command to compile and link programs
           that use the C++ Standard Library, no special switches
           are required. The C++ driver automatically includes the
           Standard Library run-time support (-lcxxstd ) on the link
           command, and automatic template instantiation (-pt ) is
           the default mode.

           For example, to build a program called prog.cxx that uses
           the Standard Library, you enter the following command:

           cxx prog.cxx

           For detailed information about the Standard Library, refer
           to Chapter 7.

     1.5 C++ Class Library

           Reusing code is a cornerstone of object-oriented
           programming. To minimize the time it takes to develop new
           applications, a set of reusable classes is an essential
           part of Compaq C++. Class libraries offer a variety
           of predefined classes that enable you to work more
           efficiently.

     1-4 Building and Running C++ Programs

 



                                       Building and Running C++ Programs
                                                   1.5 C++ Class Library

              See the C++ Class Library Reference Manual for a detailed
              explanation of the Class Library packages supplied with
              the compiler. The iostream class library package is from
              AT&T. See The AT&T C++ Language System, Release 2.0,
              Library Manual for a description of this package.

              Linking to the C++ Class Library

              Most of the C++ Class Library packages are automatically
              included in your program when needed. However, when
              using the complex package, you must provide the following
              explicit information for the linker:

              -lcomplex -lm

              [Tru64] To use the task package, specify the following
              when linking using the cxx command:

              -threads -ltask

              For example:

              cxx thread_program.cxx -threads -ltask

              If you link using the -non_shared option to the cxx
              command, you must also specify -lcmalib. For example:

              cxx -non_shared thread_program.cxx -threads -ltask -lcmalib

              These and other Class Library packages are documented in
              the C++ Class Library Reference Manual.

        1.6 Debugging

              The Ladebug Debugger is a source-level debugger that
              supports Compaq C++. Neither the dbx nor the gdb debugger
              supports debugging C++ programs. For details on using the
              Ladebug Debugger, see Chapter 9.

        1.7 Improving Build Performance

              This section contains suggestions for improving build
              performance when using Compaq C++ on your system.


                                   Building and Running C++ Programs 1-5

 



     Building and Running C++ Programs
     1.7 Improving Build Performance

     1.7.1 Object File Compression [Tru64]

           By default, the compiler compresses object files. This
           reduces object file size and can result in shortened
           link times, depending on characteristics of the system
           and the application. For some large applications, object
           file compression can significantly slow down the compiler
           and the linker and can significantly increase the amount
           of virtual memory required when linking. For some large
           applications, it is advantageous to compile without object
           file compression. To do so, specify the -nocompress option
           on the cxx command.

     1.7.2 Using Shared Libraries

           Partitioning a large application into several shared
           libraries, which are then linked into an executable,
           is a useful technique for reducing link times during
           development. See Chapter 3 for details.

     1.7.3 Using Precompiled Headers

           Using precompiled headers can reduce compilation time in
           environments where

           o  Many primary sources include the same set of headers in
              the same order.

           o  These headers introduce many lines of code.

           See Chapter 6 for details.

     1.7.4 Performance Optimization Options

           For a description of performance optimization options, see
           the cxx(1) reference page.

     1.8 Deploying Your Application [Tru64]

           Applications developed using the Compaq C++ compiler
           require functionality provided in the C++ Run-Time
           Library. While this run-time library ships with the Tru64
           UNIX operating system, newer versions are released with
           each new version of the compiler. These newer versions
           provide bug fixes and support for new features in the
           compiler.

     1-6 Building and Running C++ Programs

 



                                       Building and Running C++ Programs
                                  1.8 Deploying Your Application [Tru64]

              The C++ library redistribution kit gives the user the
              oportunity to upgrade the C++ library to the most up-to-
              date libraries without having to upgrade the entire OS and
              alleviates the need for application developers to include
              it in their distributions. Because the library is built
              to be upwardly compatible, a later version of the library
              works with applications developed by all prior versions of
              the compiler.

              While we strongly recommend upgrading for bug fixes,
              this is not mandatory. Read the compiler Release Notes
              at http://www.unix.digital.com/cplus/docs/rnu.htm to
              determine whether your application depends on these bug
              fixes.

              Upgrading for new compiler feature support is not
              optional. To run an application developed using verion
              n of the compiler, you must use a version of the library
              that provides support for all its features. In previous
              versions, this typically results in undefined symbol
              errors from the loader at runtime. Starting in V6.3,
              failure to do so will result in the following diagnosic
              from the loader at runtime:

              slab> a.out
              333677:a.out: /sbin/loader: Fatal Error: object libcxx.so from liblist in a.out
              has version "cxx6.3", which does not match the found object: libcxx.so (with
              version ":V4.0.1")

              The following table provides the version of the library
              that shipped with each version of the OS. The C++ Compiler
              Feature Version is the absolute highest version of the
              compiler with which an application could have been
              developed and be deployed on this platform without the
              redistribution kit. An application developed with a
              newer compiler or that depends on a bug fix requires the
              installation of the redistribution kit.








                                   Building and Running C++ Programs 1-7

 



     Building and Running C++ Programs
     1.8 Deploying Your Application [Tru64]

           __________________________________________________________
                                         Highest Version of C++
                                         Compiler
                 Default C++ Library     Not Requiring Redistribution
           OS____Shipped_with_System_____Kit_________________________

           4.0D  6.0-021                 6.1-031

           4.0E  6.0-021                 6.1-031

           4.0F  6.1-031                 6.1-031

           4.0G  6.2-037                 6.2-040

           5.0   6.2-024                 6.2-040

           5.0A  6.2-037                 6.2-040

           5.1   6.2-037                 6.2-040

           5.1A  6.3-001                 6.5-nnn

           NEXT  6.3-001                 6.5-nnn

           TBD___6.5-nnn_________________6.5-nnn_____________________

     1.8.1 Redistributing the C++ Run-Time Library

           If you are a third-party vendor who is shipping a product
           based on Version 6.5 or later, you must ensure your that
           your customers have a V6.3 or later C++ Run-Time Library.
           To do so, you can direct them to download the latest
           redistribution kit from the  Compaq C++ web site, or
           you can redistribute it under conditions stated in the
           Software Product Description.

           The mechanism for redistributing the library is for you to
           provide the file

           /usr/lib/cmplrs/cxx/version/CXXREDIST650Vmm.tar

           mm is the revision numbers for this release. This tar file
           contains a setld kit that installs /usr/lib/cmplrs/cxx/version/libcxx.so
           and places a symbolic link in /usr/lib/cmplrs/cxx to the
           latest runtime installed on the system.

     1-8 Building and Running C++ Programs

 



                                       Building and Running C++ Programs
                                  1.8 Deploying Your Application [Tru64]

        1.8.2 Instructions for Installing Redistribution Kit

              To install the kit, follow these steps:

              1. Check if the installed libcxx is earlier than the one
                 on this redistribution kit

                 Newer libcxx.so images have symbols defined which
                 identify the version of the run-time library. If the
                 symbol __libcxx_V60500001 exists in the image on your
                 system, then you do not need to install this kit.

                    # nm /usr/lib/cmplrs/cxx/libcxx.so | grep libcxx_V
                    __libcxx_V60200002    | 0004396996916008 | G | 0000000000000000
                    __libcxx_V60200003    | 0004396996916016 | G | 0000000000000000
                    __libcxx_V60300001    | 0004396996918728 | G | 0000000000000000
                    __libcxx_V60500001    | 0004396996920176 | G | 0000000000000000

              2. If an older redistribution kit was previously installed
                 on the system, it must be removed prior to the
                 installation of the new one.

                 The subset name could be CXXLIBnnn or CXXREDISTnnn

                    # /usr/sbin/setld -i | egrep "CXXLIB|CXXREDIST" | grep install
                    CXXREDIST610   installed  Compaq C++ Run-Time Library ...

                    # /usr/sbin/setld -d CXXREDIST610

              3. Install the redistribution kit

                    # tar -xvf CXXREDIST650Vmm.tar
                    # /usr/sbin/setld -l CXXREDIST650.kit

        1.9 Using OpenMP

              The compiler supports C/C++ OpenMP Version 1.0. C++
              exception handling within an OpenMP parallel region
              is not initially supported but will be supported in a
              later release. By default, the compiler ignores all C++
              OpenMP directives unless you specify the -omp option. For
              example:

              cxx -omp omp_program.cxx

                                   Building and Running C++ Programs 1-9

 









                                                                       2
        ________________________________________________________________

                                               Compaq C++ Implementation



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

        2.1 Implementation-Specific Attributes

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

        2.1.1 #pragma Preprocessor Directive

              The #pragma preprocessor directive is a standard method
              for implementing features that differ from one compiler
              to the next. This section describes pragmas specifically
              implemented in the compiler for Compaq Tru64 UNIX and
              Linux Alpha systems.

              Note that the compiler accepts double underscore
              forms of keywords (for example, #pragma __inline) for
              compatibility with user-written header files.

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

              The following #pragma directives are subject to macro
              expansion. A macro reference can occur anywhere after the
              pragma keyword.


                                           Compaq C++ Implementation 2-1

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes


           builtins         inline           linkage[2]       use_
                                                              linkage[2]

           dictionary[1]    noinline         module           extern_
                                                              model

           member_          message          define_template  extern_
           alignment                                          prefix
           [1]Not_supported;_specific_to_C_on_OpenVMS________________

           [2]Not supported; specific to C

     2.1.1.1 #pragma define_template Directive

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

           #pragma define_template name < template-argument-list >

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

           #pragma define_template mytempl<arg1, arg2>

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

     2.1.1.2 #pragma instantiate Directive

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

           o  The instantiate pragma causes a specified entity
              to be instantiated, similar to the define_template
              pragma. It provides finer instantiation control than
              define_template when instantiating function templates.
              It provides the same functionality as the explicit
              instantiation syntax described in Section 14.7.2 of the
              C++ International Standard.

     2-2 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              o  The do_not_instantiate pragma suppresses the instan-
                 tiation of a specified entity. It is typically used
                 to suppress the instantiation of an entity for which a
                 specific definition will be supplied.

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

        2.1.1.3 #pragma environment Directive

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

              On Compaq Tru64 UNIX and Linux Alpha systems, the #pragma
              environment directive affects the following pragmas:

                 #pragma member_alignment/pack
                 #pragma message
                 #pragma extern_model
                 [Tru64] #pragma pointer_size/required_pointer_size
                 #pragma required_vptr_size

              This pragma has the following syntax:

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

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

              header_defaults
              Sets the states of all the context pragmas to their
              default values for Compaq Tru64 UNIX and Linux Alpha
              systems. This is almost equivalent to the situation
              in which a program with no command-line options and
              no pragmas is compiled; except that this pragma sets
              the pragma message state to #pragma nostandard, as is
              appropriate for system header files.

                                           Compaq C++ Implementation 2-3

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

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

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

           Someone who creates a general purpose library, distributed
           as an archive or shared library, typically distributes
           header files that specify the interface to the library.
           For calls to the library to work, the header file must
           normally use the same member alignment, pointer size,
           extern model, and other compilation options as when the
           library was built.

           The header file should contain pragmas to save the user's
           compilation options, set the correct compilation options
           for the library, and then restore the user's compilation
           options when the include file ends. The pragmas let
           library users choose whatever compilation options are
           appropriate for their own code without unintentionally
           affecting the interface to the library.

           Not only is the #pragma environment preprocessor directive
           more convenient than explicitly specifying each individual
           pragma that controls a compilation option, it is also
           upwardly compatible. As new pragmas are added to the
           compiler , #pragma environment header_defaults will be
           enhanced to set the state of the new pragmas to their
           default. Thus, a header file that uses #pragma environment
           sets a known state for not only the current pragmas in the
           compiler, but future pragmas as well.

           Without requiring further changes to the source code, you
           can use #pragma environment to protect header files from
           things like language extensions and enhancements that
           might introduce additional contexts.

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


     2-4 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

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

              In this example:

              1  Saves the state of all context pragmas

              2  Sets the default compilation environment

              3  Pops the member alignment context from the #pragma
                 member_alignment stack that was pushed by #pragma
                 __environment save (restoring the member alignment
                 context to its preexisting state)

              4  Pushes the member alignment context back onto the stack
                 so that the #pragma __environment restore can pop off
                 the entry

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

        2.1.1.4 #pragma extern_prefix Directive

              The #pragma extern_prefix directive is an OpenVMS pragma
              that cannot be used on Compaq Tru64 UNIX and Linux Alpha
              systems.

        2.1.1.5 #pragma ident Directive

              The #pragma ident directive enables insertion of an
              identification string into the object and executable
              (usually a version number). The string can be found by
              using the strings command or, if the string contains a
              specific recognized substring, by using the what command.
              For more information on the strings and what commands, see
              the reference pages.

                                           Compaq C++ Implementation 2-5

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

           In version 4.n of Compaq's Compaq Tru64 UNIX, the contents
           of the string are placed in the .rconst section of the
           object file and in the executable. In the next major
           release of the operating system, the contents of the
           string are placed in the .comment section of the object
           and the executable. The .comment section is present in the
           executable on disk but is not mapped into virtural memory
           at load-time.

           The mcs command allows users to perform operations
           on the comment section .comment of (e)COFF object
           files. This section can contain information such
           as the "ident" string from a source file and other
           information used by components of the Compaq Tru64 UNIX
           development environment. Users can optionally add their
           own information to the comment section by using the mcs
           tool.

           For additional information, refer to the Revision Contol
           System (RCS) and Source Code Control System (SCCS)
           reference pages.

           The pragma has the following syntax:

           #pragma ident "user-defined string"

     2.1.1.6 #pragma [no]inline Directive

           This is a C pragma that cannot be used in C++. Use the
           inline keyword instead.

     2.1.1.7 #pragma intrinsic Directive

           The #pragma intrinsic directive specifies that calls to
           the specified functions are intrinsic. Intrinsic functions
           are functions in which the compiler generates optimize
           code in certain situations, possibly avoiding a function
           call.

           The #pragma intrinsic directive has the following syntax:

           #pragma intrinsic (function1[,function2, . . . ])

           You can use this directive to make intrinsic the default
           form of functions that have intrinsic forms. The following
           functions have intrinsic forms:

     2-6 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              abs
              fabs
              labs
              alloca

              You can use the #pragma function directive to override the
              #pragma intrinsic directive for specified functions.

              The function must have a declaration visable at the time
              the compiler encounters the #pragma intrinsic directive.
              The compiler takes no action if the compiler does not
              recognize the specified function name as an intrinsic.

        2.1.1.8 #pragma [no]member_alignment Directive

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

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

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

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

              This pragma has the following syntax:

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

              When #pragma member_alignment is used, the compiler aligns
              structure members on the next boundary appropriate to
              the type of the member, rather than on the next byte. For
              example, a long variable is aligned on the next longword
              boundary; a short variable is aligned on the next word
              boundary. Consider the following example:

                                           Compaq C++ Implementation 2-7

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

           #pragma nomember_alignment
           struct x {
                      char c;
                      int b;
                      };
           #pragma member_alignment

           struct y {
                     char c;       /*3 bytes of filler follow c */
                     int b;
                     };

           main ()

           {
                   printf( "The sizeof y is: %d\n", sizeof (struct y) );
                   printf( "The sizeof x is: %d\n", sizeof (struct x) );
           }

     When this example is executed, it shows the difference between
     #pragma member_alignment and #pragma nomember_alignment.

           The optional base_alignment parameter can be used to
           specify the base-alignment of the structure. Use one of
           the following keywords for the base_alignment:

              byte (1 byte)
              word (2 bytes)
              longword (4 bytes)
              quadword (8 bytes)
              octaword (16 bytes)

           The #pragma member_alignment save and #pragma member_
           alignment restore directives can be used to save the
           current state of the member_alignment and to restore the
           previous state, respectively. This feature is necessary
           for writing header files that require member_alignment or
           nomember_alignment, or that require inclusion in a member_
           alignment that is already set.






     2-8 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

        2.1.1.9 #pragma message Directive

              The #pragma message preprocessor directive controls the
              kinds of individual diagnostic messages or groups of
              messages that the compiler issues.

              Default severities used by the compiler can be changed
              only if they are informationals, warnings or discretionary
              errors. Attempts to change more severe severities are
              ignored. If a message severity has not been altered by
              the command line and is not currently being controlled by
              a pragma, the compiler checks to see whether the message
              severity should be changed because of the "quiet" state.
              If not, the message is issued using the default severity.

              Error message severities start out with command line
              severities applied to default compiler severities.
              Pragma message severities are then applied. In general,
              pragma severities override command line severities, which
              override default severities. The single exception this is
              that command line options can always be used to downgrade
              messages. However, command line options cannnot be used
              to raise the severity of messages currently controlled by
              pragmas.

              The #pragma message directive has the following syntax:

              #pragma message disable (message-list)
              #pragma message enable (message-list)
              #pragma message restore
              #pragma message save
              #pragma message error
              #pragma message informational
              #pragma message warning

              disable
              Suppresses the compiler-issued messages specified in the
              message-list argument. The message-list argument can be
              any one of the following:

              o  A single message identifier

              o  The keyword for a single message group as follows:

                    all-All messages issued by the compiler
                    check-All messages about potentially poor coding
                    practices

                                           Compaq C++ Implementation 2-9

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

                 portable-All messages about portability


           o  A single message identifier enclosed in parentheses

           o  A single message group name enclosed in parentheses

           o  A comma-separated list of message identifiers or group
              names (freely mixed) enclosed in parentheses

           The message identifier is the name following the message
           text when the -verbose option is set. A D: preceding
           the message identifier indicates that the message is
           discretionary; that is, you can change its severity or
           disable it. For example, consider the following message:

           Non-void function "name" does not contain a return statement. (D:missingreturn).

           The message identifier is missingreturn. To prevent the
           compiler from issuing this message, use the following
           directive:

           #pragma message disable missingreturn

           enable
           Enables the compiler to issue the messages specified in
           the message-list argument.

           restore
           Restores the saved state of enabling or disabling compiler
           messages.

           save
           Saves the current state of enabling or disabling compiler
           messages.

           The save and restore options are useful primarily within
           header files. See Section 2.1.1.3.

     2.1.1.10 #pragma module Directive

           When you compile source files to create an object file,
           the compiler assigns the first of the file names specified
           in the compilation unit to the name of the object file.
           The compiler adds the .o file extension to the object
           file. Internally, the operating system and the debugger
           recognize the object module by the file extension.

     2-10 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              To change the system-recognized module name and version
              number, use the #pragma module directive.

              You can find the module name and the module version number
              listed in the compiler listing file and the linker load
              map.

              You can use the #pragma module directive when compiling in
              any mode.

              The #pragma module directive has the following syntax:

              #pragma module identifier identifier

              #pragma module identifier string

              The first parameter must be an identifier and specifies
              the module name. This is primarily used by the linker on
              OpenVMS systems, but is also used in the heading of the
              listing file. The second parameter specifies the optional
              identification. See Section 2.1.1.5 for more information
              about this.

        2.1.1.11 #pragma once Directive

              The #pragma once preprocessor directive specifies that the
              header file is evaluated only once.

              The #pragma once directive has the following format:

              #pragma once

        2.1.1.12 #pragma pack Directive

              The #pragma pack preprocessor directive specifies packing
              alignment for structure and union members. Whereas the
              packing alignment of structures and unions is set for
              an entire translation unit by the -ZpN (N = 1, 2, or 4)
              and the -nomember_align option, the packing alignment
              is set at the data-declaration level by the pack pragma.
              The pragma takes effect at the first structure or union
              declaration after the pragma is seen; the pragma has no
              effect on definitions.

              The #pragma pack directive has the following format:

              #pragma pack [(n)]

                                          Compaq C++ Implementation 2-11

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

           When you use #pragma pack(n), where n is 1, 2, 4, 8, or
           16, each structure member after the first is stored on
           the smaller member type or n-byte boundaries. If you use
           #pragma pack without an argument, structure members are
           packed to the value specified by -Zp. The default -Zp
           packing size is -Zp8.

           The compiler also supports the following enhanced syntax:

           #pragma pack( [ [ { push | pop}, ] [ identifier, ] ] [ n ]
     )

           This syntax allows you to combine program components into
           a single translation unit if the various components use
           pack pragmas to specify different packing alignments.

           Each occurrence of a pack pragma with a push argument
           stores the current packing alignment on an internal
           compiler stack. The pragma's argument list is read from
           left to right. If you use push, the current packing
           value is stored. If you provide a value for n, that
           value becomes the new packing value. If you specify an
           identifier, a name of your choosing, the identifier is
           associated with the new packing value.

           Each occurrence of a pack pragma with a pop argument
           retrieves the value at the top of an internal compiler
           stack and makes that value the new packing alignment.
           If you use pop and the internal compiler stack is empty,
           the alignment value is that set from the command-line and
           a warning is issued. If you use pop and specify a value
           for n, that value becomes the new packing value. If you
           use pop and specify an identifier, all values stored on
           the stack are removed from the stack until a matching
           identifier is found. The packing value associated with the
           identifier is also removed from the stack and the packing
           value that existed just before the identifier was pushed
           becomes the new packing value. If no matching identifier
           is found, the packing value set from the command line
           is used and a level-one warning is issued. The default
           packing alignment is 8.




     2-12 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              The pack pragma allows you to write header files that
              ensure that packing values are the same before and after
              the header file is encountered:

              /* File name: include1.h
              */
              #pragma pack( push, enter_include1 )
              /* Your include-file code ... */
              #pragma pack( pop, enter_include1 )
              /* End of include1.h */

              In the previous example, the current pack value is
              associated with the identifier enter_include1 and pushed,
              remembered, on entry to the header file. The pack pragma
              at the end of the header file removes all intervening
              pack values that may have occurred in the header file and
              removes the pack value associated with enter_include1. The
              header file thus ensures that the pack value is the same
              before and after the header file.

              The new functionality also allows you to use code, such
              as header files, that uses pack pragmas to set packing
              alignments that differ from the packing value set in your
              code:

              #pragma pack( push, before_include1 )
              #include "include1.h"
              #pragma pack( pop, before_include1 )

        In the previous example, your code is protected from any changes
        to the packing value that might occur in include.h.

        2.1.1.13 #pragma pointer_size Directive [Tru64]

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

              o  References

              o  Pointers to member declarations

              o  Function declarations

              o  Array declarations

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

                                          Compaq C++ Implementation 2-13

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

           This pragma has the following syntax:

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

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

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

           restore
           Restores the saved pointer size from the pointer size
           stack.

           save
           Saves the current pointer size on a pointer size stack.

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

           Use of short pointers is restricted to the Compaq C++ and
           the C compilers resident on Compaq Tru64 UNIX systems.
           Programs should not attempt to pass short pointers from
           C++ routines to routines written in any other language
           except the C programming language.

           Compaq C++ might require explicit conversion of short
           pointers to long pointers in applications that use short
           pointers. You should first port those applications in
           which you are considering using short pointers, and then
           analyze them to determine if short pointers would be
           beneficial.

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

     2-14 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              The compiler issues an error-level diagnostic if:

              o  Two functions defined differ in argument types only
                 with respect to pointer sizes.

              o  Two functions differ in return type only with respect
                 to pointer size.

              o  The compiler encounters a member function that tries to
                 overload another that differs only with respect to the
                 pointer size of the this parameter.

        2.1.1.14 #pragma required_pointer_size Directive [Tru64]

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

        2.1.1.15 #pragma required_vptr_size Directive [Tru64]

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

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

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

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


                                          Compaq C++ Implementation 2-15

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

     2.1.1.16 #pragma [no]standard Directive

           Use the #pragma nostandard and #pragma standard prepro-
           cessor directives to disable all but the most significant
           messages from header file processing.

           This pragma has the following syntax:

           #pragma [no]standard

           Use #pragma nostandard to mark the start of reduced
           message activity.

           Use #pragma standard to mark the resumption of normal
           message activity.

     2.1.1.17 #pragma weak Directive

           Use the #pragma weak preprocessor directive to create weak
           symbols. Weak symbols are symbols that can be overridden
           by strong symbols. Symbols are strong by default.

           This pragma has the following syntax:

           #pragma weak weak_name
           #pragma weak weak_name = strong_name
           #pragma weak ( weak_name, strong_name )

           The first form of the pragma makes the specified name a
           weak symbol. The other two make a weak symbol that refers
           to the same symbol as the other name.

     2.1.2 Protecting System Header Files

           It is important to protect system header files from
           generating diagnostics and from user-specified changes
           to member alignment and pointer sizes.

           To provide the necessary protection you can do one of the
           following:

           o  Use a header file protection option provided by the
              compiler.

           o  Modify each header file.

     2-16 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

        2.1.2.1 Using the Compiler's Header File Protection Option

              With this option, you can place special header files
              in a directory. the compiler processes these special
              header files before and after each file included with
              the #include directive from this directory. These special
              header files are named:

                 __DECC_include_prologue.h
                 __DECC_include_epilogue.h

              The compiler checks for files with these special names
              when processing #include directives. If the special
              prologue file exists in the same directory as a file
              with the #include directive, the contents of the prologue
              file are processed just before the file included with
              the #include directive. Similarly, if the epilogue file
              exists in the same directory as the file included with the
              #include directive, it is processed just after that file.

              For convenience, you can protect header files using the
              script supplied in the following directory:

              /usr/lib/cmplrs/cxx/protect_system_headers.sh

              This script creates, in all directories in a directory
              tree that contain header files, symbolic links to Compaq-
              supplied header prologue and epilogue files.

              The default directory tree root assumed by the script is
              /usr/include, but you can specify other roots.

        2.1.2.2 Modifying Each Header File

              If you choose to modify each header file that needs
              protection, you can use the #pragma environment directive,
              as in the following example:

              #pragma __environment save              // Save pointer size
              #pragma __environment header_defaults   // set to system defaults

              // existing header file

              #pragma__environment restore            // Restore pointer size

              See Section 2.1.1.3 for more information about using this
              pragma.

                                          Compaq C++ Implementation 2-17

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

     2.1.3 Predefined Macro Names

           The following tables list predefined C++ macros used
           by Compaq C++. These names are useful in preprocessor
           #ifdef and #if defined directives to isolate code intended
           for one of the particular cases. The names can be used
           anywhere you use other defined names, including within
           macros.

           For information on using predefined macros in header files
           in the common language environment, see Section 3.1.

           Table_2-1_Standard_Macro_Names____________________________

           __cplusplusefined by the C++ compiler when compiling
                     source code.

           __LINE__  The current line number (a decimal integer).

           __FILE__  The current file name (a character string).

           __DATE__  The source file's compilation date (a character
                     string literal of the form "Mmm dd yyyy", where
                     the month names are the same as those generated
                     by the asctime function, and the first character
                     of "dd" is a space character if the value is
                     less than 10.)

           __STDC__  [Linux] Compiler supports ANSI C language
                     constructs.

           __TIME__  The source file's compilation time (a character
                     string literal of the form "hh:mm:ss"), as in
           __________the_time_generated_by_the_asctime_function._____

           Table_2-2_System_Identification_Macro_Names_______________

           Macro_Name______________________Description_______________

           __alpha[1], __alpha__,          System has an Alpha
           __ALPHA                         processor.

           __arch64__                      System with 64-bit
                                           architecture.

           [1]Use_this_form_for_portability._________________________

                                             (continued on next page)

     2-18 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              Table_2-2_(Cont.)_System_Identification_Macro_Names_______

              Macro_Name______________________Description_______________

              __digital__                     System identification name
                                              on Tru64 UNIX.

              __linux, __linux__[1]           System is a Linux Alpha
                                              system.

              linux                           [Linux] System is a Linux
                                              Alpha system. Provided
                                              for GNU compatibility;
                                              use of this macro is not
                                              recommended. However, some
                                              open-source libraries use
                                              it.

              __osf__                         System is a Tru64 UNIX
                                              system.

              __unix, __unix__                System is a UNIX system.

              unix                            [Linux] System is a UNIX
                                              system. Provided for GNU
                                              compatibility; use of this
                                              macro is not recommended.
              [1]Use_this_form_for_portability._________________________

              __________________________________________________________

              Table_2-3_Other_Predefined_Macro_Names____________________

              Macro_Name______________________Description_______________

              _BOOL_EXISTS                    Indicates that bool is a
                                              typedef or keyword

              __BOOL_IS_A_RESERVED_WORD       Indicates that bool is a
                                              keyword

              __DECCXX                        Compiler is Compaq C++.

              __DECCXX_VER                    Compiler version
                                              identifier in string form.

              __IEEE_FLOAT                    The compiler supports IEEE
                                              floating point.

                                                (continued on next page)

                                          Compaq C++ Implementation 2-19

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

           Table_2-3_(Cont.)_Other_Predefined_Macro_Names____________

           Macro_Name______________________Description_______________

           __INITIAL_POINTER_SIZE          [Tru64] A decimal constant
                                           containing the initial
                                           pointer size allocation,
                                           as specified by the
                                           command line. Legal
                                           values on Tru64 UNIX are:
                                           0 (no pointer size option
                                           set), 32 (short or 32-
                                           bit pointers allocated),
                                           and 64 (long or 64-bit
                                           pointers allocated). The
                                           only legal value on Linux
                                           Alpha is 0.

           __INTRINSICS                    Compaq C++ recognizes
                                           intrinsic functions.

           __LANGUAGE_C__,  __LANGUAGE_C,  [Linux] Compiler
           LANGUAGE_C                      translates C language
                                           constructs and keywords.
                                           Provided for GNU
                                           compatibility; use of
                                           these macros is not
                                           recommended.

           _LONGLONG                       Compiler supports "long
                                           long" type declarations.

           __PRAGMA_ENVIRONMENT            The compiler supports
                                           pragma environment.

           __STDC_VERSION__                Version number of ANSI C
                                           support, in string form;
                                           not defined by the C++
                                           compiler.

           _SYSTYPE_BSD                    Compiler supports BSD type
                                           system headers.

                                             (continued on next page)

     2-20 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              Table_2-3_(Cont.)_Other_Predefined_Macro_Names____________

              Macro_Name______________________Description_______________

              _WCHAR_T[1], __WCHAR_T[2]       wchar_t is a typedef or a
                                              keyword.

              __X_FLOAT                       System has default long
                                              double size of 128 bits.
              [1]Use_this_form_for_portability._________________________

              [2]This form is used on OpenVMS systems.
              __________________________________________________________

              Predefined Language Dialect Macro Names

              Table 2-4 shows the macro names defined by specifying the
              listed command-line options.

              Table_2-4_Language_Dialect_Macro_Names____________________

              Command-line_Option______Macro_Name_______________________

              -std arm                 __STD_ARM

              -std ansi                __STD_ANSI

              -std cfront, -cfront     __CFRONT, __STD_CFRONT

              -std gnu                 __STD_GNU

              -std ms, -ms             __MS, __STD_MS

              -std strict_ansi         __STD_STRICT_ANSI, __PURE_CNAME

              -std strict_ansi_errors  __STD_STRICT_ANSI_ERRORS,
              ___________________________PURE_CNAME_____________________

              Predefined Implementation Compatibility Macro Names

              Table 2-5 shows the macro names defined by specifying the
              listed command-line options.

              Table_2-5_Implementation_Compatibility_Macro_Names________

              Command-line_Option______Macro_Name_______________________

              -fprm                    __FLT_ROUNDS

                                                (continued on next page)

                                          Compaq C++ Implementation 2-21

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

           Table 2-5 (Cont.) Implementation Compatibility Macro
           __________________Names___________________________________

           Command-line_Option______Macro_Name_______________________

           -global_array_new        __GLOBAL_ARRAY_NEW

           -ieee                    __IEEE_FP

           -implicit_include        __IMPLICIT_INCLUDE_ENABLED

           -long_double_size        __X_FLOAT

           -model ansi              __MODEL_ANSI

           -model arm               __MODEL_ARM

           -pch,-create_pch,-use_   __PCH_ENABLED
           pch

           -pthreads                _REENTRANT

           -pure_cname              __PURE_CNAME

           -rtti                    __RTTI

           -stdnew                  __STDNEW

           -threads                 _REENTRANT, _PTHREAD_USED_D4

           -using_std_________________IMPLICIT_USING_STD_____________

           Predefined __DECCXX_VER Version Number Macro

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

           The format of the compiler version-identifier string is:

           TMM.mm-eee

           Where:

           o  T is the version type (letter).

           o  MM is the major version number.

           o  mm is the update (minor version number).

           o  eee is the edit suffix number.

           The format of the integer encoding for __DECCXX_VER is:

           vvuuteeee

     2-22 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              Where:

              o  vv is the major version number.

              o  uu is the update (minor version number).

              o  t is the numerical encoding of the alphabetic version
                 type from the version-identifier string.

                 Table 2-6 lists the possible version types and their
                 encodings

              o  eeee is the edit suffix number.

              Table_2-6___DECC_VER_Version-Type_Encodings_______________

                   Numerical
              Type_Encoding__Description________________________________

              T    6         Field-test version

              S    8         Customer special

              V____9_________Officially_supported_version_______________

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

              1. The major version is multiplied by 10,000,000 (ten
                 million).

              2. The minor version (the digits between the period (.)
                 and any edit suffix) is multiplied by 100,000 (one
                 hundred thousand) and added to the suffix value (the
                 suffix value has a range of 0 to 999).

              3. If the character immediately preceding the first digit
                 of the major version number is one of those listed
                 in Table 2-6, its numerical encoding is multiplied by
                 10000.

              4. The preceding values are added together.

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

                                          Compaq C++ Implementation 2-23

 



     Compaq C++ Implementation
     2.1 Implementation-Specific Attributes

           ident           __DECCXX_VER
           string          vvuuteeee

           T5.2-003   -->   50,260,003
           V6.0-001   -->   60,090,001

     2.1.4 Translation Limits

           The only translation limits imposed in the compiler are as
           follows:

           __________________________________________________________
           Limit__Meaning____________________________________________

           32,767 Characters in an internal identifier or macro name.

           32,767 Characters in a logical or physical source line.

           32,767 Bytes in the representation of a string literal.
                  This limit does not apply to string literals formed
                  by concatenation.

           32,767 Significant characters in an external identifier.
                  A warning is issued if such an identifier is
                  truncated. Linking further limits external
           _______identifiers_to_1022_characters.____________________

     2.1.5 Numerical Limits

           The numerical limits, as defined in the header files
           <limits.h> and <float.h>, are as follows:

           o  The number of bits in a character of the execution
              character set is 8 bits.

           o  The representation and set of values for type char and
              for type signed char are the same. You can change this
              equivalence from signed char to unsigned char using the
              -unsigned option (see the cxx(1) reference page).

           o  The representation and set of values for the short type
              is 16 bits.

           o  The representation and set of values for the types int,
              unsigned int, and float are 32 bits.

           o  The representation and set of values for type double
              are 64 bits.

     2-24 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                  2.1 Implementation-Specific Attributes

              o  The representation and set of values for type long
                 double is 128 bits on Compaq Tru64 UNIX Version 5.0
                 and later. You can change this equivalence using the
                 -long_double_size 64 option (see the cxx(1) reference
                 page).

              Numerical limits not described in this list are defined in
              the C++ International Standard.

        2.1.6 Argument-Passing and Return Mechanisms


              Even if an argument is declared pass by value, the
              compiler passes arrays, functions, and class objects
              that have non-trivial copy constructors or destructors
              by reference. In the first two cases, this behavior is
              defined by the language standard.

              Class objects have non-trivial copy constructors if they
              have user-declared copy constructors, or if they have
              virtual bases, virtual functions, or non-static data
              members that require virtual table initialization.

              In the case of a class with a non-trivial copy constructor
              or a destructor, the compiler calls a copy constructor
              to copy the object to a temporary location, and then
              it passes the address of that location to the called
              function. All other objects are passed by value.

              If the return value of a function is a class that has a
              non-trivial copy constructor or destructor or is greater
              than 64 bits, storage is allocated by the caller, and the
              address of this storage is passed in the first parameter
              to the called function. The called function uses the
              storage provided to construct the return value.

        2.2 Implementation Extensions and Features

              This section describes the extensions and implementation-
              specific features of Compaq C++ for Tru64 UNIX and Linux
              Alpha systems.




                                          Compaq C++ Implementation 2-25

 



     Compaq C++ Implementation
     2.2 Implementation Extensions and Features

     2.2.1 Identifiers

           In Compaq C++, the dollar sign ($) is a valid character in
           an identifier.

           For each external function with C++ linkage, the compiler
           decorates the function name with a representation of the
           function's type.

     2.2.1.1 Character Limit for Long Names

           If an external name has more than 1022 characters, the
           compiler truncates the name to 1022 characters. The
           compiler keeps the first 1015 characters intact, reduces
           (hashes) the remaining characters to a string of 7
           characters, and appends the 7 hashed characters to the
           first 1015.

     2.2.2 Order of Static Object Initialization

           The order of static objects is defined by the implemen-
           tation. Relying on this order is not good programming
           practice. For Compaq C++, static objects are initialized
           in declaration order within a compilation unit. On Tru64
           UNIX the order across compilation units is the order on
           the link. On Linux Alpha, the order across compilation
           units is reversed. The order is a function of the linker,
           not the compiler, and is the same as g++ on Linux.

     2.2.3 Integral Conversions

           When demoting an integer to a signed integer, if the value
           is too large to be represented, the result is truncated
           and the high-order bits are discarded.

           Conversions between signed and unsigned integers of the
           same size involve no representation change.

     2.2.4 Floating-Point Conversions

           When converting an integer to a floating-point number that
           cannot exactly represent the original value, the compiler
           rounds off the result of the conversion to the nearest
           value that can be represented exactly.

     2-26 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                              2.2 Implementation Extensions and Features

              When the result of converting a floating-point number to
              an integer or other floating-point number at compile time
              cannot be represented, the compiler issues a diagnostic
              message.

              When converting an integral number or a double floating-
              point number to a floating-point number that cannot
              exactly represent the original value, the compiler rounds
              off the result to the nearest value of type float.

              When demoting a double value to float, if the converted
              value is within range but cannot exactly represent the
              original value, the compiler rounds off the result to the
              nearest representable float value.

              The compiler performs similar rounding for demotions from
              long double to double or float.

        2.2.5 Explicit Type Conversion

              In Compaq C++, the expression T() (where T is a simple
              type specifier) creates an rvalue of the specified type,
              whose value is determined by default initialization.
              According to The C++ Programming Language, 3rd Edition,
              the behavior is undefined if the type is not a class with
              a constructor, but the ANSI working draft removes this
              restriction. With this change you can now write:

                  int i=int(); // i must be initialized to 0

        2.2.6 The sizeof Operator

              The type of the sizeof operator is size_t. In the header
              file <stddef>, this type is defined as unsigned long,
              which is the type of the integer that holds the maximum
              size of an object.

        2.2.7 Explicit Type Conversion

              A pointer takes up the same amount of memory storage
              as objects of type long (or the unsigned equivalent).
              Therefore, a pointer can convert to any of these types and
              back again without changing its value. No scaling occurs
              and the representation of the value is unchanged.

                                          Compaq C++ Implementation 2-27

 



     Compaq C++ Implementation
     2.2 Implementation Extensions and Features

           Conversions to and from a shorter integer and a pointer
           are similar to conversions to and from a shorter integer
           and unsigned long. If the shorter integer type was signed,
           conversion fills the high-order bits of the pointer with
           copies of the sign bit.

     2.2.8 Multiplicative Operators

           The semantics of the division (/) and remainder (%)
           operator are as follows:

           o  If either operand of the division operator is negative,
              the compiler truncates the result toward 0 (that
              is, the smallest integer larger than the algebraic
              quotient).

           o  If either operand of the remainder operator is
              negative, the result takes the same sign as that of
              the first operand.

           In the following cases of undefined behavior detected at
           compile time, the compiler issues a warning:

              Integer overflow
              Division by 0
              Remainder by 0

     2.2.9 Additive Operators

           You can subtract pointers to members of the same array or
           a pointer that points just past the end of an array. The
           result is the number of elements between the two array
           members, and is of type ptrdiff_t. In the header file
           <stddef.h>, the compiler defines this type as long.

     2.2.10 Shift Operators

           The expression E1 >> E2 shifts E1 to the right E2
           positions. If E1 has a signed type, the compiler fills
           the vacated high-order bits of the shifted value E1 with a
           copy of E1's sign bit (arithmetic shift).




     2-28 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                              2.2 Implementation Extensions and Features

        2.2.11 Equality Operators

              When comparing two pointers to members, the compiler
              guarantees equality if either of the following conditions
              hold:

              o  Both pointers are NULL.

              o  The same address expression (&) created both pointers.

              When comparing two pointers to members, the compiler
              guarantees inequality if either of the following
              conditions hold:

              o  Only one pointer is NULL.

              o  Each pointer produces a different member if applied to
                 the same object.

              When created by different address expressions, two
              pointers to members may compare as equal if they
              produce the same member when applied to the same object;
              otherwise, they are unequal.

        2.2.12 volatile Type Specifier

              For variables that are modifiable in ways unknown to the
              compiler, use the volatile type specifier. Declaring
              an object to be volatile means that every reference to
              the object in the source code results in a reference to
              memory. Volatile quantities are also referenced atomically
              in the hardware; that is, they are fetched and stored with
              single assembler instructions. Attempts to make a volatile
              quantity be declared as not aligned incurs a compiler
              error.

              Any object whose type includes the volatile type qualifier
              indicates that the object should not be subject to
              compiler optimizations altering references to, or
              modifications of, the object.

              Optimizations that are defeated by using the volatile
              specifier can be categorized as follows:

              o  Optimizations that alter an object's duration; for
                 example, cases where references to the object are
                 shifted or moved to another part of the program.

                                          Compaq C++ Implementation 2-29

 



     Compaq C++ Implementation
     2.2 Implementation Extensions and Features

           o  Optimizations that alter an object's locality; for
              example, cases where a variable serving as a loop
              counter is stored in a register to save the cost of
              doing a memory reference.

           o  Optimizations that alter an object's existence;
              for example, loop induction to actually eliminate a
              variable reference.

           An object without the volatile specifier does not
           compel the compiler to perform these optimizations; it
           indicates that the compiler has the freedom to apply the
           optimizations depending on program context and compiler
           optimization level.

           The volatile specifier forces the compiler to allocate
           memory for the volatile object, and to always access
           the object from memory. This qualifier is often used
           to declare that an object can be accessed in some way
           not under the compiler's control. Therefore, an object
           qualified by the volatile keyword can be modified or
           accessed in ways by other processes or hardware, and is
           especially vulnerable to side effects.

           The following rules apply to the use of the volatile
           specifier:

           o  The volatile specifier can be used to qualify any
              data type, including a single member of a structure
              or union.

           o  Redundant use of the volatile keyword elicits a warning
              message. For example:

              volatile volatile int x;

           o  When volatile is used with an aggregate type declara-
              tion, all members of the aggregate type are qualified
              with volatile. When volatile is used to qualify a
              member of an aggregate type, only that member is
              qualified. For example:




     2-30 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                              2.2 Implementation Extensions and Features

                 volatile struct employee {
                     char *name;
                     int   birthdate; /* name, birthdate, job_code, and salary are */
                     int   job_code;  /* treated as though declared with volatile. */
                     float salary;
                     } a,b;          /*  All members of a and b are volatile-qualified  */

                 struct employee2 {
                     char *name;
                     volatile int birthdate;  /*  Only this member is qualified    */
                     int job_code;
                     float salary;
                     } c, d;

                 If the tag employee is used to specify another
                 structure later in the program, the volatile specifier
                 does not apply to the new structure's members unless
                 explicitly specified.

                 The const specifier can be used with the volatile spec-
                 ifier. This is useful, for example, in a declaration of
                 a data object that is immutable by the source process
                 but can be changed by other processes, or as a model of
                 a memory-mapped input port such as a real-time clock.
                 The address of a non-volatile object can be assigned
                 to a pointer that points to a volatile object. For
                 example:

                 const int *intptr;
                 volatile int x;
                 intptr = &x;

                 Likewise, the address of a volatile object can be
                 assigned to a pointer that points to a non-volatile
                 object.

        2.2.13 __unaligned Type Specifier

              Use this data-type specifier in pointer definitions to
              indicate to the compiler that the data pointed to is not
              properly aligned on a correct address. (To be properly
              aligned, the address of an object must be a multiple of
              the size of the type. For example, two-byte objects must
              be aligned on even addresses.)

                                          Compaq C++ Implementation 2-31

 



     Compaq C++ Implementation
     2.2 Implementation Extensions and Features

           When data is accessed through a pointer declared
           __unaligned, the compiler generates the additional
           code necessary to copy or store the data without causing
           alignment errors. It is best to avoid use of misaligned
           data altogether, but in some cases the usage may be
           justified by the need to access packed structures, or
           by other considerations.

           Here is an example of a typical use of __unaligned:

           typedef enum {int_kind, float_kind, double_kind} kind;
           void foo(void *ptr, kind k) {
               switch (k) {
               case int_kind:
                   printf("%d", *(__unaligned int *)ptr);
                   break;
               case float_kind:
                   printf("%f", *(__unaligned float *)ptr);
                   break;
               case double_kind:
                   printf("%f", *(__unaligned double *)ptr);
                   break;
               }
           }

     2.2.14 Linkage Specifications

           Specifying linkage other than "C++" or "C" generates a
           compile-time error.

           In object files, the compiler decorates with type
           information the names of functions with C++ linkage. This
           permits overloading and provides rudimentary type checking
           across compilation units. The type-encoding algorithm used
           is similar to that given in 7.2.1c of The Annotated C++
           Reference Manual.

     2.2.15 Temporary Objects

           The compiler creates temporary objects for class objects
           with constructors:

           o  An object is returned from a function.

           o  An object is passed as an argument.

           o  An object is created using the constructor notation.

     2-32 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                              2.2 Implementation Extensions and Features

              o  A user-defined conversion is implicitly used.

              Variations in the compiler generation of such temporary
              objects can adversely affect their reliability in user
              programs. The compiler avoids introducing a temporary
              object whenever it discovers that the temporary object is
              not needed for accurate compilation. Therefore, you should
              modify or write your programs so as not to depend on side
              effects in the constructors or destructors of temporary
              objects.

        2.2.15.1 Nonconstant Reference Initialization with a Temporary
                 Object

              If your program tries to initialize a nonconstant
              reference with a temporary object, the compiler generates
              a warning. For example:

              struct A {
                A(int);
              };
              void f(A& ar);

              void g() {
                f(5);  // warning!!
              }

        2.2.16 Exception Handling

              The compiler optimizes the implementation of exception
              handling for normal execution, as follows:

              o  Applications that do not have exception handlers incur
                 no overhead.

              o  Applications with handlers that run without causing
                 exceptions incur only slight overhead:

                 -  The size of an executable image increases slightly
                    because of the tables that describe the handlers.

                 -  Code optimization is less aggressive in the presence
                    of handlers.

              o  As much as possible, overhead for exceptions is
                 incurred when throwing an exception. Entering or
                 leaving a try block incurs no overhead.

                                          Compaq C++ Implementation 2-33

 



     Compaq C++ Implementation
     2.2 Implementation Extensions and Features

           In Compaq C++, a procedure with handlers has no intrinsic
           overhead. For example, procedures with handlers do not
           have frame pointers or additional register usage.

           Some procedures without explicit handlers may have
           implicit handlers. The compiler creates a handler for
           each automatic object that has a destructor. The compiler
           also creates handlers for constructors that initialize
           subobjects that have destructors. In such a constructor,
           the compiler creates a handler for each member with a
           destructor, and a handler for each base class with a
           destructor.

           The -nocleanup option suppresses generation of such
           implicit handlers, which results in an executable file
           that is slightly smaller. You should use this option for
           programs that do not use exception handling or that do not
           require destruction of automatic objects during exception
           processing.

           Exception specifications in function prototypes that
           conflict with function definitions are illegal. Beware
           of such conflicting exception specifications, particularly
           if you have exception specifications in prototypes that
           are in header files accessible to other programs.

     2.2.17 File Inclusion

           The #include directive inserts external text into the
           source stream delivered to the compiler. Programmers
           often use this directive to include global definitions for
           use with Compaq C++ functions and macros in the program
           stream.

           The #include directive has the following search path
           semantics:

           o  Quoted path names:

              1. Quoted path names are first searched for in the
                 directory that contains the file with the #include
                 directive.

              2. If the file is not found, the search continues to
                 the list of directories specified on the command
                 line with the -I directoryname compiler option, in
                 order.

     2-34 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                              2.2 Implementation Extensions and Features

                 3. If the file is still not found, the compiler
                    searches the /usr/include/cxx, /usr/include/cxx_cname,
                    and /usr/include directories, then in the /usr/include/cxx_
                    cname directory.

              o  Angle-bracketed files are searched for in the list of
                 directories specified on the command line, then in the
                 /usr/include/cxx, /usr/include/cxx_cname, and finally
                 in the /usr/include directory.

              o  By default, the compiler searches for include files
                 in the standard directories /usr/include/cxx,
                 /usr/include/cxx_cname, and in the /usr/include
                 directory in the order described above. If you want
                 to override this behavior and force the compiler to
                 search only in directories specified on the command
                 line, use the -I open without any arguments. (See the
                 description of the -I option in the cxx.1 reference
                 page.)

        2.2.18 Inheritance and Header Files

              Inheritance means that one object or file derives some
              of its contents by virtual copying from another object or
              file. In the case of C++ header files, for example, one
              header file includes another and then replaces or adds
              something.

              If the inheriting header file and the base header file
              have different names, inheritance is straightforward:
              simply write #include "base" in the inheriting file.

              However, if it is necessary to give the inheriting file
              the same name as the base file, inheritance is less
              straightforward.

              For example, suppose an application program uses
              the system header file sys/signal.h, but the ver-
              sion of /usr/include/sys/signal.h on a particular
              system does not do what the program expects. You
              could define a local version, perhaps with the name
              /usr/local/include/sys/signal.h, to override or add to
              the one supplied by the system. Using the -I option for
              compilation, you could then write a file sys/signal.h
              that does what the application program expects. But if you
              try to include the standard sys/signal.h in your version

                                          Compaq C++ Implementation 2-35

 



     Compaq C++ Implementation
     2.2 Implementation Extensions and Features

           using #include <sys/signal.h>, the result is an infinite
           recursion and a fatal compilation error.

           Specifying #include </usr/include/sys/signal.h> would
           include the correct file, but that technique makes
           maintenance difficult because it assumes that the location
           of the system header files will never change.

           You should therefore use the #include_next directive,
           which means "Include the next file with this name." This
           directive works like #include but starts searching the
           list of header file directories after the directory in
           which the current file was found.

           Suppose you specify -I /usr/local/include, and the list
           of directories to search also includes /usr/include.
           Then suppose that both directories contain a file named
           sys/signal.h. Specifying #include <sys/signal.h> finds
           your version of the file in the /usr/local/include direc-
           tory. If that file contains #include_next <sys/signal.h>,
           the search starts after that directory and finds the
           correct system standard file in /usr/include.

     2.2.19 Nested Enums and Overloading

           The C++ language allows programmers to give distinct
           functions the same name, and uses either overloading or
           class scope to differentiate the functions:

           void f(int);
           void f(int *);
           class C {void f(int);};
           class D {void f(int);};

           All compilers, including Compaq C++, use name mangling
           to assign unique names to these functions. These unique
           mangled names allow the linker to tell the overloaded
           functions apart.

           The compiler forms a mangled name by appending an encoding
           of the parameter types of the function to the function's
           name. If the function is a member function, the compiler
           qualifies the function name by the names of the classes
           within which it is nested.

     2-36 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                              2.2 Implementation Extensions and Features

              For example, for the function declarations at the
              beginning of this section, the compiler generates the
              mangled names f__Xi, f__XPi, f__1CXi,  and f__1DXi
              respectively. In these names, i means a parameter type
              was int, P means "pointer to", 1C means nested within
              class C, and 1D means nested within class D.

              There is a flaw in the name mangling scheme used by the
              compiler that can cause problems in uncommon cases. The
              compiler fails to note in the encoding of an enum type in
              a mangled name whether the enum type was nested within a
              class. This can cause distinct overloaded functions to be
              assigned the same mangled name:

              #include <stdlib.h>
              struct C1 {enum E {red, blue};};
              struct C2 {enum E {red, blue};};

              extern "C" int printf(const char *, ...);
              void f(C1::E x) {printf("f(C1::E)\n");}
              void f(C2::E x) {printf("f(C2::E)\n");}

              int main()
              {
                  f(C1::red);
                  f(C2::red);
                  return EXIT_SUCCESS;
              }

              In the previous example, the two overloaded functions
              named f differ only in that one takes an argument of enum
              type C1::E and the other takes an argument of enum type
              C2::E. Because the compiler fails to include the names
              of the classes containing the enum type in the mangled
              name, both functions have mangled names that indicate the
              argument type is just E. This causes both functions to
              receive the same mangled name.

              In some cases, the compiler detects this problem at
              compile-time and issues a message that both functions
              have the same type-safe linkage. In other cases, the
              compiler issues no message, but the linker complains about
              duplicate symbol definitions.


                                          Compaq C++ Implementation 2-37

 



     Compaq C++ Implementation
     2.2 Implementation Extensions and Features

           If you encounter such problems, you can recompile using
           the
           -distinguish_nested_enums command line switch. This causes
           the compiler to include the name of class or classes that
           an enum is nested within when forming a mangled name. This
           eliminates cases where different functions receive the
           same mangled name.

           Because the -distinguish_nested_enums command-line switch
           changes the external symbols the compiler produces, you
           can get undefined symbol messages from the linker if some
           modules are compiled with -distinguish_nested_enums
           and some are compiled without it. Because of this,
           -distinguish_nested_enums might make it difficult to link
           against old object files or libraries of code.

           If you compile your code with -distinguish_nested_enums
           and try to link against a library that was compiled
           without the -distinguish_nested_enums command line switch,
           you will receive an undefined symbol message from the
           linker if you attempt to call a function from the library
           that takes an argument of a nested enum type. The mangled
           name of the function in the library will be different from
           the mangled name your code is using to call the function.

     2.2.20 Guiding Declarations

           A guiding declaration is a function declaration that
           matches a function template, does not introduce a function
           definition (implies an instantiation of the template
           body and not a explicit specialization), and is subject
           to different argument matching rules than those that
           apply to the template itself-therefore affecting overload
           resolution. Consider the following example:

           template <class T> void f(T) {
             printf("In template f\n");
           }

           void f(int);

           int main() {
             f(0);      // invokes non-template f
             f<>(0.0);  // invokes template f
             return 0;
           }

     2-38 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                              2.2 Implementation Extensions and Features

              void f(int) {
                printf("In non-template f\n");
              }

              Because there is no concept of guiding declaration in
              the current version of the C++ International Standard,
              the function f in the example is not regarded as an
              instance of function template f. Furthermore, there are
              two functions named f that take an int parameter. A call
              of f(0) would invoke the former, while a call of f<>(0)
              would be required to invoke the latter.

        2.3 Run-time Type Identification

              The compiler emits type information for Run-Time Type
              Identification (RTTI) in the object module with the
              virtual function table, for classes that have virtual
              function tables.

              You can specify the -[no]rtti option to enable or
              disable support for RTTI (runtime type identification)
              features: dynamic_cast and typeid. Disabling runtime type
              identification can also save space in your object file
              because static information to describe polymorphic C++
              types is not generated. The default is to enable runtime
              type information features and generate static information
              in the object file.

              Specifying -nortti does not disable exception handling.

              The type information for the class may include references
              to the type information for each base class and informa-
              tion on how to convert to each. The typeinfo references
              are mangled in the form __T__<class>.

        2.4 Implementation of Polymorphism During Object Construction

              During object construction, the compiler allocates
              intermediate virtual function tables on the constructor's
              stack for each virtual base class. If the object currently
              under construction is a subobject of a more derived
              object, the compiler uses the local virtual function
              tables. Each table's Run-Time Type Identification contains
              the offset to convert successfully from the virtual base
              class to the object being constructed. This offset is
              known at runtime through the object's virtual base table

                                          Compaq C++ Implementation 2-39

 



     Compaq C++ Implementation
     2.4 Implementation of Polymorphism During Object Construction

           and can be assigned into the corresponding local virtual
           function table's RTTI information. Virtual function calls
           that occur during construction can then correctly adjust
           the "this" pointer.

           Compiler-generated thunks to this pointers ("interludes")
           take advantage of the RTTI's offset:

               void __INTER__1S_funcname_2Vn_type(Vn *this)
               {
                   this = this + this.vptr[RTTI_INDEX].offset;
                   funcname(this);
               }

           Again, this offset represents the proper delta to convert
           from a virtual base class to the more derived class that
           overrode the virtual function declared within the virtual
           base class. For example:

               struct V {
                   V() { f(); }
                   virtual void f() { g(); }
                   virtual void g() { printf("V::g, this = %x\n", this); }
               };

               struct S : virtual V {
                   S() { f(); }
                   virtual void g() { printf("S::g, this = %x\n", this); }
               };

               struct D : virtual S {
                   D() { f(); }
                   virtual void g() { printf("D::g, this = %x\n", this); }
               };

               S's constructor would be rewritten as follows:

               S()
               {
                   if (most_derived) {
                       Assign btbls;
                       Call virtual base class constructors;
                   }

                   if (!most_derived) {

     2-40 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
           2.4 Implementation of Polymorphism During Object Construction

                              /* For each virtual base generate the following code */
                              /* Vn represents a particular virtual base class */

                              int *__local_vtbl__2Vn1S[Vn_vtbl_compile_time_known_size];

                              memmove(__local_vtbl__2Vn1S, __vtbl__2Vn1S,
                              Vn_vtbl_compile_time_known_size);

                              __local_vtbl__2Vn1S[RTTI_INDEX].offset = S.bptr[Vn];

                              Vn.vptr = &__local_vtbl__2Vn1S;

                      } else {
                              Assign vtbls like we do today;
                      }

                      Call non-virtual direct base class constructors

                      /* body of S's constructor */

                      if (!most_derived) {
                          Reassign vtbls like we do today;
                      }
                  }

        2.5 Message Control Options

              The compiler supports the following message control
              options. The options apply only to discretionary, warning,
              and informational messages. The tag variable can be the
              keyword all, a tag obtained from -msg_display_tag, or a
              number obtained from -msg_display_number. The tag variable
              is preferred.

              -msg_inform tag,...
              Reduce message(s) severity to informational.

              -msg_warn tag,...
              Reduce message(s) severity to warning.

              -msg_error tag,...
              Increase message(s) severity to error

              -msg_enable tag,...
              Enable specific messages that would normally not be
              issued. You can also use this option to re-enable messages
              disabled with -msg_disable.

                                          Compaq C++ Implementation 2-41

 



     Compaq C++ Implementation
     2.5 Message Control Options

           -msg_disable tag,...
           Disable message. Can be used for any nonerror message.

           -msg_quiet
           Be more like Version 5.n error reporting. Fewer messages
           are issued using this option. This is the default in arm
           mode (-std arm). All other modes default to -nomsg_quiet.

           You can use the msg_enable option with this option
           to enable specific messages normally disabled using
           -msg_quiet.

     2.6 Message Information Options

           The compiler supports the following message information
           options. Both are disabled by default.

              ________________________Note ________________________

              "D" (meaning discretionary) indicates that the
              severity of the message can be controlled from the
              command line. The message number can be used as
              the tag in the message control options described
              in Section 2.5. If "D" is not displayed with the
              message number, any attempt to control the message
              is ignored.

              _____________________________________________________

           -msg_display_tag
           A more descriptive tag is issued at the end of each
           message issued. "D" indicates the severity of the message
           can be controlled from the command line. The tag displayed
           can be used as the tag in the message control options
           described in Section 2.5.

           Example:

           cxx -msg_display_tag t.cxx
           cxx: ... is nonstandard ("int" assumed) (D:nonstd_implicit_int)
           cxx -msg_disable nonstd_implicit_int  t.cxx




     2-42 Compaq C++ Implementation

 



                                               Compaq C++ Implementation
                                         2.6 Message Information Options

              Note that you can change the severity of a diagnostic
              message if the message is discretionary. For example,
              -msg_inform nonstd_implicit_int changes the severity to an
              informational. These options interact with -w0, -w1, and
              -w2.

              -msg_display_number
              The error number is displayed at the beginning of each
              message issued.

              Example:

              cxx -msg_display_number t.cxx
              cxx: Warning: t.cxx, line 1: #117-D non-void function "f" ...
              cxx -msg_disable 117 t.cxx






























                                          Compaq C++ Implementation 2-43

 









                                                                       3
        ________________________________________________________________

                                         Compaq C++ Language Environment



              This chapter describes the guidelines and procedures
              for customizing your language environment. It includes
              sections on changing your C header files to work with
              C++, using 32-bit pointers, organizing your C++ files,
              interfacing to other programming languages, and designing
              upwardly compatible C++ classes.

        3.1 Using Existing C Header Files

              C header files that already conform to ANSI C standards
              must be slightly modified for use by Compaq C++ programs.
              In particular, be sure to address the following issues:

              o  Enable the proper linkage for each language.

              o  Ensure that C++ keywords are not used as identifiers.

              o  Reconcile any name space and scoping differences.

              The following sections provide details on how to properly
              modify your header files.

        3.1.1 Providing C and C++ Linkage

              To modify header files, use conditional compilation and
              the extern specifier.

              When programming header files to be used for both C and
              C++ programs, use the following convention for predefined
              macros. The system header files also provide an example of
              correct usage of the predefined macros.




                                     Compaq C++ Language Environment 3-1

 



     Compaq C++ Language Environment
     3.1 Using Existing C Header Files

           #if defined __cplusplus
               /* If the functions in this header have C linkage, this
                * will specify linkage for all C++ language compilers.
                */
               extern "C" {
           #endif
           extern int func1(int);
           extern int func2(int);
              .
              .
              .
           #if defined __cplusplus
               }   /* matches the linkage specification at the beginning. */
           #endif

           See The C++ Programming Language, 3rd Edition for more
           information on linkage specifications.

     3.1.2 Resolving C++ Keyword Conflicts

           If your program uses any of the following C++ language
           keywords as identifiers, you must replace them with
           nonconflicting identifiers:

           asm         bool        catch             class
           const_cast  delete      dynamic_cast      explicit
           export      false       friend            inline
           mutable     namespace   new               operator
           private     protected   public            reinterpret_cast
           static_     template    this              throw
           cast
           true        try         typeid            typename
           virtual     wchar_t

     3.2 Using Compaq C++ with Other Languages

           The following are suggestions regarding the use of Compaq
           C++ with other languages:

           o  Passing entities, such as classes, by reference is
              safest.

           o  You cannot invoke class member functions from within
              any language other than C++.

     3-2 Compaq C++ Language Environment

 



                                         Compaq C++ Language Environment
                               3.2 Using Compaq C++ with Other Languages

              o  Every C++ routine that will be called from the other
                 language should be declared in C++ with extern "C". For
                 example:

                 extern "C"
                    int myroutine(int, float);

                 The extern "C" will cause the routine to have an
                 unmangled name, so that you can refer to it as
                 myroutine from a language such as Cobol or Fortran.
                 Otherwise the routine's link name will be mangled into
                 something like myrout__Xif.

              o  If the main routine is defined in the other language,
                 you will probably need to use the other language's
                 command-line interface to perform your link step. To
                 include the appropriate C++ libraries and startup file,
                 you will need to add some arguments to the command
                 line. The most reliable way to determine what is needed
                 is to test with a small C++ program as follows:

                 cxx -c tiny.cxx
                 cxx -v tiny.o

                 The -v option causes the compiler to display the
                 command line when it links tiny.o.

                 The following is an example of the resulting display
                 on Compaq Tru64 UNIX Version 4.0 systems or higher and
                 Linux Alpha:

                 /usr/lib/cmplrs/cc/ld -g0 -O1 -call_shared /usr/lib/cmplrs/cc/crt0.o \
                         /usr/lib/cmplrs/cxx/_main.o tiny.o -lcxxstd -lcxx -lexc -lc

                 In this example, for your link step involving a
                 language other than C++, you would add the following to
                 the command line:

                 /usr/lib/cmplrs/cxx/_main.o -lcxxstd -lcxx -lexc

                 If your language uses the linker directly, you would
                 also need to add the following:

                 /usr/lib/cmplrs/cc/crt0.o  . . .  -lc

                                     Compaq C++ Language Environment 3-3

 



     Compaq C++ Language Environment
     3.3 Linkage to Non-C++ Code and Data

     3.3 Linkage to Non-C++ Code and Data

           With linkage specifications, you can both import code and
           data written in other languages into a Compaq C++ program
           and export Compaq C++ code and data for use with other
           languages. See The C++ Programming Language, 3rd Edition
           for details on the extern "C" declaration.

     3.4 How to Organize Your C++ Code

           This section explains the best way for Compaq C++ users
           to organize an application into files; it assumes that
           you are using automatic instantiation to instantiate any
           template classes and functions.

     3.4.1 Code That Does Not Use Templates

           The general rule is to place declarations in header
           files and place definitions in library source files. The
           following items belong in header files:

           o  Class declarations

           o  Global function declarations

           o  Global data declarations

           o  Inline function definitions

           The following items belong in library source files:

           o  Static member data definitions

           o  Out-of-line member function definitions

           o  Out-of-line global function definitions

           o  Global data definitions

           Header files should be directly included by modules that
           need them. Because several modules may include the same
           header file, a header file must not contain definitions
           that would generate multiply defined symbols when all the
           modules are linked together.

           Library source files should be compiled individually and
           then linked into your application. Because each library
           source file is compiled only once, the definitions it
           contains will exist in only one object module and multiply
           defined symbols are thus avoided.

     3-4 Compaq C++ Language Environment

 



                                         Compaq C++ Language Environment
                                       3.4 How to Organize Your C++ Code

              For example, to create a class called "array" you would
              create the following two files:

              Header file, array.h:

              // array.h
              #ifndef ARRAY_H
              #define ARRAY_H

              class array {
              private:
                      int curr_size;
                      static int max_array_size;
              public:
                      array() :curr_size(0) {;}
                      array(int);
              };

              #endif

              Library source file, array.cxx:

              // array.cxx
              #include "array.h"

              int array::max_array_size = 256;

              array::array(int size) :  curr_size(size) {  . . . ;  }

              You would then compile the array.cxx library source file
              using the following command:

              cxx array.cxx

              The resulting object file could either be linked directly
              into your application or placed in a library (see
              Section 3.4.3).

              Note that the header file uses header guards, which is a
              technique to prevent multiple inclusion of the same header
              file.




                                     Compaq C++ Language Environment 3-5

 



     Compaq C++ Language Environment
     3.4 How to Organize Your C++ Code

     3.4.2 Code That Uses Templates

           With the widespread use of templates in C++, determining
           the proper place to put declarations and definitions
           becomes more complicated.

           The general rule is to place template declarations and
           definitions in header files, and to place specializations
           in library source files.

           Thus, the following items belong in template declaration
           files:

           o  Declarations of global function templates

           o  Declarations of class templates

           o  Declarations of global function template specializa-
              tions

           o  Declarations of class template specializations

           The following items can be placed either in the header
           file with the corresponding template declaration or in
           a separate header file that can be implicitly included
           when needed. This file has the same basename as the
           corresponding declaration header file, with a suffix
           that is found by implicit inclusion. For example, if
           the declaration is in the header file inc1.h, these
           corresponding definitions could be in file inc1.cxx.

           o  Definitions of out-of-line global function templates

           o  Definitions of static member data of class templates

           o  Definitions of out-of-line member functions of class
              templates

           The following must be placed in library source files to
           prevent multiple definition errors:

           o  Definitions of global function template specializations

           o  Definitions of static member data specializations of
              class templates

           o  Definitions of out-of-line class member function
              specializations

     3-6 Compaq C++ Language Environment

 



                                         Compaq C++ Language Environment
                                       3.4 How to Organize Your C++ Code

              These guidelines also apply to nontemplate nested classes
              inside of template classes.

                ________________________Note  ________________________

                Do not place definitions of nontemplate class
                members, nontemplate functions, or global data
                within template header files; these must be placed
                in library source files.

                _____________________________________________________

              All these header files should use header guards, to
              ensure that they are not included more that once either
              explicitly or by implicit inclusion.

              For example, the array class from Section 3.4.1, modified
              to use templates, could now look as follows:

              Template declaration file array.h:

               // array.h

               #ifndef ARRAY_H
               #define ARRAY_H

               template <class T>
               class array {
               private:
                       int curr_size;
                       static int max_array_size;
               public:
                       array() :curr_size(0) {;}
                       array(T);
               };

               #endif

              Template definition file array.cxx:

               // array.cxx
               template <class T>
               int array<T>::max_array_size = 256;

               template <class T>
               array<T>::array(int size) :  curr_size(size) { ; }

                                     Compaq C++ Language Environment 3-7

 



     Compaq C++ Language Environment
     3.4 How to Organize Your C++ Code

           You would then create, as follows, the source file
           myprog.cxx that uses the array class:

            // myprog.cxx

            #include <array.h>

            main() {
                    array<int> ai;

                    // ...
            }

     3.4.3 Creating Libraries

           Libraries are useful for organizing the sources within
           your application as well as for providing a set of
           routines for other applications to use. Libraries can
           be either object libraries or shareable libraries. Use
           an object library when you want the library code to be
           contained within an application's image; use shareable
           libraries when you want multiple applications to share the
           same library code.

           Creating a library from nontemplate code is straight-
           forward: you simply compile each library source file and
           place the resulting object file in your library.

           Creating a library from template code requires that you
           explicitly request the instantiations that you want to
           provide in your library. Alternatively, if automatic
           template instantiation has been used, the instantiation
           object files in the repository can be placed in your
           library. See Chapter 7 for details.

           If you make your library available to other users,
           you must also supply the corresponding declarations
           and definitions that are needed at compile time. For
           nontemplate interfaces, you must supply the header files
           that declare your classes, functions, and global data.
           For template interfaces, you must provide your template
           declaration files as well as your template definition
           files.

           For more information on creating libraries, see the ar(1)
           reference page and the loader(1) reference page.

     3-8 Compaq C++ Language Environment

 



                                         Compaq C++ Language Environment
                                       3.5 Using 32-bit Pointers (xtaso)

        3.5 Using 32-bit Pointers (xtaso)

              Normally, Compaq C++ uses 64 bits for all pointers in
              generated code. The Extended Truncated Address Support
              Option (xtaso), and other #pragma directives and compiler
              options, let code with 32-bit pointers coexist within this
              64-bit operating system environment. Such a capability can
              be useful when the data layout used for pointers must be
              compatible with the layout on a 32-bit processor.

              The 32-bit pointer data type lets application developers
              minimize the amount of memory used by dynamically
              allocated pointers. Using 32-bit pointers can sometimes
              improve performance if the volume of data occupied by
              pointers is large. In certain instances, the capability
              can be helpful in porting applications that contain
              assumptions about pointer sizes, although the following
              precautions apply:

              o  Mixing 32-bit and 64-bit pointers may introduce new
                 porting problems if the data structures in system
                 libraries still use 64-bit pointers.

              o  Anyone who supplies object modules (or libraries)
                 compiled with 32-bit pointers thereby restricts users
                 of those objects to the use of 32-bit pointers and
                 requires those users to be aware of the difficulties of
                 using 32-bit pointers in a mixed 32/64-bit environment.

              To use 32-bit pointers, you must use a combination of
              #pragma preprocessor directives and command-line compiler
              options. These #pragmas are described in Section 2.1.1 and
              are summarized in the following table:

              __________________________________________________________
              #pragma_Directive___Description___________________________

              pointer_size        Controls the pointer size of all
                                  pointers except virtual function and
                                  virtual base pointers in a C++ class
                                  object.

                                  Has an effect only if you specify one
                                  or more of the pointer-size compiler
                                  options.

                                     Compaq C++ Language Environment 3-9

 



     Compaq C++ Language Environment
     3.5 Using 32-bit Pointers (xtaso)

           __________________________________________________________
           #pragma_Directive___Description___________________________

           required_pointer_   Has the same effect as #pragma
           size                pointer_size but is always enabled,
                               whether or not you specify any
                               pointer-size compiler options.

           required_vptr_size  Controls the size of virtual function
                               and virtual base pointers in a C++
                               class object.

                               Always enabled, whether or not you
                               specify any pointer size compiler
           ____________________options.______________________________

           The pointer size compiler options are -xtaso, -xtaso_
           short, -vptr_size, and -vptr_size_short. Whenever any
           of these options are specified on the command line, the
           following actions occur:

           o  #pragma pointer_size is enabled. This pragma has an
              effect only if you specify a pointer size compiler
              option on the command line.

           o  The cxx command automatically passes the -taso option
              to the linker. This option causes the linker to load
              the executable in the lower 31-bit addressable virtual
              address range and causes memory allocations to be made
              from the same virtual address page. Thus, your program
              is limited to a 31-bit virtual address space whenever
              you use any of the pointer-size compiler options.

           Individually, the pointer size options have following
           effects:

           __________________________________________________________
           Compiler_Option___Description_____________________________

           -xtaso            Sets the default pointer size of the
                             compilation unit to 64 bits (for all
                             pointers except virtual function and
                             virtual base pointers in a C++ class
                             object). This is the normal default
                             unless overridden by -xtaso_short.

     3-10 Compaq C++ Language Environment

 



                                         Compaq C++ Language Environment
                                       3.5 Using 32-bit Pointers (xtaso)

              __________________________________________________________
              Compiler_Option___Description_____________________________

              -xtaso_short      Sets the default pointer size of the
                                compilation unit to 32 bits (for all
                                pointers except virtual function and
                                virtual base pointers in a C++ class
                                object).

              -vptr_size        Makes 64 bits the default size of
                                virtual function and virtual base
                                pointers in a C++ class object. This
                                is the normal default unless overridden
                                by -vptr_size_short.

              -vptr_size_short  Makes 32 bits the default size of
                                virtual function and virtual base
              __________________pointers_in_a_C++_class_object._________

              You cannot reset the size of the this pointer. The this
              pointer always remains the system default pointer size,
              which is 64 bits.

              When using these #pragma directives and compiler options,
              you must take particular care if you call functions in
              any library compiled with different pointer sizes. The
              approaches that you can use to mix 32- and 64-bit pointers
              are as follows:

              1. Make 64 bits the default pointer size and use 32-bit
                 pointers for particular declarations.

              2. Make 32 bits the default pointer size.

              The second approach generally is more difficult because
              of problems in combining your code with code that expects
              64-bit pointers. The sections that follow discuss these
              approaches in more detail.

              Approach 1: Making 64 bits the default pointer size

              With this approach, most pointers in your application are
              64 bits, and 32 bits are used for selected pointers. To
              use this approach, you must compile with -xtaso to enable
              #pragma pointer_size and cause the cxx command to pass
              -taso to the linker.

                                    Compaq C++ Language Environment 3-11

 



     Compaq C++ Language Environment
     3.5 Using 32-bit Pointers (xtaso)

           You use #pragma pointer_size, #pragma required_pointer_
           size, and #pragma required_vptr_size to control the
           pointer sizes for particular declarations. For example,
           to save space in an object, you can declare a class as
           follows:

           #pragma pointer_size save
           #pragma required_vptr_size save
           #pragma pointer_size short
           #pragma required_vptr_size long
                   class Table_Node {
                           char *table;    // 32-bit pointers
                           Table_Node *next;
                           Table_Node *(Table_Node::*search)(char *);
                                           // pointer to member has
                                           // 2 32-bit fields
                   public:
           #pragma pointer_size long
                           void insert_node(char *);
                           Table_Node *extract_node(char *);
                           Table_Node *search_forward(char *);
                           Table_Node *search_backward(char *);
                   };
           #pragma pointer_size restore
           #pragma required_vptr_size restore

           With this approach, you must take care to specify the
           pointer size #pragma directives after any #include
           directives, so that header files that assume 64-bit
           pointer sizes are not affected.

           Approach 2: Making 32 bits the default pointer size

           To use this approach, compile using the -xtaso_short and
           -vptr_size_short options on the cxx command. With this
           approach, the default pointer size is 32 bits; you must
           take care when interfacing to code that expects 64-bit
           pointers.

           Specifically, you must protect header files so that the
           pointer size assumptions made in compiling the header
           file are the same as those made when the associated code
           was compiled. None of the system header files, including
           those for the standard C library, are protected. Thus,
           most programs do not work correctly when compiled with the

     3-12 Compaq C++ Language Environment

 



                                         Compaq C++ Language Environment
                                       3.5 Using 32-bit Pointers (xtaso)

              -xtaso_short option unless you protect the system header
              files and any other header files associated with code
              that assumes 64-bit pointers. For more information, see
              Section 2.1.2.

              No matter which approach you use, you must take particular
              care when passing any data that contains pointers (for
              example, an array of pointers or a struct that contains
              pointers) to be sure that the pointer size is the same as
              expected by the called function.

              Pointer expressions are normal sized regardless of the
              currect pointer size. For example:

              int x;
              int *px;
              int X::*pXk;

              sizeof(int*)=4
              sizeof(px)=4
              sizeof(&x)=8

              sizeof(int X::*)=8
              sizeof(pXk)=8
              sizeof(&X::k)=16

              Compaq C++ does not permit overloading based on pointer
              sizes. To minimize problems, you should declare functions,
              including member functions with long pointer sizes. During
              calls to such functions, the compiler promotes short
              pointers to long pointers.

        3.6 Hints for Designing Upwardly Compatible C++ Classes

              If you produce a library of C++ classes and expect to
              release future revisions of your library, you should
              consider the upward compatibility of your library. Having
              your library upwardly compatible makes upgrading to higher
              versions of your library easier for users. And if you
              design your library properly from the start, you can
              accomplish upward compatibility with minimal development
              costs.

              The levels of compatibility discussed in this section are
              as follows:

              1. Source compatibility

                                    Compaq C++ Language Environment 3-13

 



     Compaq C++ Language Environment
     3.6 Hints for Designing Upwardly Compatible C++ Classes

           2. Link compatibility

           3. Run or binary compatibility

           The format in which your library ships determines the
           levels of compatibility that apply:

           __________________________________________________________
           If you ship your library
           in_._._.__________________The_following_apply:____________

           Source format             Source compatibility only

           Object format             Source and link compatibility

           Shareable_library_format__All_three_kinds_of_compatibility

           If you break compatibility between releases, you should at
           least document the incompatible changes and provide hints
           for upgrading between releases.

     3.6.1 Source Compatibility

           Achieving source compatibility means that users of your
           library will not have to make any source code changes
           when they upgrade to your new library release. Their
           applications will compile cleanly against your updated
           header files and will have the same run-time behavior as
           with your previous release.

           To maintain source compatibility, you must ensure that
           existing functions continue to have the same semantics
           from the user's standpoint. In general, you can make
           the following changes to your library and still maintain
           source compatibility:

           o  Add new data members and classes.

           o  Add new virtual and nonvirtual functions (as long as
              they do not change overload resolution of existing
              calls).

           o  Loosen protection.

           o  Change inline functions to out-of-line and out-of-line
              functions to inline.

           o  Change the implementation of functions.

     3-14 Compaq C++ Language Environment

 



                                         Compaq C++ Language Environment
                 3.6 Hints for Designing Upwardly Compatible C++ Classes

              o  Add arguments with default values to existing member
                 functions.

        3.6.2 Link Compatibility

              Achieving link compatibility means that users of your
              library can relink an application against your new object
              or shareable library and not be required to recompile
              their sources.

              What can change

              To maintain link compatibility, the internal representa-
              tion of class objects and interfaces must remain constant.
              In general, you can make the following changes to your
              library and still maintain link compatibility:

              o  Change the implementation of an out-of-line function.

              o  Loosen protection.

              o  Add a new nonvirtual member function (as long as
                 it does not change overload resolution for existing
                 calls).

              What cannot change

              Because the user may be linking object modules from
              your previous release with object modules from your new
              release, the layout and size of class objects must be
              consistent between releases. Any user-visible interfaces
              must also be unchanged; even the seemingly innocent change
              of adding const to an existing function will change the
              mangled name and thus break link compatibility.

              The following are changes that you cannot make in your
              library:

              o  Add, move, or delete data members.

              o  Add, move, or delete virtual functions.

              o  Change the signature of virtual and nonvirtual
                 functions.

              o  Remove nonvirtual functions.

              o  Change inline function definitions.

              o  Change functions from out-of-line to inline.

                                    Compaq C++ Language Environment 3-15

 



     Compaq C++ Language Environment
     3.6 Hints for Designing Upwardly Compatible C++ Classes

           Designing Your C++ Classes for Link Compatibility

           Although the changes you are allowed to make in your
           library are severely restricted when you aim for link
           compatibility, you can take steps to prepare for this and
           thereby reduce the restrictions. Compaq suggests using one
           of the following design approaches:

           o  Set aside dummy (reserved-for-future-use) data fields
              and virtual functions within your classes. This assumes
              you can foresee how much your classes will grow and
              change in the future.

           o  Add a level of indirection to hide your virtual
              functions and data fields from the user. This lets
              you add and change data fields and virtual functions
              without affecting the library user; however, there
              may be some disadvantages such as in performance. This
              approach is detailed in Effective C++, Section 34, by
              Scott Meyers.

     3.6.3 Run Compatibility

           Achieving run compatibility means that users of your
           library can run an application against your new shareable
           library and not be required to recompile or relink the
           application.

           This requires that you follow the guidelines for link
           compatibility as well as any operating system guidelines
           for shareable libraries. For example, you need to ensure
           your version identifier is upwardly compatible between
           releases. Refer to the ld reference pages for information
           on creating a shareable library.

     3.6.4 Additional Reading

           The C++ Programming Language, 3rd Edition offers some
           advice on compatibility issues. Another good reference is
           Designing and Coding Reusable C++, Chapter 7, by Martin D.
           Carroll and Margaret E. Ellis.




     3-16 Compaq C++ Language Environment

 









                                                                       4
        ________________________________________________________________

                                                   Porting to Compaq C++



              Compaq C++ implements the International C++ Standard, with
              some differences, as described in the online release notes
              in:

              /usr/lib/cmplrs/cxx/DECCXXnnn.release-notes

              This language differs significantly from The Annotated
              C++ Reference Manual, implemented by the Version 5.n
              compilers. When switching from a Version 5.n compiler,
              you might need to modify your source files, especially if
              you use the default language mode. In addition, language
              changes can affect the run-time behavior of your programs.
              If you want to compile existing source code with minimal
              source changes, compile using the -std arm option. See for
              information on and changes to the Standard Library.

              This chapter describes ways to avoid having the compiler
              reject program code that previously worked with other
              C++ implementations that adhere less strictly to the C++
              language definition. References to applicable portions of
              The C++ Programming Language, 3rd Edition indicate where
              you can find additional help.

        4.1 Compatibility with Other C++ Compilers

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

              o  Run-time type identification (RTTI), with dynamic_cast
                 and the typeid operator (see Section 2.3)

              o  New-style casts (static_cast, reinterpret_cast, and
                 const_cast).

              o  Array new and delete

                                               Porting to Compaq C++ 4-1

 



     Porting to Compaq C++
     4.1 Compatibility with Other C++ Compilers

           For compatibility with previous versions, the compiler
           provides the following language mode options:

           -std ansi
           Specify this option if you want an ANSI C++ compiler that
           supports some commonly used extensions and is somewhat
           less strict than the standard. This is the default
           compiler mode.

           If you want to use ANSI mode but find that the compiler
           generates too many diagnostics in that mode, you can
           use the -msg_quiet option with the -std ansi option. The
           -msg_quiet option relaxes error checking and suppresses
           or reduces the severity of many diagnostics. It also
           suppresses many warnings that are generated in ANSI mode
           but were not issued by Version 5.6. For information on
           message control options, see Message Control Options in
           Chapter 2.

           -std arm
           Specify this option if you want to compile programs
           developed using Version 5.n and want to minimize source
           changes.

           If you usually want your compilations done in this mode
           and don't want to specify -std arm on each cxx command,
           define environment variable DEC_CXX as follows:

                setenv DEC_CXX "-std arm"

           You can place a single vertical bar ("|") within the
           variable. All arguments preceding the bar are evaluated
           before any explicit command-line arguments; all arguments
           following the bar are evaluated afterwards. In the absence
           of a vertical bar, all arguments are evaluated before the
           explicit command-line arguments.

           Specify -v to obtain the definition of DEC_CXX For
           example, assuming the definition of DEC_CXX above, the
           cxx -v command results in the following:

                % cxx -v
                $DEC_CXX contains: -std arm


     4-2 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                              4.1 Compatibility with Other C++ Compilers

              To enhance compatibility with other C++ compilers, Compaq
              C++ supports options that direct the compiler to interpret
              the source program according to certain rules followed by
              other implementations:

              -std cfront
              Specify this option if you want to compile programs
              developed using cfront or a compiler based on cfront.


              -std gnu
              Use this option if you want to compile programs developed
              using the GNU compiler. This option also defines the
              __STD_GNU macro. The following changes in behavior are
              provided for compatibility with the GNU C++ compiler:

              o  These options are enabled by default:

                 -alternative_tokens, -tlocal, and -no_implicit_include

              o  Access control is not enforced for types defined inside
                 a class.

              o  Unrecognized character escape sequences in string
                 literals produce an informational instead of a warning
                 message.

              o  The __inline keyword is enabled and is equivalent to
                 inline.

              o  When overloading, enum types are treated as integral
                 types.

              The following known incompatibilities are not addressed in
              the -std gnu mode:

              o  The compiler strictly enforces the requirement to
                 define functions before they are used. This requirement
                 also applies to built-in functions such as strlen.

              -std ms
              Specify this option if you want the compiler to accept
              additional Microsoft Visual C++ extensions.


                                               Porting to Compaq C++ 4-3

 



     Porting to Compaq C++
     4.1 Compatibility with Other C++ Compilers

           -std strict_ansi
           Specify this option if you want the compiler to enforce
           the ANSI C++ standard strictly but permit some ANSI
           violations that should be errors to be warnings.

           -std strict_ansi_errors
           Specify this option if you want strict_ansi and also want
           errors to be issued for all ANSI violations.

           With either -std ms or -std cfront you might also want to
           specify -msg_quiet to reduce the number of diagnostic
           messages generated. For details, see Message Control
           Options in Chapter 2.

     4.2 Compatibility With Version 5.n Compilers [Tru64]

           This section provides information about differences
           between the current compiler and Version 5.n compilers.

           o  Language differences

           o  Implementation differences

           o  Library differences

           o  Run-Time library differences

     4.2.1 Compiler Version Options [Tru64]

           This release provides the following compiler version
           options:

           -newcxx
           Invokes the Version 6.3 compiler. This is the default.

           -oldcxx
           Invokes a bug fix update to the Version 5.7 compiler.

           The -oldcxx option is provided for cases where the Version
           6.n compiler requires excessive source changes or for
           problems in using that compiler. If extensive source
           changes are required to correct errors, try using the
           -std arm option. For excessive warnings, try the -msg_
           quiet option.

     4-4 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                    4.2 Compatibility With Version 5.n Compilers [Tru64]

              If you want -oldcxx to be the default, define the DEC_CXX
              environment variable as follows:

                   setenv DEC_CXX "-oldcxx"

              Before you can use the -oldcxx option, the optional -
              oldcxx subset must be installed. See the  Compaq C++
              Installation Guide for Tru64 UNIX .

        4.2.2 Language Differences [Tru64]

              Be aware of the following language differences between the
              current compiler and Version 5.n compilers:

              o  The most important language differences result from
                 the implementation of the International C++ Standard
                 in Version 6.n. If you want to compile existing source
                 code with minimal source changes, specify the -std arm
                 option.

              o  Because the current compiler performs more error
                 checking than previous versions, it generates
                 significantly more diagnostic messages. However, you
                 can use the -msg_quiet option to relax error checking
                 and reduce the severity of many diagnostics. See Compaq
                 C++ Implementation.

                 With some option combinations, you might see unwanted
                 diagnostics from system header files. If so, you
                 might obtain better results if you protect your
                 system header files using the script provided in
                 /usr/lib/cmplrs/cxx/protect_system_headers.sh. For
                 more information, see Protecting System Header Files.

              o  The current compiler fixes several class member access
                 bugs in previous versions. Some illegal programs
                 that compiled cleanly with previous versions require
                 modification to compile with the current version.

              o  The following keywords, introduced with the International
                 C++ Standard, are always keywords in all compiler
                 modes:

                 bool, const_cast, explicit, export, false, mutable, dynamic_cast,
                 reinterpret_cast, static_cast, truce, typeid, typename, wchar_t

                                               Porting to Compaq C++ 4-5

 



     Porting to Compaq C++
     4.2 Compatibility With Version 5.n Compilers [Tru64]

              Alternative representation keywords are as follows:

              and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq

           o  Creation of temporaries and their lifetimes vary among
              compiler modes.

           o  Taking the address of a bit field is not allowed in the
              current version.

           o  Macro expansion in pragmas can give different results
              in the current and previous versions.

           o  The following are distinct types in the current
              version; they were the same type in previous versions:

                 typedef void (*PF)();             // Pointer to an extern "C++" function
                 extern "C" typedef void (*PCF)(); // Pointer to an extern "C" function
                 void f(PF);
                 void f(PCF);

           o  The current version does not allow converting a pointer
              to member from a derived class to a virtual base class.

           o  Calling a nonstatic member function through a null
              pointer is undefined behavior. Certain cases that used
              to run without errors in previous versions no longer
              run in the current version. For example:

                   #include <iostream.h>

                   struct A {
                       int a;
                   };

                   struct D : public virtual A
                   {
                       A* toA(){ return (A*) this; }
                   };

                   main ()
                   {
                       D* d = NULL;
                       A* ad = d->toA();  // will seg fault
                       if (ad==NULL) cout << "ok";
                   }

     4-6 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                    4.2 Compatibility With Version 5.n Compilers [Tru64]

              o  In the current version, bool is a built in type. In
                 previous versions, it is user defined, typically as
                 int in system header files. Mangling therefore differs
                 between the current and previous versions.

                 In the current version, the size of bool is 1. In
                 previous versions, bool is user defined, typically
                 as int with a size of 4.

                 In the current version, the size of a boolean
                 expression (sizeof(a && b)) is 1. In previous versions,
                 the size is 4, independent of the size of bool.

              o  The current version does not cause pragmas to become
                 effective within function bodies when scanning template
                 definitions.

              o  The current version does not permit dropping qualifiers
                 on pointer assignments. For example, the following is
                 not permitted:

                      volatile int *vptr;  int *ptr=vptr;

              o  The current version does not allow the "virtual"
                 storage class modifier to be used with member function
                 definitions outside a class.

              o  The current version does not allow declaration of
                 pointers to members of type void. For example, the
                 following is not allowed:

                 typedef void Z::* any_ptom;

        4.2.3 Implementation Differences [Tru64]

              Users should be aware of the following implementation
              differences between the current and previous versions of
              the compiler:

              o  The automatic template instantiation model has
                 been redesigned for the current version. See Using
                 Templates.

              o  The current version does not support the -show
                 statistics option implemented in Version 5.7.

                                               Porting to Compaq C++ 4-7

 



     Porting to Compaq C++
     4.2 Compatibility With Version 5.n Compilers [Tru64]

           o  The current version drops qualifiers on parameters
              when determining the function type, as dictated by
              the International C++ Standard. For instance, in the
              following example, the function declarations are the
              same function.

                   f(const int p1);
                   f(int p1);

              For compatibility with previous versions, if qualifiers
              are included in function declarations, they are also
              included in the mangled name.

           o  The current and previous versions differ in inter-
              preting undefined behavior, as when incrementing takes
              effect in this example:

                   f(i++, i++);

           o  The current version cannot handle a #pragma define_
              template that spans multiple lines without the
              backslash ( \ ) delimiter. Version 5.6 can handle this
              without problems.

           o  The current version displays #line number in -E output.
              The previous version displays #number.

           o  After encountering an illegal multibyte character
              sequence, the current version issues a warning
              diagnostic and continues processing. The previous
              version issues an error and stops processing.

     4.2.4 Library Differences [Tru64]

           Aspects of memory allocation and deallocation have
           changed. For detailed information, see

     4.3 Using Classes

           This section discusses porting issues pertaining to C++
           classes.




     4-8 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                                                       4.3 Using Classes

        4.3.1 Friend Declarations

              When making friend declarations, use the elaborated form
              of type specifier. The following code fragment implements
              the legal and comments out the illegal friend declaration:

              class Y;
              class Z;
              class X;
                 //friend Y;  ** not legal
                 friend class Z; // legal
              };

        4.3.2 Member Access

              Unlike some older C++ implementations, Compaq C++ strictly
              enforces accessibility rules for public, protected, and
              private members of a base class. For more information, see
              The C++ Programming Language, 3rd Edition.

        4.3.3 Base Class Initializers

              Unlike some older C++ implementations, Compaq C++ requires
              you to use the base class name in the initializer for a
              derived class. The following code fragment implements a
              legal initializer and comments out an illegal initializer:

              class Base {
                  //  . . .
              public:
                  Base (int);
              };
              class Derived : public Base {
                  //  . . .
              public:
                  // Derived(int i) : (i)  {/*  . . .
        */}    ** not legal
                  Derived(int i) : Base(i) {/*  . . .
        */} // ** legal, supplies class name
              };

              For more information, see The C++ Programming Language,
              3rd Edition.


                                               Porting to Compaq C++ 4-9

 



     Porting to Compaq C++
     4.4 Undefined Global Symbols for Static Data Members

     4.4 Undefined Global Symbols for Static Data Members

           When a static data member is declared, the compiler issues
           a reference to the external identifier in the object
           code, which must be resolved by a definition. On Compaq
           Tru64 UNIX and Linux Alpha systems, the compiler does
           not support the declaration anachronism shown in The C++
           Programming Language, 3rd Edition.

           For example, consider the following code fragment:

           #include <stdio.h>
           class C {
           public:
                   static int i;
                   };
           //missing definition
           //int C::i = 5;
           int main ()
           {
               int x;
               x=C::i;
               printf("x %d\n",x);
               return 0;
           }

           The compiler does not issue any messages during com-
           pilation; however, when you attempt to link a program
           containing this code, the linker issues a message similar
           to the following:

           ld:
           Error: Undefined:
           i__1C

     4.5 Functions and Function Declaration Considerations

           Compaq C++ requires the use of function definitions as
           described in The C++ Programming Language, 3rd Edition.
           For examples of outdated syntax not allowed in Compaq C++,
           see The C++ Programming Language, 3rd Edition.




     4-10 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                   4.5 Functions and Function Declaration Considerations

              Because all linkage specifications for a name must agree,
              function prototypes are not permitted if the function is
              later declared as an inline function. The following code
              is an example of such a conflicting function declaration:

              int f();
              inline int f() { return l; }

              In this example, f is declared with both internal and
              external linkage, which causes a compiler error.

              Similarly, the declaration int f(i,j) causes an error
              even when the declaration is defined with the "C" linkage
              specification, because the linkage specification has no
              effect on the semantics of the declaration.

        4.6 Using Pointers

              This section explains how to use pointers effectively in
              Compaq C++.

        4.6.1 Pointer Conversions

              In Compaq C++, you cannot implicitly convert a const
              pointer to a nonconstant pointer. For example, char *
              and const char * are not equivalent; explicitly performing
              such a cast can lead to unexpected results.

              For more information, see The C++ Programming Language,
              3rd Edition.

        4.6.2 Bound Pointers

              Binding a pointer to a member function with a particular
              object as an argument to the function is not allowed in
              Compaq C++. For more information on the illegality of
              casting bound pointers, see The C++ Programming Language,
              3rd Edition.

        4.6.3 Constants in Function Returns

              Because the return value cannot be an lvalue, a constant
              in a function return has no effect on the semantics of
              the return. However, using a constant in a function return
              does affect the type signature. For example:

              static int f1( int a, int b) {;}
              const int (* const (f2[])) (int a, int b) = {f1};

                                              Porting to Compaq C++ 4-11

 



     Porting to Compaq C++
     4.6 Using Pointers

           In this example, the referenced type of the pointer value
           f1 in the initializer for f2[] is function (signed
           int, signed int), which returns signed int. This is
           incompatible with function (signed int, signed int), which
           returns const signed int.

           You can omit the const of int because it affects only the
           constant return signature.

     4.6.4 Pointers to Constants

           The following example shows a type mismatch between a
           pointer to a char and a pointer to a const char:

           void foo (const char* argv[]) {}
           int main()
           {
                   static char* args[2] = {"foo","bar"};
           /* 'In this statement, the referenced type of the pointer value
            "args" is "pointer to char"' which is not compatible with
            "pointer to const char"'*/
                   foo (args);
           return 0;
           }

           You can correct this example by changing static char to
           static const char. Use an explicit type cast to get an
           argument match only if no other option is available; such
           a cast may break on some C++ implementations.

     4.7 Using typedefs

           Using a synonym after a class, struct, or union prefix is
           illegal. Using a synonym in the names for constructors and
           destructors within the class declaration itself is also
           illegal.

           In the following example, the illegal typedef specifier is
           commented out:

           typedef struct { /*  . . .  */ } foo;
           // typedef struct foo foobar;             ** not legal

           For more information, see The C++ Programming Language,
           3rd Edition.

     4-12 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                                             4.8 Initializing References

        4.8 Initializing References

              Compaq C++ warns against initializing nonconstant
              references to refer to temporary objects. The following
              example demonstrates the problems that can result:

              static void f()
              {
                  int i = 5;
                  i++;        // OK
                  int &ri = 23;
                  ri++;       // In the initializer for ri, the initialization of a
                              // non-const reference requires a temporary for "23".
              }

              The issue of reference initialization arises most often in
              assignment operators and in copy constructors. Wherever
              possible, declare all reference arguments as const.

              For more information, see The C++ Programming Language,
              3rd Edition.

        4.9 Using the switch and goto Statements

              Branching around a declaration with an explicit or
              implicit initializer is not legal, unless the declaration
              is in an inner block that is completely bypassed. To
              satisfy this constraint, enclose the declaration in a
              block. For example:

              int i;

              switch (i) {
              case 1:
                  int l = 0;     //not initialized at this case label
                  myint m = 0;   //not initialized at this case label
                  {
                  int j = 0;     // legal within the braces
                  myint m = 0;   // legal within the braces
                  }
              case 2:
                  break;
              //  . . .
              }

              For more information on using the switch statement, see of
              The C++ Programming Language, 3rd Edition.

                                              Porting to Compaq C++ 4-13

 



     Porting to Compaq C++
     4.10 Using Volatile Objects

     4.10 Using Volatile Objects

           You must supply the meaning of copy constructing and
           assigning from volatile objects, because the compiler
           generates no copy constructors or assignment operators
           that copy or assign from volatile objects. The following
           example contains examples of such errors, as noted in the
           comments:

           class A {
           public:
             A() { }
             // A(volatile A&) { }
             // operator=(volatile A&) { return 0; }
           };

           void foo()
           {
             volatile A va;
             A a;

             A cca(va);  // error - cannot copy construct from volatile object
             a = va;     // error - cannot assign from volatile object

             return;
           }

           For more information, see The C++ Programming Language,
           3rd Edition.

     4.11 Preprocessing

           Compaq C++ allows identifiers, but not expressions, on the
           #ifdef preprocessor directive. For example:

           // this is not legal
           // #ifdef KERNEL && !defined(__POSIX_SOURCE)

           The following is the legal alternative:

           // use this instead
           #if defined(KERNEL) && !defined(__POSIX_SOURCE)

           For more information, see The C++ Programming Language,
           3rd Edition.

     4-14 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                                                    4.12 Managing Memory

        4.12 Managing Memory

              The proper way to manage memory for a class is to overload
              the new and delete operators. This is in contrast to some
              older C++ implementations, which let you manage memory
              through assignment to the this pointer.

              For more information, see The C++ Programming Language,
              3rd Edition.

              Program developers must take care that any user-defined
              new operators always return pointers to quadword aligned
              memory.

        4.13 Size-of-Array Argument to delete Operator

              If a size-of-array argument accompanies a delete operator,
              the compiler ignores the argument and issues a warning.
              The following example includes an anachronistic use of the
              delete operator:

              int main()
              {
                      int *a = new int [20];
                      int *b = new int [20];
                      delete[20] a;     //old-style; argument ignored, warning issued
                      delete[] b;
              return 0;
              }

        4.14 Flushing the Output Buffer

              Do not depend on the newline character (\n) to flush your
              terminal output buffer. A previous stream implementation
              might have done so, but this behavior is not in confor-
              mance with Version 2.0 of the AT&T iostream library.
              If you want to flush the output buffer, use the endl
              manipulator or the flush member function.







                                              Porting to Compaq C++ 4-15

 



     Porting to Compaq C++
     4.15 Missing Parenthesis Error Message

     4.15 Missing Parenthesis Error Message

           Situations occur in which a simple typographical error
           generates a missing parenthesis error message. In the
           following example, the class name CaseSensitive is
           incorrectly specified as Casesensitive in the constructor
           declaration:

           class CaseSensitive {
               void Test( const Casesensitive &foo );
           };

           As the compiler parses the argument declaration list:

           1. It interprets const as a type specifier.

           2. It interprets Casesensitive as a different indentifier.

           Among the next legal tokens are the equal sign, comma,
           and closing parenthesis. Upon finding an ampersand, the
           compiler expects a closing parenthesis. With all other
           possibilities exhausted, the compiler has what appears to
           be a legal argument declaration list, after which the
           closing parenthesis is the only allowable token. The
           compiler expected one thing but encountered something
           else. Often, inserting newline characters can isolate the
           offending token.

     4.16 Link Using cxx

           Use the cxx command, not the ld command, to build a
           binary; otherwise, the run-time startup and other crucial
           code will not build properly. Some symptoms of linking
           incorrectly are

           o  Segmentation faults (signal SEGV) occur while running
              your program

           o  Undefined symbols

           o  Static constructors not being executed




     4-16 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                                             4.17 Source File Extensions

        4.17 Source File Extensions

              Compaq C++ automatically treats files with a .c extension
              as C language source files and passes the files to the cc
              command. For Compaq C++ to compile them, your files must
              have one of the following extensions:

              .cxx        .CXX
              .cpp        .CPP
              .cc         .CC
              .C          .C++

              You also can use the -x option to direct the compiler to
              ignore file-name extensions and treat all named files,
              other than those with an .a or .o extension, as C++ source
              files.

        4.18 Incrementing Enumerations

              Some other C++ implementations let you perform integer
              arithmetic, including ++, on enumerated types; Compaq C++
              does not allow this.

        4.19 Scope of Variables Declared on a for Statement

              If the for-init-statement is a declaration, the scope
              of the name(s) declared extends to the end of the for-
              statement, as shown in the following example:

              int i=5;

              void f()
              {
                for (int i=0;i<10;i++);

                printf("%d\n",i);
              }

              When compiled -std ansi, strict_ansi, or strict_ansi_
              errors, the compiler produces the results expected by
              the International C++ Standard. In all other modes, the
              compiler produces the results expected by The Annotated
              C++ Reference Manual; that is, the scope of the names
              declared extends to the end of the enclosing scope.

                                              Porting to Compaq C++ 4-17

 



     Porting to Compaq C++
     4.20 Guidelines for Writing Clean 64-Bit Code

     4.20 Guidelines for Writing Clean 64-Bit Code

           Paying careful attention to data types can ensure that
           your code works on both 32-bit and 64-bit systems. Use the
           following guidelines to write clean 64-bit code:

           o  Variables that should be 32 bits in size on both 32-bit
              systems and 64-bit Alpha systems should be declared as
              int (not long). Even better would be to declare them as
              int32, which is a macro you define to be int.

           o  Variables that should be 32 bits in size on a 32-bit
              system and 64 bits in size on a 64-bit Alpha system
              should be declared as long. Even better would be to
              declare them as long-int, which is a macro you define
              to be long.

           o  Check any variables in your code that are declared
              long. If the variable must be 32 bits in size, you must
              change its type to int.

           o  Variables declared as int should not be used to hold an
              address; sizeof (int) does not equal sizeof (char *) on
              Alpha systems.

           o  Remember that register variables and unsigned variables
              default to int (32 bits).

           o  Constants are 32-bit quantities by default. Performing
              shift operations or bit operations on constants will
              give 32-bit results. You must add L to the constant to
              get a 64-bit result. For example:

              long foo, bar;
              foo = 1L << bar;

           o  Using a 0 where you should use NULL generates a 32-bit
              constant. On Alpha systems, this could yield 0 in the
              low 32 bits and useless data in the high 32 bits when
              passed into a function that accepts a variable number
              of arguments. Using NULL from the <stdio.h> header file
              provides the correct value.

           o  Assigning to a char is not atomic on Alpha processors
              before the EV56. You will obtain a load of 32 or 64
              bits, followed by byte operations to extract, mask, and
              shift the byte, followed by a store of 32 or 64 bits.

     4-18 Porting to Compaq C++

 



                                                   Porting to Compaq C++
                           4.20 Guidelines for Writing Clean 64-Bit Code

              o  Bit-fields declared as int on Alpha systems generate
                 load/store 32 bits. Bit-fields declared as long on
                 Alpha systems generate load/store 64 bits.

              o  If you do not explicitly declare the formal parameters
                 to functions, their sizes may not match the caller
                 sizes. The default is int, which truncates 64-bit
                 addresses.

              o  The %d and %x format specifiers print 32 bits of data.
                 Use %ld or %lx with printf to print 64 bits of data.
                 You can use %p on both 32- and 64-bit systems to print
                 the value of pointers.

              For more information, see the ULTRIX to Compaq Tru64 UNIX
              Migration Guide.





























                                              Porting to Compaq C++ 4-19

 









                                                                       5
        ________________________________________________________________

                                                         Using Templates



              The C++ template instantiation model includes the
              following features:

              o  Automatic template instantiation occurs at compile
                 time. Necessary templates are instantiated automati-
                 cally by the compilation of the source file that needs
                 them and has access to the template definitions.

              o  During automatic template instantiation, instantiations
                 are written into the repository (./cxx_repository)
                 as object files. Compilation of instantiations in no
                 longer done at link time.

              o  For automatic instantiation, the compiler does not
                 require that template declarations and definitions
                 appear in header files.

              o  Several manual template instantiation pragmas are
                 availble.

        5.1 Overview

              A C++ template is a framework for defining a set of
              classes or functions. The process of instantiation creates
              a particular class or function of the set by resolving the
              C++ template with a group of arguments that are themselves
              types or values. For example:

              template <class T> class Array {
                  T *data;
                  int size;
              public:
                  T &operator[](int);
              };

                                                     Using Templates 5-1

 



     Using Templates
     5.1 Overview

           The code in this example declares a C++ class template
           named Array that has two data members named data and size
           and one subscript operator member function. Array<int>
           instantiates Array with type int. This instantiation
           generates the following class definition:

           class Array {
               int *data;
               int size;
           public:
               int &operator[](int);
           };

           The compiler supports instantiation of C++ class,
           function, and static data member templates. The following
           sections describe the alternative methods available
           for instantiating templates: automatic or manual
           instantiation.

     5.2 Automatic Template Instantiation

           In automatic template instantiation mode, the compiler
           attempts to instantiate every referenced template at
           compile time. For automatic instantiation to work, at
           least one compilation that references a template function
           must be able to find the template definition. There is
           no restriction on where a template can be declared or
           defined, as long as the definition is visible to the
           compilation unit. You can use implicit inclusion to find
           it.

           The compiler writes instantiation object files to a
           directory called the repository; file names are based on
           the names of the entities being instantiated. The default
           repository is ./cxx_repository.

     5.2.1 Specifying Alternate Repositories

           You can use the -ptr command-line option to specify
           one or more alternate repository directories. The first
           repository named is the read-write repository into which
           the compiler writes instantiation objects when processing.
           At link time, all repositories are read only. There is
           one object file in the repository for each instantiated
           template function, for each instantiated static data

     5-2 Using Templates

 



                                                         Using Templates
                                    5.2 Automatic Template Instantiation

              member, and for each virtual table required for virtual
              functions.

              When the program is linked, the linker searches the
              repositories for needed template instantiations.

        5.2.2 Reducing Compilation Time with the -ttimestamp Option

              To keep instantiations up to date, the compiler always
              instantiates templates by default, even if the required
              template already exists in the respository. However, in
              environments that share many templates among many sources,
              this process can increase compilation time.

              In these environments, users can specify the -ttimestamp
              option to override the default behavior and thereby reduce
              compilation time. This option causes the compiler to
              create a timestamp file named TIMESTAMP in the repository.
              Thereafter, instantiations are added or regenerated only
              if needed; that is, if they do not alreay exist, or if
              existing ones are older than the timestamp.

              The -ttimestamp option is immediately useful when building
              a system from scratch, starting with an empty repository.
              It avoids reinstantiating unchanged code and is totally
              safe, because all required instantiations are generated
              and up to date.

              Incremental application building is normally done without
              this option, so that new instantiations overwrite earlier
              ones as sources are recompiled.

              Although the -ttimestamp option is intended mainly for
              initial builds, you can use it for ongoing development
              in a structured way. Because the compiler creates a new
              timestamp file only if one does not already exist, you
              must remove or modify any existing timestamp file before
              making changes to your code base. This procedure ensures
              that all subsequent compilations generate up-to-date
              instantiations. In the following example, the file is
              removed before and immediately after the compilation of
              a.cxx, b.cxx, and c.cxx.



                                                     Using Templates 5-3

 



     Using Templates
     5.2 Automatic Template Instantiation

           rm cxx_repository/TIMESTAMP
           cxx -ttimestamp -c a.cxx
           cxx -ttimestamp -c b.cxx
           cxx -ttimestamp -c c.cxx
           rm cxx_repository/TIMESTAMP

           The compiler generates all instantiations needed by a.cxx,
           b.cxx, and a.cxx only once, as opposed to the default
           scheme, in which it would generate them once for each
           module that used the instantiations.

           Specifying the -ptv option causes the compiler to emit
           an informational message naming the instantiation and
           repository file being skipped in this mode.

     5.3 Implicit Inclusion

           When implicit inclusion is enabled, the compiler assumes
           that if it needs a definition to instantiate a template
           entity declared in a .h or .hxx file, it can implicitly
           include the corresponding implementation file to obtain
           the source code for the definition.

           If a template entity ABC::f is declared in file xyz.h, and
           if an instantiation of ABC::f is required in a compilation
           but no definition of ABC::f appears in the source code,
           the compiler checks whether a file xyz.cxx exists. If it
           does, the compiler processes it as if it were included at
           the end of the main source file.

           When looking for a template definition, the compiler uses
           the following lookup order:

           1. If the #include name for the header file containing the
              template declaration is specified with an absolute path
              name, look only in the directory specified by the path
              name.

           2. If the #include for the header file containing the
              template declaration is specified with a relative path
              name, take the following action:

              o  If the header file name is specified with double
                 quotation marks (" ") and the -nocurrent_include
                 option was not specified, append the relative path
                 name to the directory containing the source file and
                 search for files with the appropriate suffixes.

     5-4 Using Templates

 



                                                         Using Templates
                                                  5.3 Implicit Inclusion

                 o  Otherwise, append the relative path name to all
                    the -I directories and look in those resulting
                    directories for files with the appropriate
                    suffixes.

              For source files, the appropriate suffixes are, in order
              of preference: .cxx, .CXX, .C, .cc, .CC, .cpp, and .c, or
              as defined by the -ptsuf command-line option.

              The compiler ignores any file extension that does not
              begin with a dot (.).

              The -ptsuf command-line option allows the user to
              explicitly define the file extensions to be used with
              implicit inclusion. For example:

               cxx -ptsuf ".CPP.CC" file.cxx

              This command searches for template definition files with
              the extensions .CPP and .CC.

        5.3.1 Compiling Programs with Automatic Instantiation

              In general, the use of automatic template instantiation is
              transparent to the user. Automatic template instantiation
              is enabled by default. The following commands are
              equivalent:

               cxx file.cxx

               cxx -pt file.cxx

               cxx -pt -ptr ./cxx_repository file.cxx

              These commands:

              o  Cause the compilation of the file file.cxx

              o  Create any instantiations that are required whose
                 definitions are visible to the compiler

              o  Create an executable, a.out, by linking together the
                 generated object file and any instantiations required
                 from the repository

              You can specify the repository explicitly with the -ptr
              switch. For example:

               cxx -pt -ptr /project/repository -c file.cxx

                                                     Using Templates 5-5

 



     Using Templates
     5.3 Implicit Inclusion

           This command compiles file.cxx, produces a file.o in the
           current directory, and puts instantiated template files in
           the directory /project/repository.

           The compiler attempts to instantiate templates at compile
           time; therefore, any specialization used in the program
           must be declared in each file in which the specialization
           is referenced, to prevent the instantiation of the
           overridden template function.

           If a template instantiation refers to a static function,
           that function is created as an external entry point in the
           primary object file, and the instantiation object file in
           the repository then refers to this __STF function.

           If the template instantiation is linked into an appli-
           cation that does not have the original primary object
           file, an unresolved reference to the __STF function
           occurs. If this happens, recompile an object file that
           regenerates the instantiation or use manual instantiation
           to reinstantiate the template.

     5.3.2 Linking Programs with Automatic Instantiation

           When all source files are compiled and linked in the
           same step, the operation is transparent. For example,
           the following command compiles a.cxx and b.cxx, writes
           instantiations to ./cxx_repository, and links the
           application using the object files and the instantiations
           from ./cxx_repository:

            cxx a.cxx b.cxx

           When compiling and linking an application in separate
           steps, the repositories that were used during the
           compilation step must be used in the link step as well.
           For example, the following command uses ./cxx_repository
           implicitly in both the compile and link step:

            cxx -c a.cxx b.cxx
            cxx a.o b.o

           If a repository is explicitly named in the compile step,
           then it must also be named in the link step. For example:

            cxx -c -ptr my_repository a.cxx b.cxx
            cxx -ptr my_repository a.o b.o

     5-6 Using Templates

 



                                                         Using Templates
                                                  5.3 Implicit Inclusion

              It is easiest if the compilation of all sources use the
              same repository:

               cxx -c -ptr my_repository a.cxx
               cxx -c -ptr my_repository b.cxx
               cxx -ptr my_repository a.o b.o

              If different repositories are used for the compilation of
              the sources, then all repositories must by specified on
              the link step, as follows:

               cxx -c -ptr repository1 a.cxx
               cxx -c -ptr repository2 b.cxx
               cxx -ptr repository1 -ptr repository2 a.o b.o

              At link time, the specified repositories are searched in
              the order given, to find the required instantiations. If
              one of the repositories used is the default repository, it
              must be explicitly specified on the link step if more than
              one repository is used, as follows:

               cxx -c  a.cxx
               cxx -c -ptr repository2 b.cxx
               cxx -ptr ./cxx_repository -ptr repository2 a.o b.o

              It is usually much easier and safer to use a single
              repository, because the same instantiations could
              potentially be present in multiple repositories, and it
              is possible to update some but not all repositories when
              changes are made to templates.

              The link phase of cxx processes object files so that all
              the external symbol references are resolved. The objects
              are linked together in the following order:

              1. The order in which object files and object libraries
                 are specified on the command line.

              2. If -nopt is specified, stop.

              3. For each unresolved external, search the repositories
                 in the order specified on the command line for a file
                 that contains that external. If such a file is found,
                 add it at the top of the list of object files being
                 searched.

                                                     Using Templates 5-7

 



     Using Templates
     5.3 Implicit Inclusion

           4. Link again and repeat Step 3 until no more externals
              are found or until no more object files are found in
              which to resolve the external.

           The following apply to instantiations:

           o  Instantiations that appear in explicitly linked
              object files or libraries hide instantiations in the
              repositories.

           o  Only template instantiations that are actually
              referenced in sources that can instantiate them appear
              in the repository. You must specify any other wanted
              instantiations manually or use the -tall_repository
              switch.

           o  Instantiations are satisfied from the list of
              unsatisfied externals from the linking of specified
              files, but are linked at the beginning of those files.
              This means that they are linked in only if they are
              satisfied from no specified file given the file order
              behavior of ld, and bring in any external references
              that they need from the first library that satisfies
              them.

     5.4 Manual Template Instantiation

           The compiler provides the following methods to instantiate
           templates manually:

           o  Using the #pragma directives

              You can use an instantiation pragma to direct the
              compiler to instantiate a specific template, as
              described in Section 5.4.1.

           o  Using explicit template instantiation syntax

              The C++ language defines specific syntax for specifying
              that a template should be instantiated. See The C++
              Programming Language, 3rd Edition.

              Compaq strongly recommends using the explicit template
              instantiation syntax when possible.

           o  Using the command-line option method

     5-8 Using Templates

 



                                                         Using Templates
                                       5.4 Manual Template Instantiation

                 This method directs the compiler to instantiate
                 templates at compile time in the user's .o file.
                 Several options are available to control linkage and
                 extent of template instantiation. For more information
                 about this option, see Section 5.2.

        5.4.1 Instantiation Directives

              The next sections describe the following instantitation
              directives:

                 #pragma define_template
                 #pragma instantiate_template
                 #pragma do_not_instantiate_template

        5.4.1.1 #pragma define_template

              The compiler provides a mechanism for manual instan-
              tiation, using the #pragma define_template directive.
              This directive lets you tell the compiler what class
              or function template to instantiate in conjunction with
              the actual arguments with which the template is to be
              instantiated. The #pragma define_template directive has
              the following format:

              #pragma define_template identifier  <template_arguments>

              Identifier is the name of the class or function template
              that the compiler is directed to instantiate at compile
              time. For the instantiation to succeed, the definition
              of the template must appear before the #pragma define_
              template directive.

              Template_arguments is a list of one or more actual
              types that correspond to the template parameters for the
              particular class or function template being instantiated.
              Whatever type is specified is used as the type for the
              instantiation.

              The following is an example of a valid template manual
              instantiation:

                     //main.cxx
                     #include <stdlib.h>
                     template <class T> void sort (T*);

                     int al[100];
                     float a2[100];

                                                     Using Templates 5-9

 



     Using Templates
     5.4 Manual Template Instantiation

                  int main()
                  {
                      sort(a1);
                      sort(a2);
                      return EXIT_SUCCESS;
                  }

                  //sort.cxx
                  template <class T> void sort (T *array)
                  {
                      /* body of sort */
                  }

                  #pragma define_template sort<int>
                  #pragma define_template sort<float>

           To compile and link these sources, enter the following
           command:

                cxx -nopt main.cxx sort.cxx

           When you use #pragma define_template or explicit instan-
           tiation, only the specified template is instantiated;
           templates to which it refers because of member types or
           base classes are not instantiated.

           Sorting an array of template class elements requires the
           use of additional pragmas for the module sort.cxx. For
           example:

                  template <class T> void sort (T* array)
                  {
                      /*body of sort*/
                  }

                  template <class T> class entity {
                  public:
                      T member;
                      int operator < (const entity<T> &) const;
                  }

                  template <class T>
                  int entity<T>::operator < (const entity<T> &operand) const
                  {
                       return member < operand.member;
                  }

     5-10 Using Templates

 



                                                         Using Templates
                                       5.4 Manual Template Instantiation

                     int al[100];
                     float a2[100];
                     entity<int> a3[100];

                     #pragma define_template sort<int>
                     #pragma define_template sort<float>
                     #pragma define_template sort<entity<int> >

                     void sort_all_arrays ()
                     {
                         sort(a1);
                         sort(a2);
                         sort(a3);
                     }

              The define_template pragma is position sensitive. If a
              define_template occurs lexically before a function, member
              function, or static data member template definition,
              the compiler is unable to instantiate the corresponding
              template because the body of that template is not present
              before the pragma directive.

              The compiler instantiates all instances of sort and of
              entity::operator < needed for this compilation unit.

              To organize a program to use the define_template pragma,
              you can place the declarations of class and functions
              templates into header files, and instantiate all instances
              of a particular template from a single compilation unit.
              The following example shows how to do this:

                     // sort.h
                     #include <stdlib.h>
                     template <class T> void sort (T*);

                     // entity.h
                     template <class T> class entity {
                     public:
                         T member;
                         int operator < (const entity<T> &) const;
                     };

                     // main.cxx
                     #include "sort.h"
                     #include "entity.h"

                                                    Using Templates 5-11

 



     Using Templates
     5.4 Manual Template Instantiation

                  int al[100];
                  float a2[100];
                  entity<int> a3[100];

                  int main()
                  {
                      sort(a1);
                      sort(a2);
                      sort(a3);
                      return EXIT_SUCCESS;
                  }

                  // sort.cxx
                  #include "sort.h"
                  #include "entity.h"
                  template <class T> void sort (T* array)
                  {
                      /*body of sort*/
                  }
                  #pragma define_template sort<int>
                  #pragma define_template sort<float>
                  #pragma define_template sort<entity<int> >

           Compiling the following file provides a definition of
           entity::operator < with type int:

                  // entity.cxx
                  #include "entity.h"

                  template <class T>
                  int entity<T>::operator < (const entity<T> &operand) const
                  {
                       return member < operand.member;
                  }

                  #pragma define_template entity<int>

           To compile this example, issue the following command:

                  cxx main.cxx sort.cxx entity.cxx

           If the program uses other instantiations of entity in
           other compilation units, you can provide definitions
           of operator < for those entities by adding define_
           template pragmas to entity.cxx. For example, if other
           compilation units use the following instantiations of
           entity, appending the following pragmas to entity.cxx

     5-12 Using Templates

 



                                                         Using Templates
                                       5.4 Manual Template Instantiation

              causes the compiler to generate instantiations of operator
              < for those requests of entity:

                 entity<long> and entity< entity<int> >,
                 #pragma define_template entity<long>
                 #pragma define_template entity< entity<int> >

        5.4.1.2 #pragma instantiate and #pragma do_not_instantiate

              The compiler also provides several pragmas that provide
              fine control over the instantiation process. Instantiation
              pragmas, for example, can be used to control the
              instantiation of specific template entities or sets of
              template entities. There are two instantiation pragmas:

              o  The instantiate pragma causes a specified entity to be
                 instantiated, similar to the define_template pragma.
                 It provides finer instantiation control than define_
                 template when instantiating function templates.

              o  The do_not_instantiate pragma suppresses the instan-
                 tiation of a specified entity. It is typically used
                 to suppress the instantiation of an entity for which a
                 specific definition is supplied.

              The argument to the instantiation pragma can be:

              a template class name     A<int>

              a template class          class A<int>
              declaration

              a member function name    A<int>::f

              a static data member      A<int>::i
              name

              a static data declara-    A<int>::i
              tion

              a member function         void A<int>::f(int, char)
              declaration

              a template function       char* f(int, float)
              declaration

              A pragma in which the argument is a template class name
              (for example, A<int> or class A<int> is equivalent to
              repeating the pragma for each member function and static
              data member declared in the class. When instantiating
              an entire class, a given member function or static data

                                                    Using Templates 5-13

 



     Using Templates
     5.4 Manual Template Instantiation

           member may be excluded using the do_not_instantiate
           pragma. For example:

            #pragma instantiate A<int>
            #pragma do_not_instantiate A<int>::f

           The template definition of a template entity must be
           present in the compilation for an instantiation to occur.
           If an instantiation is explicitly requested by use of the
           instantiate pragma and no template definition is available
           or a specific definition is provided, an error is issued.

            template <class T> void f1(T);  // No body provided
            template <class T> void g1(T);  // No body provided
            void f1(int) {}  // Specific definition
                   #include <stdlib.h>
             int main()
            {
              int     i;
              double  d;
              f1(i);
              f1(d);
              g1(i);
              g1(d);
                     return EXIT_SUCCESS;
            }
            #pragma instantiate void f1(int) // error - specific definition
            #pragma instantiate void g1(int) // error - no body provided

           The functions f1(double) and g1(double) are not instanti-
           ated (because no bodies were supplied) but no errors are
           produced during the compilation (if no bodies are supplied
           at link time, a linker error is produced).

           A member function name (for example, A<int>::f can
           be used as a pragma argument only if it refers to a
           single user-defined member function (that is, not an
           overloaded function). Compiler-generated functions are
           not considered, so a name may refer to a user-defined
           constructor even if a compiler-generated copy constructor
           of the same name exists. Overloaded member functions can
           be instantiated by providing the complete member function
           declaration:

            #pragma instantiate char* A<int>::f(int, char*)

     5-14 Using Templates

 



                                                         Using Templates
                                       5.4 Manual Template Instantiation

              The argument to an instantiation pragma must not be a
              compiler-generated function, an inline function, or a pure
              virtual function.

        5.5 Advanced Program Development and Templates

              The following sections discuss templates in the context of
              advanced program development.

        5.5.1 Dependency Management

              The compiler does no dependency management of its own.
              Because template instantiations are compiled when source
              files that reference those instantiations are compiled,
              those source files must be recompiled if the template
              declaration or definition changes.

              The -M output from the compiler lists the implicitly
              included files, so that the make program can automatically
              recompile any source files that depend upon template
              files. If make is not being used, it is the user's
              responsibility to ensure that instantiations that have
              changed are recompiled. The user does so by recompiling
              at least one source file that references the changed
              instantiations.

              The compiler does not check command line dependencies
              of template instantiations at link time. If you compile
              two different source files that instantiate a specific
              template with two different sets of options, the last
              option setting affects the template instantiation. Use
              consistent option settings for each build into each
              repository.

        5.5.2 Mixing Automatic and Manual Instantiation

              Object files that have been compiled using manual
              instantiation can be linked freely with objects that have
              been compiled using automatic instantiation. To ensure
              that the template instantiations needed by the files
              compiled with automatic instantiation are provided, the
              application must be linked using automatic instantiation,
              and the appropriate repositories must be present.


                                                    Using Templates 5-15

 



     Using Templates
     5.5 Advanced Program Development and Templates

           When a template instantiation is present in an explicitly
           named object file or object library it takes precedence
           over the same named instantiation in a repository.

     5.5.3 Creating Libraries

           Creating libraries with object files created with
           automatic instantiations is relatively straightforward.
           You must decide where the instantiations that were
           generated automatically are provided to the users of the
           library.

           For applications that use the library to link success-
           fully, all template instantiations that are needed by
           the code in the library must be available at link time.
           Because template instantiation happens at compile time,
           the object files that contain the instantiated templates
           must be available at link time. This can be done in two
           ways:

           o  Put the instantiations in the library. They hide the
              same named instantiations in any repositories or any
              libraries following the library on the command line.

           o  Provide a repository that contains the instantiations.

           It is usually easiest to put the instantiations in the
           library. This is a good choice if the instantiations are
           internal to the library and are not instantiated directly
           by the user's code. To put the instantiations in the
           library, add all of the object files in the repositories
           required by the library into the library, as shown in the
           following example:

            cxx -c -ptr lib_repository a.cxx b.cxx c.cxx
            ar r mylib.a a.o b.o c.o lib_repository/*.o

           If the template instantiations can be overridden by the
           user, the templates should be provided in a repository
           that the user specifies after all the user's repositories.
           For the previous example, create the library as follows:

            cxx -c -ptr lib_repository a.cxx b.cxx c.cxx
            ar r mylib.a a.o b.o c.o

     5-16 Using Templates

 



                                                         Using Templates
                          5.5 Advanced Program Development and Templates

              When linking the application, the user would specify lib_
              repository as the last read-only repository on the line as
              follows:

               cxx -c -ptr ./cxx_repository -ptr lib_repository user_code.cxx mylib.a

              The user must explicitly name the repository when linking,
              even if it is the default repository ./cxx_repository.
              The compiler first satisfies all unresolved instantiations
              from ./cxx_repository, and then it uses lib_repository to
              resolve any remaining unresolved instantiations.

              Only the instantiations that are required by the code in
              the library are generated in the library repository lib_
              repository. If you must provide other instantiations that
              the user requires but cannot instantiate, you must provide
              these instantiations using manual template instantiation.

        5.5.4 Creating A Common Instantiation Library

              If you want to put all current instantiations into a
              common instantiation library, follow these steps:

              1. Compile with the -ptv option and save the results to a
                 file.

              2. Edit that file and save the names that appear after
                 the "automatically instantiating ..." string. You can
                 ignore any messages about instantiating vtables. Put
                 #pragma instantiate before each name.

              3. Put the result of that edit into a separate source file
                 and include at the top of the file any headers needed
                 for template definitions.

              4. Put matching #pragma do_not_instantiate (see Section 5.4.1.2)
                 into the headers that define each of these template
                 classes or functions.

              5. Place each #pragma do_not_instantiate directive between
                 an #ifndef of the form #ifndef SOME_MACRO_NAME and an
                 #endif.

              6. Compile the inst.cxx file with SOME_MACRO_NAME defined.

              7. Link the source file with the resulting object file.

                                                    Using Templates 5-17

 



     Using Templates
     5.5 Advanced Program Development and Templates

           The following examples show how to create a common
           instantiation library for all the instantiations currently
           being automatically instantiated for this file.

           // foo.cxx
           #include <stdlib.h>
           #include <vector>
           #include "C.h"

           int main() {
            vector<C> v;
            v.resize(20);
                   return EXIT_SUCCESS;
           }

           // C.h
           #ifndef __C_H

           class C {};

           #endif

           Compiling with the -ptv option shows which instantiations
           occur automatically:

           Writable_repository: ./cxx_repository
           Repository_list: ./cxx_repository
           cxx: Info: /usr/proj/decc2/mainline/exxalphaosf/stdlibinclude/vector.cc, line
           90:
                     automatically instantiating void std::vector<C, std::allocator<C >
                     >::resize(unsigned long)
           void vector<T,Allocator>::resize (size_type new_size)
           // etc. etc.

           1. Place all these instantiations into a file called
              inst.cxx that is built separately or into a library:

              // inst.cxx
              #include <vector>
              #include "C.h"





     5-18 Using Templates

 



                                                         Using Templates
                          5.5 Advanced Program Development and Templates

                 #pragma instantiate void std::vector<C, std::allocator<C > >::resize(unsigned
                 long)
                 #pragma instantiate void std::vector<C, std::allocator<C > >::insert(C *,
                 unsigned long, const C &)
                 #pragma instantiate void std::vector<C, std::allocator<C > >::__insert(C *,
                 unsigned long, const C &, __true_category)
                 #pragma instantiate C *std::copy_backward(C *, C *, C *)
                 #pragma instantiate void std::fill(C *, C *, const C &)
                 #pragma instantiate C *std::copy(C *, C *, C *)
                 #pragma instantiate const unsigned long std::basic_string<char,
                 std::char_traits<char >, std::allocator<void> >::npos

              2. Add these instantiations into C.h and change "instan-
                 tiate" to "do_not_instantiate". Add an #ifndef, so
                 that when building inst.cxx, the compiler creates these
                 instantiations in the inst object file:

                 #ifndef __C_H

                 class C {};

                 #ifndef __BUILDING_INSTANTIATIONS
                 #pragma do_not_instantiate void std::vector<C,
                         std::allocator<C > >::resize(unsigned long)
                 #pragma do_not_instantiate void std::vector<C,
                         std::allocator<C > >::insert(C*, unsigned long, const C &)
                 #pragma do_not_instantiate void std::vector<C,
                         std::allocator<C > >::__insert(C*, unsigned long,
                         const C &, __true_category)
                 #pragma do_not_instantiate C *std::copy_backward(C *, C *, C *)
                 #pragma do_not_instantiate void std::fill(C *, C *, const C &)
                 #pragma do_not_instantiate C *std::copy(C *, C *, C *)
                 #pragma do_not_instantiate const unsigned long
                         std::basic_string<char, std::char_traits<char >,
                         std::allocator<void> >::npos
                 #endif
                 #endif

              3. Build the inst object file:

                 cxx -D__BUILDING_INSTANTIATIONS -c inst.cxx




                                                    Using Templates 5-19

 



     Using Templates
     5.5 Advanced Program Development and Templates

           4. Link with the inst object file. It will use instan-
              tiations from that file instead of creating them
              automatically:

              cxx foo.cxx inst.o

           To verify that your procedure worked correctly, you can
           remove all files from the cxx_repository subdirectory
           before you compile foo.cxx. This subdirectory should
           contain no instantiations after linking with the inst
           object file.

           If you have an inst.cxx file that contains many instan-
           tiations and you do not want all the symbols in the inst
           object file to be put into a user's executable even if
           only some symbols are used, (as happens with archive
           libraries), you can either split the inst.cxx into many
           smaller source files, or specify the -tused_repository
           qualifier to create the instantiations as separate object
           files in the repository (see Section 5.6). You must then
           link all the required individual object files in the
           repository into your library.

     5.5.5 Multiple Repositories

           As shown in Section 5.5.4, multiple repositories can be
           specified to link an application. The first repository
           named is the read-write repository, and when processing,
           the compiler writes instantiation object files into it. At
           link time, all repositories are read only.

           The repositories are searched in a linear order, iter-
           atively, and satisfy only the unresolved instantiations
           from each pass. That is, references from instantiations
           that are added in one pass are not resolved until the next
           pass. Consider the link line in the previous example:

              cxx -c -ptr ./cxx_repository -ptr lib_repository user_code.cxx mylib.a

           In this example, all references that could be resolved
           from lib_repository would be resolved in the first
           pass. Any reference arising from an instantiation in
           lib_repository in the first pass would be resolved by
           instantiations in ./cxx_repository in the second pass.

     5-20 Using Templates

 



                                                         Using Templates
                                                    5.6 Template Options

        5.6 Template Options

              Compaq C++ includes various template instantiation
              modes that control when, where, and how a template is
              instantiated:

              o  Manual instantiaion, automatic instantion, or both

              o  Placing templates in the output object or into a
                 repository

              o  Using local or external linkage

              o  As needed or complete instantiation

              A C++ program can cause the compiler to perform a template
              instantiation in two ways: explicitly or implicitly.
              A template instantiation is explicitly requested by
              using #pragma define_template, #pragma instantiate,
              or an explicit instantiation request (see Stroustrup,
              section C.13.10). A template instantiation is implicitly
              requested by simply using the template. Requesting a
              template instantiation explicitly is referred to as manual
              instantiation, while the process by which the compiler
              instantiates implicit requests is referred to as automatic
              template instantiation.

              When a template is manually instantiated, it is completely
              instantiated. For a template class, a complete instan-
              tiation means all its member functions and static data
              members are instantiated even if they were not used.
              Automatically instantiated templates may optionally be
              completely instantiated.

              Each of the following modes is mutually exclusive. Only
              one should be specified on the command line:

              -pt
              Automatically instantiate templates into the repository
              with external linkage. Manually instantiated templates are
              placed in the output object with external linkage. This
              option is the default.

              -tused
              Similar to -pt, except that automatically instantiated
              templates are placed in the output object.

                                                    Using Templates 5-21

 



     Using Templates
     5.6 Template Options

           -tused_repository (cxx -newcxx only)
           Similar to -pt, except that manually instantiated
           templates are placed in the repository.

           -nopt
           Disable automatic template instantiation. Manually
           instantiated templates are placed in the output object
           with external linkage.

           -define_templates
           -tall
           Automatically instantiate templates completely and place
           them in the output object with external linkage. Manually
           instantiated templates are also placed in the output
           object with external linkage.

           -tall_repository (cxx -newcxx only)
           Same as -tall except that all instantiations are placed in
           the repository instead of the output object. This option
           is useful for creating a pre-instantiation library.

           -tlocal
           Instantiate templates automatically, placing them in the
           output object with internal linkage. Manually instantiated
           templates are also placed in the output object with
           internal linkage. This option provides a simple mechanism
           for getting started with templates, but it has a number
           of limitations. Because the templates have local storage,
           they must be instantiated in every module that uses them,
           and code bloat could occur. In addition, a variable that
           would otherwise have a single global copy can instead have
           many local copies that do not share the same state.

           -timplicit_local (cxx -newcxx only)
           Same as -tlocal, except that manually instantiated
           templates are placed in the repository with external
           linkage. This is useful for build systems that need
           to have explicit control of the template instantiation
           mechanism. This mode can suffer the same limitations as
           -tlocal and is the default when -std gnu is specified.





     5-22 Using Templates

 



                                                         Using Templates
                                                    5.6 Template Options

              -tweak (cxx -newcxx only)
              Same as -timplicit_local, but automatically instantiated
              templates receive weak linkage. Weak linkage resembles
              external linkage, except that duplicate symbols do not
              result in a link error. The linker simply chooses one of
              the symbols. While this behavior can still result in code
              bloat, it avoids the problem of having multiple copies of
              the same variable not sharing the same state.

              The cxx command supports the following additional options
              for the instantiation of templates:

              -pending_instantiations n
              Limit the depth of recursive instantiations so that
              infinite instantiation loops can be detected before some
              resource is exhausted. -pending_instantiations requires
              a positive non-zero value n as argument and issues an
              error when n instantiations are pending for the same class
              template. The default value for n is 64.

              -ttimestamp (cxx -newcxx only)
              Used with automatic instantiation. Causes automatic
              instantiation to instantiate templates only if they
              are not already in the repository, or if the existing
              instantiations in the repository are older than the
              timestamp in the repository.

              -Hx
              Stops the cxx command after the prelinker runs and before
              the final link. Provided for compatibility with previous
              versions of C++.

              -[no]implicit_include (cxx -newcxx only)
              Effective only with Version 6.0 and later. Enable or
              disable inclusion of source files as a method of finding
              definitions of template entities. Implicit inclusion is
              enabled by default, and it is disabled when compiling with
              -E or -P. The search rules for finding template definition
              files are the same as for include files. This option also
              defines the macro __IMPLICIT_INCLUDE_ENABLED. You might
              want to disable implicit inclusion with the -ms and -std
              ms options to match the behavior on Microsoft C++ more
              closely.


                                                    Using Templates 5-23

 



     Using Templates
     5.6 Template Options

           -nopragma_template
           Directs the compiler to ignore any #pragma define_template
           directives. This option is provided for users who want to
           migrate quickly to automatic instantiation without having
           to remove all the pragma directives from their code base.

           -ptr dir
           Specifies a repository, with ./cxx_repository as the
           default. If you specify several repositories, only the
           first is writable, and the rest are read only. Read-
           only repositories are used only at link time. Specifying
           this option at link time enables C++ to recognize and use
           the template instantiation information files within the
           specified repository. If you use this option, make sure
           that the repository specified at compile time is the same
           one specified at link time.

           -ptsuf
           Specifies a list of file name suffixes that are valid
           for template definition files. Items in the list
           must be separated by commas and each suffix preceded
           by a period. A suffix may have no more than eight
           characters excluding the beginning period. The default
           is ".cxx,.CXX,.C,.cc,.CC,.cpp,.c".

           -ptv
           Turns on verbose or verify mode to display each phase of
           instantiation as it occurs. This option is useful as a
           debugging aid.

     5.7 Compatibility with Earlier Versions of C++

           The automatic template instantiation model is not
           directly compatible with previous C++ automatic template
           instantiation.

           The compiler invoked when you use the -oldcxx option is a
           Version 5.n compiler. Where possible, it is safest to
           start fresh with an empty repository, and create the
           required instantiations by compiling all source files.
           If this is not possible, there are some strategies that
           can be used to link mixed generation instantiations.



     5-24 Using Templates

 



                                                         Using Templates
                          5.7 Compatibility with Earlier Versions of C++

              If you used both Version 6.n and Version 5.n to build
              applications, Compaq strongly recommends that you use
              different repositories to contain automatic template in-
              stantiations for Version 6.n and Version 5.n compilations.

              The default repository name is the same for Version 6.n as
              for prior versions. Thus, if you use Version 6.n with
              older C++ compilers, you should do compilations in a
              different directory for each compiler or explicitly
              specify a different repository for each using the -ptr
              option.

        5.7.1 Linking with Version 5.n Instantiations

              When linking applications using Version 6.n against
              instantiations created with Version 5.n, it is necessary
              to complete the Version 5.n instantiation process, to
              create instantiation object files. This can be done with
              the -oldcxx and -Hx command-line options when linking.
              If old_repository is a Version 5.n repository then you
              would create the Version 5.n instantiation object files by
              using:

               cxx -oldcxx -Hx  -ptr old_repository <Version 5.n object files>

              The <Version 5.n object files> are the object files
              that were created using the Version 5.n compiler; old_
              repository now contains the instantiation object files.
              Create a library of these object files as follows:

               ar r lib_old_repository.a old_repository/*.o

              When linking using Version 6.n, specify lib_old_
              repository.a after all of the Version 5.n object files
              that are being linked.

              It is possible for repositories to reference objects in
              libraries that had not been referenced previously. If
              this case, you must specify the library on the command
              line again after the repository. The library might
              also reference objects not previously referenced. Some
              cycles might therefore require a single repository to be
              specified multiple times on the command line.


                                                    Using Templates 5-25

 



     Using Templates
     5.8 Linking Version 5.n Applications Against Version 6.n Repositories

     5.8 Linking Version 5.n Applications Against Version 6.n
         Repositories

           In a similar way, you can create a library of Version
           6.n instantiation object files to link into a Version 5.n
           application being linked using C++ Version 5.n. If new_
           repository is the Version 6.n repository, then a library
           of the instantiations would be created by:

            ar r lib_new_repository.a new_repository/*.o

           When linking using Version 5.n, specify lib_new_
           repository.a after all of the Version 6.n object files
           that are being linked.

           It is possible for repositories to reference objects in
           libraries that had not been referenced previously. If
           this case, you must specify the library on the command
           line again after the repository. The library might
           also reference objects not previously referenced. Some
           cycles might therefore require a single repository to be
           specified multiple times on the command line.























     5-26 Using Templates

 









                                                                       6
        ________________________________________________________________

                                                     Precompiled Headers



              Using precompiled header (PCH) files can dramatically
              reduce compilation time in environments where:

              o  Many primary sources include the same set of headers in
                 the same order.

              o  These headers introduce many lines of code.

              The Version 6.0 compiler provides a mechanism that, in
              effect, takes a snapshot of the compilation state at
              a particular point and writes it to a disk file before
              completing the compilation. Then, when recompiling the
              same source file or compiling another file with the same
              set of headers, the compiler can recognize the snapshop
              point, verify that the corresponding PCH file is reusable,
              and read it back in.

              PCH files can be large (from a minimum of 250 KB to
              several megabytes or more). To achieve the maximum
              performance gain at the smallest cost, as many sources as
              possible should share the same PCH files. The performance
              gain is thereby achieved at the smallest cost in disk
              storage. Compaq C++ for Linux Alpha does not support
              precompiled headers.

              This chapter describes mechanisms used to generate and
              process PCH files. Topics include the following:

              o  Automatic precompiled header processing

              o  Manual precompiled header processing

              o  Other ways to control precompiled headers

              o  Performance issues

              Section 6.5 describes command-line options.

                                                 Precompiled Headers 6-1

 



     Precompiled Headers
     6.1 Automatic Precompiled Header Processing

     6.1 Automatic Precompiled Header Processing

           You enable automatic precompiled header process-
           ing by specifying the -pch command-line option (see
           Section 6.5). The compiler automatically looks for a
           qualifying precompiled header file to read in, or it
           creates one for use on a subsequent compilation. In some
           cases, it performs both operations.

           The PCH file contains a snapshot of all the code preceding
           the header stop point, typically the first token in
           the primary source file that does not belong to a
           preprocessing directive. You also can specify the stop
           point directly by using #pragma hdrstop if that comes
           first (see Section 6.3). For example:

                #include "xxx.h"
                #include "yyy.h"
                int i;

           The header stop point is int (the first nonpreprocessor
           token), and the PCH file contains a snapshot reflecting
           the inclusion of xxx.h and yyy.h. If the first non
           preprocessor token or the #pragma hdrstop appears within
           a #if block, the header stop point is the outermost
           enclosing #if. For example:

                #include "xxx.h"
                #ifndef YYY_H
                #define YYY_H 1
                #include "yyy.h"
                #endif
                #if TEST
                int i;
                #endif

           Here, the first token that does not belong to a prepro-
           cessing directive is again int, but the header stop point
           is the start of the #if block containing it. The PCH file
           reflects the inclusion of xxx.h and conditionally the
           definition of YYY_H and inclusion of yyy.h; it does not
           contain the state produced by #if TEST.



     6-2 Precompiled Headers

 



                                                     Precompiled Headers
                             6.1 Automatic Precompiled Header Processing

              A PCH file is produced only if the header stop point
              and the code preceding it (mainly, the header files
              themselves) meet the following requirements:

              o  The header stop point must appear at file scope-it may
                 not be within an unclosed scope established by a header
                 file. For example, a PCH file is not created in this
                 case:

                          // xxx.h
                          class A {

                          // xxx.C
                          #include "xxx.h"
                          int i; };

                 The header stop point may not be inside a declaration
                 started within a header file, nor may it be part of
                 a declaration list of a linkage specification. For
                 example, in the following case the header stop point
                 is int, but because it is not the start of a new
                 declaration, no PCH file is created:

                          // yyy.h
                          static

                          // yyy.C
                          #include "yyy.h"
                          int i;

              o  The header stop point cannot be inside a #if block or
                 a #define started within a header file. The processing
                 preceding the header stop must not have produced any
                 errors. (Warnings and other diagnostics are generally
                 not reproduced when the PCH file is reused.)

                 No references to predefined macros __DATE__ or
                 __TIME__ may have appeared. No use of the #line
                 preprocessing directive may have appeared; #pragma no_
                 pch (see Section 6.3) must not have appeared. The code
                 preceding the header stop point must have introduced
                 a sufficient number of declarations to justify the
                 overhead associated with precompiled headers.


                                                 Precompiled Headers 6-3

 



     Precompiled Headers
     6.1 Automatic Precompiled Header Processing

           When a precompiled header file is produced, it contains,
           in addition to the snapshot of the compiler state, some
           information that can be checked to determine under what
           circumstances it can be reused. This includes:

           o  The compiler version, including the date and time the
              compiler was built

           o  The current directory (that is, the directory in which
              the compilation is occurring)

           o  The command-line options

           o  The initial sequence of preprocessing directives from
              the primary source file, including #include directives

           o  The date and time of the header files specified in
              #include directives

           This information comprises the PCH prefix. The prefix
           information of a given source file can be compared to the
           prefix information of a PCH file to determine whether the
           latter is applicable to the current compilation.

           As an illustration, consider two source files:

                // a.C
                #include "xxx.h"
                 . . .          // Start of code

                // b.C
                #include "xxx.h"
                 . . .          // Start of code

           When a.C is compiled with -pch:

           1. A precompiled header file named a.pch is created.

           2. When b.C is compiled (or when a.C is recompiled), the
              prefix section of a.pch is read in for comparison with
              the current source file.

           If the command-line options are identical, if xxx.h has
           not been modified, and so forth, then, instead of opening
           xxx.h and processing it line by line, the compiler reads
           in the rest of a.pch and thereby establishes the state for
           the rest of the compilation.

     6-4 Precompiled Headers

 



                                                     Precompiled Headers
                             6.1 Automatic Precompiled Header Processing

              It may be that more than one PCH file is applicable to
              a given compilation. If so, the largest (that is,the one
              representing the most preprocessing directives from the
              primary source file) is used. For instance, consider a
              primary source file that begins as follows:

                   #include "xxx.h"
                   #include "yyy.h"
                   #include "zzz.h"

              If there is one PCH file for xxx.h and a second for xxx.h
              and yyy.h, the latter will be selected (assuming both are
              applicable to the current compilation). Moreover, after
              the PCH file for the first two headers is read in and the
              third is compiled, a new PCH file for all three headers
              may be created.

              When a precompiled header file is created, it takes the
              name of the primary source file, with the suffix replaced
              by .pch. Unless -pch_dir is specified, it is created in
              the current directory.

              When a precompiled header file is created or used, a
              message such as the following is issued:

                   "test.C": creating precompiled header file "test.pch"

              The user may suppress the message by using the command-
              line option -no_pch_messages.

              In automatic mode (that is, when -pch is used) the
              compiler will deem a precompiled header file obsolete
              and delete it under either of the following circumstances:

              o  The precompiled header file is based on at least one
                 out-of-date header file but is otherwise applicable for
                 the current compilation.

              o  The precompiled header file has the same base name as
                 the source file being compiled (for example, xxx.pch
                 and xxx.C) but is not applicable for the current
                 compilation (for example, because of different command-
                 line options).

              This handles some common cases; the user must manage other
              PCH file clean up.

                                                 Precompiled Headers 6-5

 



     Precompiled Headers
     6.1 Automatic Precompiled Header Processing

           Only header files that were included in the original PCH
           file are checked for modification. If the user changes
           the structure of the header files, such that different
           files would be included now from when the PCH file was
           generated, without modifying at least one of the original
           header files that were included in the PCH file, the
           change would go undetected, and an out of date PCH file
           would be used.

           For example, adding a prolog or epilog file to a directory
           that previously did not have one would not automatically
           result in a new PCH file being created.

           Also, consider the following:

            cxx -Iinc1 -Iinc2 -pch foo.c

           Where foo.c includes the file foo.h. If file foo.h is
           found in directory inc2 when the PCH file is created, but
           a new foo.h is added to directory inc1, thereby hiding the
           old foo.h in inc2, a new PCH file would not be created.

           It is the user's responsibility to remove any PCH
           files that may be out of date because of these kinds of
           changes.

     6.2 Manual Precompiled Header Processing

           Command-line option -create_pch file-name specifies that
           a precompiled header file of the specified name should be
           created.

           Command-line option -use_pch file-name specifies that the
           indicated precompiled header file should be used for this
           compilation; if it is invalid (that is, if its prefix does
           not match the prefix for the current primary source file),
           a warning will be issued and the PCH file will not be
           used.

           When either of these options is used in conjunction with
           -pch_dir, the indicated file name (which may be a path
           name) is tacked on to the directory name, unless the file
           name is an absolute path name.


     6-6 Precompiled Headers

 



                                                     Precompiled Headers
                                6.2 Manual Precompiled Header Processing

              The -create_pch, -use_pch, and -pch options may not be
              used together. If more than one of these options is
              specified, only the last one will apply. Nevertheless,
              most of the description of automatic PCH processing
              applies to one or the other of these modes-header stop
              points are determined the same way, PCH file applicability
              is determined the same way, and so forth.

        6.3 Other Ways for Users To Control Precompiled Headers

              The user can control and tune how precompiled headers are
              created and used in several ways:

              o  #pragma hdrstop may be inserted in the primary source
                 file at a point prior to the first token that does not
                 belong to a preprocessing directive. This enables the
                 user to specify where the set of header files that is
                 subject to precompilation ends. For example,

                          #include "xxx.h"
                          #include "yyy.h"
                          #pragma hdrstop
                          #include "zzz.h"

                 Here, the precompiled header file includes processing
                 state for xxx.h and yyy.h but not zzz.h. (This is
                 useful if the user decides that the information added
                 by what follows the #pragma hdrstop does not justify
                 the creation of another PCH file.)

              o  #pragma no_pch may be used to prevent the generation of
                 a pch file for a given source.

                 Command-line option -pch_dir directory-name is used to
                 specify the directory in which to search for or create
                 a PCH file.

        6.4 Performance Issues

              The relative overhead incurred in writing out and reading
              back in a precompiled header file is quite small for
              reasonably large header files.



                                                 Precompiled Headers 6-7

 



     Precompiled Headers
     6.4 Performance Issues

           In general, it does not cost much to write a precompiled
           header file even if it does not end up being used, and
           if it is used, it almost always produces a significant
           decrease in compilation time.

           Despite the faster recompilations, precompiled header
           processing is not likely to be justified for an arbitrary
           set of files with nonuniform initial sequences of
           preprocessing directives.

           The greatest benefit occurs when a number of source files
           can share the same PCH file. The more sharing, the less
           disk space is consumed. With sharing, the disadvantage of
           large precompiled header files can be minimized, without
           giving up the advantage of a significant decrease in
           compilation times.

           Consequently, to take full advantage of header file
           precompilation, users should expect to reorder the
           #include sections of their source files and to group
           #include directives within a commonly used header file.

           Different environments and different projects will have
           different needs, but in general, users should be aware
           that making the best use of the precompiled header support
           will require some experimentation and probably some minor
           changes to source code.

     6.5 Command-Line Options for Precompiled Headers

           You can specify the following options for precompiled
           headers:

           -create_pch file-name
           If other conditions are satisfied, create a precompiled
           header file with the specified name. If -pch (automatic
           PCH mode) or -use_pch appears on the command line
           following this option, the last option is used. This
           option defines the macro __PCH_ENABLED.

           -pch
           Automatically use, create, or both, a precompiled header
           file. If -use_pch or -create_pch (manual PCH mode) appears
           on the command line following this option, the last option
           is used. This option defines the macro __PCH_ENABLED.

     6-8 Precompiled Headers

 



                                                     Precompiled Headers
                        6.5 Command-Line Options for Precompiled Headers

              -pch_dir directory-name
              The directory in which to search for, create, or both,
              a precompiled header file. You can use this option with
              automatic PCH mode (-pch) or manual PCH mode (-create_pch
              or -use_pch).

              -pch_messages
              -no_pch_messages
              Enable or disable the display of a message indicating
              that a precompiled header file was created or used in the
              current compilation. The default is -pch_messages.

              -use_pch file-name
              Use a precompiled header file of the specified name as
              part of the current compilation. If -pch (automatic PCH
              mode) or -create_pch appears on the command line following
              this option, the last option is used. This option defines
              the macro __PCH_ENABLED.



























                                                 Precompiled Headers 6-9

 









                                                                       7
        ________________________________________________________________

                                                The C++ Standard Library



              The C++ Standard Library provided with this release
              defines a complete specification of the International
              C++ Standard, with some differences, as described in the
              online release notes in:

              /usr/lib/cmplrs/cxx/CompaqCXXversion.release-notes

              or

              /usr/lib/compaq/cxx-version/alpha-linux/doc/readme.ps | .txt

              The Standard Library in this release includes the ANSI
              locale and iostream libraries.

              Portions of the ANSI C++ Standard Library have been
              implemented in Compaq 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 Compaq C++ documentation with permission
              of Rogue Wave Software, Inc. All rights reserved.

              On Tru64 UNIX, some of the components in the C++ Standard
              Library are designed to replace nonstandard components
              that are currently distributed in the Class Library.
              The Class Library will continue to be provided in its
              nonstandard form. However, you now have the option of
              using new standard components.

              In this release, the shared libraries for the Complex and
              Task packages have been removed from the compiler kit. The
              redistribution kits that ship on the Tru64 Associated
              Products disribution have been removed from releases
              after Tru64 5.0A. Although applications can continue to
              use these libraries, they are linked statically. These
              libraries may be completely removed in a future release.

                                            The C++ Standard Library 7-1

 



     The C++ Standard Library


           Compaq recommends that code using complex be migrated
           as documented in Section 7.5.4. Code using task should
           migrate to using Posix Threads (see man pthread).

           This chapter provides information about the implementation
           of the Standard Library, including upward compatibility,
           compiling, linking, and thread safety. Small example
           programs showing how to use the C++ standard library are
           located in the directory /usr/examples/cxx.

           The following are Standard Library options:

           -[no]using_std
           Controls whether Standard Library header files are
           processed as though the compiled code were written as
           follows:

                using namespace std;
                #include <header>

           These options are provided for compatibility for users who
           do not want to qualify use of each Standard Library name
           with std:: or put using namespace std; at the top of their
           sources.

           -using_std turns implicit using namespace std on; this is
           the default when compiling -std arm, -std cfront, -std ms,
           or -std ansi.

           -nousing_std turns implicit using namespace std off; this
           is the default when compiling -std strict_ansi or -std
           strict_ansi_errors.

           -[no]stdnew
           Controls whether calls are generated to the ANSI or pre-
           ANSI implementation of the operator new(). On memory
           allocation failure, the ANSI implementation throws
           std::bad_alloc, while the pre-ANSI implementation returns
           0.

           -stdnew generates calls to the ANSI new() implementation;
           this is the default when compiling -std ansi, -std strict_
           ansi and -std strict_ansi_errors.

           -nostdnew generates calls to the pre-ANSI new() implemen-
           tation; this is the default when compiling -std arm, -std
           cfront and -std ms.

     7-2 The C++ Standard Library

 



                                                The C++ Standard Library


              -[no]global_array_new
              Controls whether calls to global array new and delete are
              generated as specified by ANSI. Pre-ANSI global array new
              generated calls to operator new(). According to ANSI, use
              of global array new generate calls to operator new()[].

              -global_array_new generates calls to operator new()[] for
              global array new expressions such as new int[4]; this is
              the default when compiling -std ansi, -std strict_ansi,
              -std strict_ansi_errors, and -std ms.

              -noglobal_array_new generates calls to operator new()
              for global array new expressions such as new int[4] and
              preserves compatibility with Version 5.n; this is the
              default when compiling -std arm and -std cfront.

        7.1 Important Compatibility Information

              The following sections describe specific compatibility
              issues.

        7.1.1 -[no]using_std Compiler Compatibility Switch

              All Standard Library names in Compaq C++ are inside the
              namespace std. Typically you would qualify each Standard
              Library name with std:: or put using namespace std; at the
              top of your source file.

              To make things easier for existing users, using namespace
              std; is included in a file provided with every Standard
              Library header when you are in arm, cfront, gnu, ms, or
              ansi compiler modes. This is not the default in strict_
              ansi or strict_ansi_errors mode.

              The compiler supplied switches -nousing_std and -using_std
              can be used to override the default. -nousing_std turns
              the implicit using namespace std off; -using_std turns it
              on.







                                            The C++ Standard Library 7-3

 



     The C++ Standard Library
     7.1 Important Compatibility Information

     7.1.2 Pre-ANSI/ANSI Iostreams Compatibility

           The C++ Standard Library offers support for the standard
           iostreams library based on the International C++ Standard.
           These standard iostream classes are in the new header
           files <iostream>, <ostream>, <istream>, and so on (no .h
           or .hxx extension).

           For backward compatibility, the pre-ANSI iostream library
           is still provided in the old header files iostream.hxx,
           istream.hxx, and so on. The two libraries exhibit subtle
           differences and incompatibilities.

           Users can choose which version (ANSI or pre-ANSI) of
           iostreams they want to use; either version of iostreams
           can be integrated seamlessly with the new Standard Library
           and string functionality.

           To accomplish this goal, macros called __USE_STD_IOSTREAM
           and
           __NO_USE_STD_IOSTREAM are provided. If you do not set
           these macros explicitly, the default in arm, cfront,
           gnu, ms, and ansi modes is to use the pre-ANSI iostream
           library. In strict_ansi and strict_ansi_errors mode, the
           default is to use the ANSI iostreams library.

           You override the default by defining __USE_STD_IOSTREAM
           or
           __NO_USE_STD_IOSTREAM on either the command line or in
           your source code.

           In arm, cfront, ms, and ansi modes, specify use of the
           ANSI iostreams in one of the following ways:

           o  Enter -D__USE_STD_IOSTREAM on the command line.

           o  Put #define __USE_STD_IOSTREAM in your source file
              before any include files.

           In strict_ansi and strict_ansi_errors modes specify use of
           the pre-ANSI iostreams in one of the following ways:

           o  Enter -D__NO_USE_STD_IOSTREAM on the command line.

           o  Put #define __NO_USE_STD_IOSTREAM in your source file
              before any include files.

     7-4 The C++ Standard Library

 



                                                The C++ Standard Library
                                 7.1 Important Compatibility Information

              A #error warning appears:

              1. If you have explicitly included the wrong header for
                 the current mode. For example, if you say #include
                 <iostream> (an ANSI header) and you are in -std ansi,
                 -std cfront, gnu, -std ms or -std arm mode, and if you
                 have not entered -D__USE_STD_IOSTREAM on the command
                 line, an error message appears.

              2. If you are in -std strict_ansi or -std strict_ansi_
                 errors, and you enter #include <iostream.h>, an error
                 message appears unless you also enter -D__NO_USE_STD_
                 IOSTREAM.

              Many of the other headers, <string> for example, make
              use of the iostream classes. The default version of
              iostreams that is automatically included when you include
              one of these headers depends on the mode you compile in
              and the setting of the macros __USE_STD_IOSTREAM and
              __NO_USE_STD_IOSTREAM as described earlier.

              Because the standard locale class and the standard
              iostream class are so closely tied, you cannot use the
              standard locale class with the pre-standard iostream
              classes. If you want to use locale, you must use the
              standard iostream classes.

              It is possible to use the pre-ANSI and the ANSI iostream
              library in the same source file, because all the standard
              iostream names (that is, cout, cin, and so on) are in
              namespace std, and all the pre-ANSI names are in the
              global namespace. This is not recommended, though,
              because there is no guarantee of stream objects being
              the same size or, for example, of ::cout being in sync
              with std::cout.

              To do this in all modes, include a pre-ANSI iostreams
              header before an ANSI iostreams header as follows:

                #include <stdlib.h>
                #undef __USE_STD_IOSTREAM
                #include <iostream.h>
                #define __USE_STD_IOSTREAM
                #include <iostream>

                                            The C++ Standard Library 7-5

 



     The C++ Standard Library
     7.1 Important Compatibility Information

             int main()
             {
               std::string s("abc");
               ::cout << "abc" << endl;         // pre-standard iostreams
               std::cout << "abc" << std::endl; // standard iostreams
               return EXIT_SUCCESS;
             }

           To do this in all modes, if you include an ANSI iostreams
           header before a pre-ANSI iostreams header, follow these
           steps:

           1. Compile your source using -nousing_std.

           2. Use the __USE_STD_IOSTREAM macro as shown in the
              following example. You must define __USE_STD_IOSTREAM
              at the end of your include file list so that the
              template definition files (the .cc files) are included
              in the correct mode.

                // Compile this with -nousing_std
                #include <stdlib.h>
                #define __USE_STD_IOSTREAM
                #include <iostream>
                #undef __USE_STD_IOSTREAM
                #include <iostream.h>
                #define __USE_STD_IOSTREAM // so the template definition files are ok

                int main()
                {
                  std::string s("abc");
                  ::cout << "abc" << endl; // pre-standard iostreams
                  std::cout << "abc" << std::endl; // standard iostreams
                  return EXIT_SUCCESS;
                }

     7.1.3 Support for pre-ANSI and ANSI operator new()

           The Standard C++ Library supports the ANSI implementation
           of the operator new() as well as the pre-ANSI implemen-
           tation of operator new(). The ANSI implementation throws
           std::bad_alloc on memory allocation failures.



     7-6 The C++ Standard Library

 



                                                The C++ Standard Library
                                 7.1 Important Compatibility Information

              The pre-ANSI implementation of the operator new() returns
              0 on memory allocation failures. Because the ANSI behavior
              is incompatible with pre-ANSI applications, a compile time
              switch has been added (-[no]stdnew) to control whether
              calls to ANSI new() or pre-ANSI new are generated.

              The following examples show how ANSI versus pre-ANSI
              new() check for memory allocation. First, here is an
              ANSI new() check for memory allocation failure:

                          try {
                              myobjptr = new (myobj);
                          }
                          catch (std::bad_alloc e) {
                              cout << e.what() << endl;
                          };

              The following example shows a pre-ANSI new() check for
              memory allocation failure:

                          if ((myobjptr = new (myobj)) == 0)
                              call_failure_routine();

              When upgrading pre-ANSI new() code to work with the C++
              Standard Library you also can use the nothrow version of
              ANSI new(). To do so in the pre-ANSI example, you could
              recode it as follows:

                          if ((myobjptr = new (myobj, nothrow)) == 0)
                               call_failure_routine();

              Two command line switches are available in the compiler
              to control whether calls are generated to the ANSI or
              pre-ANSI implementation of operator new(). Use the
              -stdnew switch to generate calls to the ANSI new()
              implementation. Use the -nostdnew switch to generate calls
              to the pre-ANSI new() implementation.

              You can override global new() by declaring your own
              functions.

              When compiling with -std ansi, -std strict_ansi, and -std
              strict_ansi_errors, -stdnew is the default. When compiling
              with -std arm, -std cfront, gnu, and -std ms, -nostdnew is
              the default. The compiler defines the macro __STDNEW when
              the -stdnew option is specified.

                                            The C++ Standard Library 7-7

 



     The C++ Standard Library
     7.1 Important Compatibility Information

     7.1.4 Overriding operator new()

           If you want to define a global operator new() to displace
           the version used by the C++ Standard Library or C++ Class
           Library, follow these steps:

           1. Define a module that will contain two entry points for
              your version of global operator new(): one for the
              Standard Library and one for the Class Library.

              When you link with this module, your version of the
              global operator new() displaces the version used by
              either the C++ Standard Library or C++ Class Library.

           2. Decide whether you want to compile the module using the
              -stdnew or the -nostdnew option. You must always use
              the same option when compiling the module.

           3. Code the module for the compilation method you have
              chosen, as follows:

              For module to be compiled with -stdnew

              1. Include two entry points for your version of global
                 operator new():

                 o  __7__nw__FUl  (-model ansi) or __nw__XUl  (-model
                    arm), which is used to override global operator
                    new() in the Class Library. This entry point has
                    the name generated by the Class Library version
                    of global operator new(), which is the mangled
                    name used in the Class Library.

                 o  new, which is used to override global operator
                    new() in the Standard Library. This entry point
                    has the name generated by the Standard Library
                    version of global operator new().

              2. Define global operator new() in terms of the entry
                 point new. The __7__nw__FUl  (-model ansi) or
                 __nw__XUl  (-model arm) version is declared with
                 extern C and simply calls the first version. Your
                 module will contain two routines similar to the
                 following:

     7-8 The C++ Standard Library

 



                                                The C++ Standard Library
                                 7.1 Important Compatibility Information

                         #include <new>
                         ...

                         // Redefine global operator new(),
                         // entry point into C++ Standard Library.
                         // Also override user calls to operator new()

                         void *operator new(size_t size) throw(std::bad_alloc) {
                         printf("in my global new\n");
                         ...
                         }

                         // Entry point into C++ Class Library

                         #ifdef __MODEL_ANSI
                         extern "C" void *__7__nw__FUl(size_t size) {
                         #else  //__MODEL_ARM
                         extern "C" void *__nw__XUl(size_t size) {
                         #endif
                              return ::operator new(size);
                         }

                 For module to be compiled with -nostdnew

                 1. Include two entry points for your version of global
                    operator new():

                    o  __7__stdnw__FUl  (-model ansi) or __stdnw__XUl
                       (-model arm), which is used to override global
                       operator new() in the Standard Library. This
                       entry point has the name generated by the
                       Standard Library version of global operator
                       new(), which is the mangled name used in the
                       Standard Library.

                    o  new, which is used to override global operator
                       new() in the Class Library. This entry point has
                       the name generated by the Class Library version
                       of global operator new().

                 2. Define global operator new in terms of the entry
                    point new. The __7__stdnw__FUl  (-model ansi) or
                    __stdnw__XUl (-model arm) version is declared with
                    extern C and simply calls the first version. Your
                    module will contain two routines similar to the
                    following:

                                            The C++ Standard Library 7-9

 



     The C++ Standard Library
     7.1 Important Compatibility Information

                      #include <new>
                      ...

                      // Redefine global operator new(),
                      // entry point into C++ Class Library.
                      // Also override user calls to operator new().

                      void *operator new(size_t size) {
                      printf("in my global new\n");
                      ...
                      }

                      // Entry point into C++ Standard Library

                      #ifdef __MODEL_ANSI
                      extern "C" void *__7__stdnw__FUl(size_t size) {
                      #else  //__MODEL_ARM
                      extern "C" void *__stdnw__XUl(size_t size) {
                      #endif
                           return ::operator new(size);
                      }

     7.1.5 Support for Global array new and delete Operators

           Compaq C++ Version 6.n fully supports the array new
           and delete operators as described in the ANSI standard.
           Previous versions did not. You might therefore encounter a
           compatibility problem if you have overridden the run-time
           library's operator new() with your own version.

           For example:

           #include <stdlib.h>
           #include <iostream.h>

           inline void* operator new(size_t s) {
            cout << "called my operator new" << endl;
            return 0;
           }

           int main() {
            new int;    // ok, this still calls your own
            new int[4]; // In V6.0 calls the C++ library's operator new[]
                   return EXIT_SUCCESS;
           }

     7-10 The C++ Standard Library

 



                                                The C++ Standard Library
                                 7.1 Important Compatibility Information

              In older versions, both new int and new int[4] would
              generate a call to operator new() (they would just be
              asking for different sizes). With the current compiler,
              new int still generates a call to operator new().
              However, new int[4] generates a call to operator new()[].
              This means that if you still want to override the
              library's operator new you must do one of the following:

              1. Provide your own definition of operator new()[].

              2. Use the -noglobal_array_new switch.

              The -noglobal_array_new switch converts all expressions
              such as new int[4] to calls to the global operator
              new(), thus preserving compatibility with older compiler
              versions.

              This switch has no effect on class-specific array operator
              new and delete; it affects only the global operators.

              When compiling with -std ansi, -std strict_ansi, -std
              strict_ansi_errors, and -std ms modes, -global_array_
              new is the default. When compiling with -std arm or -std
              cfront modes, -noglobal_array_new is the default. A macro
              __GLOBAL_ARRAY_NEW is predefined by the compiler when
              -global_array_new is used.

        7.2 How to Build Programs Using the C++ Standard Library

              When you use the cxx command to compile and link programs
              that use the C++ Standard Library, no special switches are
              required. The Compaq C++ driver automatically includes the
              Standard Library run-time support (-lcxxstd) on the link
              command, and automatic template instantiation (-pt) is the
              default mode.

              For example, to build a program called prog.cxx that uses
              the Standard Library, you can simply use the following
              command:

              cxx prog.cxx

                _______________ [Tru64] Thread Safety _______________

                The Standard Library provided with this release is
                thread safe but not thread reentrant. Thread safe
                means that all library internal and global data

                                           The C++ Standard Library 7-11

 



     The C++ Standard Library
     7.2 How to Build Programs Using the C++ Standard Library

              is protected from simultaneous access by multiple
              threads. In this way, internal buffers as well as
              global data like cin and cout are protected during
              each individual library operation. Users, however,
              are responsible for protecting their own objects.

              According to the C++ standard, results of recursive
              initialization are undefined. To guarantee thread
              safety, the compiler inserts code to implement a
              spinlock if another thread is initializing local
              static data. If recursive initialization occurs, the
              code deadlocks even if threads are not used.

              _____________________________________________________

              _______________ [Linux] Thread Safety _______________

              The Standard Library provided with Compaq C++ for
              Linux Alpha is not thread safe.

              _____________________________________________________

     7.3 Optional Switch to Control Buffering

           The inplace_merge, stable_sort, and stable_partition
           algorithms require the use of a temporary buffer. Two
           methods are available for allocating this buffer:

           o  Preallocate 16K bytes of space on the stack.

           o  Allocate the required amount of storage dynamically.

           By default, the current library makes use of the
           preallocated buffer, which avoids the overhead of run-time
           allocation. If your application requires a buffer that
           exceeds 16K, it can not take advantage of this default.

           If you are concerned with minimizing the use of stack
           space in your program, or if your application requires
           a buffer that exceeds 16K, define the __DEC_DYN_ALLOC
           macro to enable dynamic buffering. Do this by adding the
           following to your compile command line:

           -D__DEC_DYN_ALLOC

     7-12 The C++ Standard Library

 



                                                The C++ Standard Library
                 7.4 Enhanced Compile-time Performance of ANSI Iostreams

        7.4 Enhanced Compile-time Performance of ANSI Iostreams

              To speed up the compile-time performance of programs that
              use the standard iostream and locale components, many
              common template instantiations of these components have
              been included in the Standard Library.

              To force programs to create instantiations at compile-
              time (for example, if you want to debug them and thus
              need them to be compiled with the -gall option), define
              the macro __FORCE_INSTANTIATIONS on the command line.
              This definition suppresses the #pragma do_not_instantiate
              directives in the headers so that the compiler creates the
              instantiations in your repository directory.

              You must then specify the -nopreinst option to force the
              compiler to link your instantiations instead of those in
              the Standard Library.

        7.5 Upgrading from the Class Library to the Version 6.n
            Standard Library

              The following discussion guides you through upgrading
              the Class Library code to use the Standard Library,
              specifically replacing the vector and stack classes in
              the vector.hxx header file to the Standard Library vector
              and stack classes.

        7.5.1 Upgrading from the Class Library Vector to the Standard
              Library Vector

              To change your code from using the Class Library vector
              to the Standard Library vector, consider the following
              actions:

              o  Change the name of your #include statement from
                 <vector.h> or <vector.hxx> to <vector>.

              o  Remove the vectordeclare and vectorimplement declara-
                 tions from your code.

              o  Change all vector(type) declarations to vector<type>.
                 For example, vector(int) vi should become vector<int>
                 vi.

                                           The C++ Standard Library 7-13

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

           o  Note that the following member functions are replaced
              in the Standard Library:

              _______________________________________________________
              Nonstandard Vector      Standard Library Vector
              Function________________Function_______________________

              elem(int index)         operator[](size_t index)
                                      (no bounds checking)

              operator[](int index)   at(size_t index)
                                      (bounds checking)

              setsize(int_newsize)____resize(size_t_newsize)_________

           o  When copying vectors of unequal lengths, note that the
              Standard Library vector has a different behavior as
              follows:

              When using the Standard Library vector, if the target
              vector is smaller than the source vector, the target
              vector automatically increases to accommodate the
              additional elements.

              The Class Library vector displays an error and aborts
              when this situation occurs.

           o  Another difference in behavior occurs when you specify
              a negative index for a vector.

              The Class Library vector class detects the negative
              specification and issues an error message. However, the
              Standard Library vector silently converts the negative
              value to a large positive value, because indices are
              represented as type size_t (unsigned long) rather than
              int.

           o  When an out-of-bounds error occurs, the Class Library
              vector prints an error message and aborts, whereas the
              Standard Library vector throws an out-of-range object.





     7-14 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

        7.5.2 Upgrading from the Class Library Stack to the Standard
              Library Stack

              To change your code from using the existing stack to the
              Standard Library stack, consider the following actions:

              o  Change the name of your #include statement from
                 <stack.h> or <stack.hxx> to <stack>.

              o  Remove the stackdeclare and stackimplement declarations
                 from your code.

              o  Change all stack(type) declarations to stack<type,
                 deque<type> >. For example, stack(int) si should become
                 stack<int, deque<int> > si.

              o  Do not specify an initial size for a Standard Library
                 stack. The stack must start out empty and grow
                 dynamically (as you push and pop).

              o  The following member functions are not supported or
                 have different semantics:

                 _______________________________________________________
                 Class_Library_Stack___Standard_Library_Stack___________

                 size_used()           Does not exist because the
                                       size() function always is equal
                                       to the size_used() function.

                 full()                Does not exist because the stack
                                       always is full.

                 pop()                 Does not return the popped
                                       element. To simulate Class
                                       Library behavior, first obtain
                                       the element as the return type
                                       from the top() function and then
                                       call the pop() function. For
                                       example, change int i=s.pop();
                                       to the following:

                                       int i=s.top();
                 ______________________s.pop();_________________________

              o  The Standard Library stack differs from the Class
                 Library stack in the way errors are detected. Unlike
                 the nonstandard stack, you cannot overflow a Standard

                                           The C++ Standard Library 7-15

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

              Library stack because space is allocated dynamically as
              you push elements onto the stack.

     7.5.3 Upgrading from the Class Library String Package Code

           The Standard Library basic_string can replace the Class
           Library String Package.

           The following list guides you through upgrading nonstan-
           dard code to use the Standard Library basic_string:

           o  Change #include <string.h> or #include <string.hxx> to
              #include <string>.

           o  Change all declarations of String to string (uppercase
              S to lowercase s).

           o  The String Package allowed assignment of a string
              directly to a char *; however, the basic_string library
              does not allow this. You can assign the string's const
              char* representation using the c_str() or data()
              basic_string member functions. For example:

              string s("abc");
              char* cp = s; // not allowed
              const char* cp = s.data(); // ok

              The state of the string is undefined if the result of
              data() is cast to a non-const char* and then the value
              of that char* is changed.

           o  The String Package member functions upper() and
              lower() are not in the basic_string library. You
              can write these functions as nonmember functions, as
              follows:

              template <class charT, class traits, class Allocator>
              inline
              basic_string<charT, traits, Allocator>
              upper(const basic_string<charT,traits, Allocator>& str) {
                      basic_string<charT, traits, Allocator> newstr(str);
                      for (size_t index = 0; index < str.length(); index++)
                              if (islower(str[index]))
                                      newstr[index] = toupper(str[index]);
                      return newstr;
              }

     7-16 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

                 template <class charT, class traits, class Allocator>
                 inline
                 basic_string<charT, traits, Allocator>
                 lower(const basic_string<charT,traits, Allocator>& str) {
                         basic_string<charT, traits, Allocator> newstr(str);
                         for (size_t index = 0; index < str.length(); index++)
                                 if (isupper(str[index]))
                                         newstr[index] = tolower(str[index]);
                         return newstr;
                 }

                 Then instead of calling upper() and lower() as member
                 functions of the basic_string, pass the string as an
                 argument. For example:

                 s2 = s1.upper(); // does not compile
                 s2 = upper(s1); // ok

              o  The String Package match() member function does not
                 exist. Equivalent functionality exists in the Standard
                 Library algorithm mismatch(), although using it is
                 more complicated. For example:

                 string s1("abcdef");
                 string s2("abcdgf");
                 assert(s1.match(s2)==4); // does not compile
                 pair<string::iterator,string::iterator> p(0,0); // ok
                 p=mismatch(s1.begin(),s1.end(),s2.begin());
                 assert(p.first-s1.begin()==4);
                 string s3 = s1;
                 p=mismatch(s1.begin(),s1.end(),s3.begin());
                 assert(p.first == s1.end()); // everything matched

              o  The String Package index() member function does not
                 exist. The basic_string library equivalent is find().

              o  The String Package constructor that takes two
                 positional parameters (a start and end position) and
                 constructs a new string does not exist. It is replaced
                 in the basic_string library with the member function
                 substr(). For example:

                 string s1("abcde");
                 string s2 = s1(1,3); // does not compile
                 string s2 = s1.substr(1,3); // ok

                                           The C++ Standard Library 7-17

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

           o  Many previously undetected run-time errors now throw
              standard exceptions in the String library.

     7.5.4 Upgrading from the Class Library Complex to the ANSI
           Complex Class

           This section explains how to upgrade from the pre-ANSI
           complex library to the current standard complex library.

           In the pre-ANSI library, complex objects are not
           templatized. In the ANSI library, complex objects are
           templatized on the type of the real and imaginary parts.
           The pre-ANSI library assumes the type is double, whereas
           the ANSI library provides specializations for float,
           double, and long double as well as allowing users to
           specialize on their own floating point types.

           Mathematical error checking is not supported in the
           ANSI library. Users who rely on detection of underflow,
           overflow, and divide by zero should continue using the
           pre-ANSI complex library.

           The following is a detailed list of important changes:

           o  Change #include <complex.h> or #include <complex.hxx>
              to #include <complex>.

           o  Change all declarations of complex to complex<double>,
              for example:

              complex c;

              Change to:

              complex<double> c;

           o  The polar() function no longer supplies a default
              value of 0 for the second argument. Users will have
              to explicitly add it to any calls that have only one
              argument, for example:

              complex c;
              c = polar(c); // get polar

              Change to:

              complex<double> c;
              c = polar(c,0.0);

     7-18 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

              o  If you are calling a mathematical function or
                 mathematical operator that takes scalars as arguments
                 (polar() for example), then you must adjust the
                 arguments you pass in to be the same type as the
                 complex template parameter type. For example, you would
                 have to change:

                 complex c = polar(0,0);
                 complex c2 = c+1;

                 Change to:

                 complex<double> c = polar(0.0,0.0); // 0.0 is double
                 complex<double> c2= c + 1.0; // 1.0 is double

              o  The complex_zero variable is not declared in the
                 complex header file. If you want to use it, you will
                 have to declare it yourself. For example, add the
                 following to the top of your source file:

                 static const complex<double> complex_zero(0.0,0.0);

              o  The sqr() and arg1() functions do not exist. If
                 you want to continue to use them, you should define
                 them in one of your own headers, using the following
                 definitions:

                 template <class T>
                 inline complex<T> sqr(const complex<T>& a)
                 {
                     T r_val(real(a));
                     T i_val(imag(a));
                     return complex<T>
                     (r_val * r_val -
                      i-val * i_val,
                      2 * r_val * -_val);
                 }
                 template <class T>
                 inline T arg1(const complex<T>& a)

                 {
                     T val = arg(a);

                     if(val > -M_PI && val <= M_PI)
                         return val;

                     if(val > M_PI)
                         return val - (2*M_PI);

                                           The C++ Standard Library 7-19

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

                  // val <= -PI
                  return val + (2*M_PI);
              }

           o  The pow(complex, int) function is no longer provided.
              You must use pow(complex<double>, double). This means
              changing calls such as:

              pow(c,1);

              to:

              pow(c,1.0);

              This might yield different results. If the function
              previously was underflowing or overflowing, it might
              not continue to happen.

           o  The complex output operator (<<) does not insert a
              space between the comma and the imaginary part. If you
              want the space, you would need to print the real and
              imaginary parts separately, adding your own comma and
              space; that is:

              complex<double> c;
              cout << "(" << c.real() << ", " << c.imag() << ")"; // add extra space

           o  The complex input operator (>>) does not raise an
              Objection if bad input is detected; it instead sets
              input stream's state to ios::failbit.

           o  Floating point overflow, underflow, and divide by zero
              do not set errno and will cause undefined behavior.
              Complex error checking and error notification are
              planned in a subsequent release.

           o  You should no longer need to link your program ex-
              plicitly with the complex library. It is automatically
              linked in as part of the Standard Library. However, you
              must still explicitly link in the C math library, as
              shown in the following example:

              #include <stdlib.h>
              #include <complex>

     7-20 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

                 int main() {
                         complex<double> c1(1,1), c2(3.14,3.14);
                         cout << "c2/c1: " << c2/c1 << endl;
                         return EXIT_SUCCESS;
                         % cxx example.cxx #error
                         % cxx example.cxx -1m #okay
                 }

        7.5.5 Upgrading from the Pre-ANSI iostream library to the
              Standard Library

              This section explains how to upgrade from the pre-ANSI
              iostream library to the ANSI iostream library. In this
              section, pre-ANSI iostream refers to versions of the
              iostream library found in the Class Library; ANSI iostream
              refers to versions found in the Standard Library.

              There are a number of differences between the pre-ANSI
              and ANSI iostream library. One major difference between
              the pre-ANSI and ANSI iostream library is that the ANSI
              library is templatized on the object input/output on which
              operations are being performed. In the pre-ANSI library,
              iostreams has no templates. The ANSI library also provides
              specializations for char and wchar_t.

              Important differences are as follows:

              o  With the current compiler, you access the pre-ANSI
                 iostream library by default in non strict_ansi compiler
                 modes. You can control the version of iostreams you use
                 with the __USE_STD_IOSTREAM and __NO_USE_STD_IOSTREAM
                 macros. If you want to use the ANSI iostream library,
                 do either of the following:

                    -D__USE_STD_IOSTREAM on the command line.
                    #define __USE_STD_IOSTREAM in your source file
                    before any include files.

              o  Header names are different in the ANSI library, so to
                 use ANSI iostreams, change the iostreams headers you
                 include as follows:




                                           The C++ Standard Library 7-21

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

              _______________________________________________________
              From_____________________To____________________________

              #include <iostream.h>    #include <iostream>
              #include <iostream.hxx>

              #include <fstream.h>     #include <fstream>
              #include <fstream.hxx>

              #include <strstream.h>   #include <strstream>
              #include <strstream.hxx>

              #include <iomanip.h>     #include <iomanip>
              #include_<iomanip.hxx>_________________________________

           o  All Standard Library names in the ANSI iostream library
              are in namespace std. Typically you would qualify each
              Standard Library name with std:: or put using namespace
              std; at the top of your source file.

              To facilitate upgrading in all but strict_ansi and
              strict_ansi_errors mode, using namespace std; is set by
              default. In strict_ansi or strict_ansi_errors modes,
              after including an ANSI iostream header, you must
              qualify each name inside namespace std individually
              or do

                    using namespace std;

           o  In the pre-ANSI iostream library, including <iomanip.h>
              or <strstream.h> gave you access to cout, cin, and
              cerr. To access the predefined streams with the ANSI
              iostream library, make the following changes:

              change                        change
              #include <iomanip.h>          #include <strstream.h>
              to                            to
              #include <iomanip>            #include <strstream>
              #include <iostream>           #include <iostream>
              using namespace std;          using namespace std;

           o  The istream::ipfx, istream::isfx, ostream::opfx,
              ostream::osfx do not exist in the ANSI iostreams. Their
              functionality is provided by the sentry class found in
              basic_istream and basic_ostream, respectively.

     7-22 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

                 Common prefix code is provided by the sentry's
                 constructor. Common suffix code is provided by the
                 sentry's destructor. As a result, calls to ipfx(),
                 isfx(), opfx(), and osfx()  have their function-
                 ality replaced by construction and destruction of
                 std::istream::sentry objects and std::ostream::sentry
                 object respectively. For example:

                 #include <iostream.hxx>           |  #include <iostream.hxx>
                 void func (istream &is)           |  void func (ostream &os)
                 {                                 |  {
                    if (is.ipfx())                 |     if (os.opfx())
                        ...                        |         ...
                    is.isfx();                     |     os.osfx();
                 }                                 |  }
                                                   |
                 Would be coded as:                |  Would be coded as:
                                                   |
                 #include <iostream>               |  #include <iostream>
                 void func (istream &is)           |  void func (ostream &os)
                 {                                 |  {
                    istream::sentry ipfx(is);      |     ostream::sentry opfx(os);
                    if (ipfx)                      |     if (opfx)
                       ...                         |        ...
                    //is.isfx(); implicit in dtor  |     //os.osfx(); implicit in dtor
                 }                                 |   }

              o  The following macros from the pre-ANSI <iomanip.h> are
                 no longer available in <iomanip>:

                 SMANIP, IMANIP, OMANIP, IOMANIP,
                 SAPP,   IAPP,   OAPP,   IOAPP,
                 SMANIPREF, IMANIPREF, OMANIPREF, IOMANIPREF,
                 SAPPREF, IAPPREF, OAPPREF, IOAPPREF

                 You can add them yourself, but their use will not be
                 portable.

              o  The streambuf::stossc() function, which advances
                 the get pointer forward by one character in a stream
                 buffer, is not available in the ANSI iostream library.
                 You can make use of the std::streambuf::sbumpc()
                 function to move the get pointer forward one place.
                 This function returns the character it moved past.
                 These two functions are not exactly equivalent-if the

                                           The C++ Standard Library 7-23

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

              get pointer is already beyond the end, stossc() does
              nothing, and sbumpc() returns EOF.

                   istream &extract(istream &is)
                   {
                      ...
                      is.rdbuf()->stossc();
                   }

           o  ios::bitalloc() is no longer available in the ANSI
              iostream library.

           o  The filebuf constructors have changed in the ANSI
              iostream library. The pre-ANSI filebuf class contained
              three constructors:

                  class filebuf : public streambuf
                  {
                     filebuf();
                     filebuf(int fd);
                     filebuf(int fd, char * p, int len);
                     ...
                  }

              In the ANSI iostream library, filebuf is a typedef for
              basic_filebuf<char>, and the C++ Working Paper defines
              one filebuf constructor:

                  basic_filebuf();

              To facilitate backward compatibility, the ANSI iostream
              library does provide basic_filebuf(int fd) as an
              extension. However, the use of extensions is not
              portable.

              For example, consider the filebuf constructors in the
              following pre-ANSI iostream library program:

              #include <fstream.hxx>






     7-24 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

                 int main () {
                     int fd = 1;
                     const int BUFLEN = 1024;
                     char buf [BUFLEN];
                     filebuf fb(fd,buf,BUFLEN);
                     filebuf fb1(fd);
                     return 0;
                 }

                 To be strictly ANSI conforming, you would need to
                 recode as follows:

                   filebuf fb(fd,buf,BUFLEN); as filebuf fb();  and
                   filebuf fb1(fd); as filebuf fb1();

                 If you want to make use of the ANSI iostream file-
                 buf(fd) extension, you could recode:

                   filebuf fb(fd,buf,BUFLEN); as filebuf fb(fd);  and
                   filebuf fb1(fd); as filebuf fb1(fd);

              o  The ANSI iostream library contains support for the
                 filebuf::fd() function, which returns the file
                 descriptor for the filebuf object and EOF if the
                 filebuf object is closed as a nonportable extension.

                 This function is not supported under the -std strict_
                 ansi or -std strict_ansi_errors compiler modes.

              o  The following functions are not defined in the ISO/ANSI
                 Standard. They are provided in the standard iostream
                 library for backward compatibility only. Their use is
                 not portable.

                     ifstream::ifstream(int fd);
                     ifstream::ifstream(int fd, char *p, int len)
                     ofstream::ofstream(int fd);
                     ofstream::ofstream(int fd, char *p, int len);
                     fstream::fstream(int fd);
                     fstream::fstream(int fd, char *p, int len);

              o  The following attach functions, which attach,
                 respectively, a filebuf, fstream, ofstream, and
                 ifstream to a file are not available in the ANSI
                 iostream library:

                                           The C++ Standard Library 7-25

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

                 filebuf::attach(int);
                 fstream::attach(int);
                 ifstream::attach(int);
                 ofstream::attach(int);

              If you do not want to make use of ANSI iostream library
              extensions, you must recode the use of attach as
              follows:

              From:

              #include <fstream.hxx>
              #include <stdio.h>
              #include <fcntl.h>
              int main () {
                  int fd;
                  fd = open("t27.in",O_RDWR | O_CREAT, 0644);
                  ifstream ifs;
                  ifs.attach(fd);
                  fd = creat("t28.out",0644);
                  ofstream of;
                  of.attach(fd);
                  return 0;
              }

              To:

              #include <fstream>
              int main () {
                  ifstream ifs("t27.in", ios::in | ios::out);
                  ofstream ofs("t28.out");
                  return 0;
              }

           o  The ios enumerators for controlling the opening of
              files, ios::nocreate and ios::noreplace, are not
              available in the ANSI iostream library.

           o  The istream_withassign and ostream_withassign classes
              are not available in the ANSI iostream library.

           o  In the ANSI iostream library ios_base::width() applies
              to all formatted inserters including operator <<
              (char). This means that the stream width specified by
              either the manipulator setw() or the ios_base::width()
              member function will apply padding to the next output
              item even if it is a char.

     7-26 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

                 This was not the case in the pre-ANSI iostream library,
                 where width() applied to all formatted inserters
                 except the char inserter. The reasons for the change
                 (to allow ostream::operator<<(char) to do formatting)
                 are:

                 1. It allows operator<< functions to do formatting
                    consistently.

                 2. It allows operator<<(char) and put(char) (formatted
                    and unformatted operations on char) to have
                    different functionality.

                 Consider the following example:

                 #ifdef __USE_STD_IOSTREAM
                 #   include <iostream>
                 #   include <iomanip>
                 #else
                 #   include <iostream.hxx>
                 #   include <iomanip.hxx>
                 #endif
                 int main () {
                     cout.width(10);
                     cout.fill('^');
                     cout << 'x' << '\n';
                     cout << '[' << setw(10) << 'x' << ']' << endl;
                     return 0;
                 }

                 In the ANSI iostream library the output is:

                 ^^^^^^^^^x
                 [^^^^^^^^^x]

                 In the pre-ANSI iostream library the output is:

                 x
                 [x]^^^^^^^^^

              o  In the pre-ANSI iostream library, printing signed
                 char * or a unsigned char * printed the address of
                 the string. In the ANSI iostream library the string is
                 printed. Consider the following example:

                                           The C++ Standard Library 7-27

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

              #ifdef __USE_STD_IOSTREAM
              #include <iostream>
              #else
              #include <iostream.hxx>
              #endif

              int main () {
                  char * cs = (char *) "Hello";
                  signed char *ss = (signed char *) "world";
                  unsigned char *us = (unsigned char *) "again";

                  cout << cs << " " << ss << " " << us << endl;
                  return 0;
              }

              The output in the ANSI iostream library is:

              Hello world again

              The output in the pre-ANSI iostream library is:

              Hello 0x120001748 0x120001740

              To obtain output equivalent to the pre-ANSI iostreams,
              you might do the following:

              cout << hex << showbase << (long) ss << " " << (long) us << endl;

           o  In the pre-ANSI iostream library printing a signed char
              prints its integer value. In the ANSI iostream library
              printing a signed char prints it as a character.
              Consider the following example:

              #ifdef __USE_STD_IOSTREAM
              #include <iostream>
              #else
              #include <iostream.hxx>
              #endif

              int main () {
                  signed char c = (signed char) 'c';
                  cout << c << endl;
                  return 0;
              }

              The output in the ANSI iostream library is:

              c

     7-28 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

                 The output in the pre-ANSI iostream library is:

                 99

                 To obtain output equivalent to the pre-ANSI iostreams,
                 you must do the following:

                 cout << (long) c << endl;

              o  In the ANSI iostream library, reading invalid floating
                 point input (where invalid input is caused by no digits
                 following the letter e or E and an optional sign) from
                 a stream sets failbit to flag this error state. In
                 the pre-ANSI iostream library, these type of error
                 conditions might not be detected. Consider this program
                 fragment:

                     double i;
                     cin >> i;
                     cout << cin.rdstate() << ' ' << i << endl;

                 On the input: 123123e

                 The output in the ANSI iostream library is:

                 4 2.65261e-314          // failbit set

                 The output in the pre-ANSI iostream library is:

                 0 123123                // failbit not set

              o  In the ANSI iostream library, reading integer input
                 (which is truncated as the result of a conversion
                 operation) from a stream sets failbit to flag this
                 overflow condition. In the pre-ANSI iostreams library,
                 these types of conditions might not be detected.
                 Consider this program fragment:

                     int i;
                     cin >> i;
                     cout << cin.rdstate() << ' ' << i << endl;

                 On the input: 9999999999999999

                 The output in the ANSI iostream library is:

                 4  1874919423       // failbit set

                 The output in the pre-ANSI iostream library is:

                 0  1874919423       // goodbit set

                                           The C++ Standard Library 7-29

 



     The C++ Standard Library
     7.5 Upgrading from the Class Library to the Version 6.n Standard Library

              In the ANSI iostream library, reading -0 from a stream
              into an unsigned int outputs 0; this was not the
              case with the pre-ANSI iostream library. Consider the
              following:

                 unsigned int ui;
                 cin >> ui;
                 cout << cin.rdstate() << ' ' << ui << endl;

              On the input: -0

              The output in the ANSI iostream library is:

              0 0

           o  In the ANSI iostream library, the istream::getline(s,n);
              function extracts characters and stores them into
              successive locations of an array whose first element is
              designated by s. If fewer than n characters are input,
              failbit is set. This was not the case in the pre-ANSI
              iostream library. Consider the following:

              #include <stdlib.h>
              int main()
              {
                      char buffer[10];
                      cin.getline (buffer,10);
                      cout << cin.rdstate() << ' ' << buffer << endl;
                      return EXIT_SUCCESS;
              }

              With input of: 1234567890

              The output in the ANSI iostream library is:

              4 123456789

              The output in the pre-ANSI iostream library is:

              0 123456789

           o  When printing addresses, the ANSI library does not
              print a leading "0x" to indicate a hexadecimal base.
              The pre-ANSI library did. Consider the following:

     7-30 The C++ Standard Library

 



                                                The C++ Standard Library
 Upgrading    from the Class Library to the Version 6.n Standard Library

                 #include <stdlib.h>
                 #include <iostream>
                 int main()
                 {
                 double d;
                 int i;
                         void *p = (void *) &d;
                         int *pi = &i;
                         cout << (void *) 0 << ' ' << p << ' ' pi << endl;
                         return EXIT_SUCCESS;
                 }

                 The output in the ANSI iostream library is:

                 0 11fffe7a0 11fffe798

                 The output in the pre-ANSI iostream library is:

                 0x0 0x11fffdc40 0x11fffdc38

              o  basic_filebuf::setbuf is a protected member function in
                 the ANSI iostream library. Therefore, the following no
                 longer compiles:

                 #include <stdlib.h>
                 int main() {
                    filebuf fb;
                    ...
                    fb.setbuf(0,0);
                    return EXIT_SUCCESS;
                 }














                                           The C++ Standard Library 7-31

 









                                                                       8
        ________________________________________________________________

                                                     Handling Exceptions



              C++ incorporates an exception mechanism for handling
              unusual program events (not necessarily just errors).
              Exception handling enables you to detect program events
              and to provide handlers to deal with the events.

              Compaq C++ implements the exception handling model
              described in the International C++ Standard.

              This chapter provides a brief introduction to exception
              handling, describes the run-time considerations of
              exception handling in Compaq C++, and recommends ways
              to use exception handlers for optimum performance. For
              a detailed description of C++ exception handling in
              general, see Chapter 14 in The C++ Programming Language,
              3rd Edition.

              Readers of this chapter should be familiar with the C++
              exception-handling terminology, such as throwing and
              catching exceptions.

              For information on debugging programs with exception
              handlers, see the Compaq Tru64 UNIX Ladebug Debugger
              Manual, which is included with the operating system
              documentation.

        8.1 Structure

              The following example shows the basic structure for
              declaring and using exception handlers in C++:






                                                 Handling Exceptions 8-1

 



     Handling Exceptions
     8.1 Structure

               .
               .
               .
           void might_break(int i)
           {
               if (i == 1) throw "something!";
               if (i == 4) throw 4;
               //  . . .
           }

           void p (int i)
           {                                //
               try                          //        begin try block
               {                            //
                   might_break(i);          //
               }                            //
               catch (const char *p)        //        begin handler
               {                            //         .
                   cout << "caught " << p;  //         .
                   // fix whatever...       //         .
               }                            //        end try block
           }                                //        end handler
               .
               .
               .

           In this example, calling p with a value of anything other
           than 1 or 4 causes the program to execute normally, with
           no exception thrown. If p is called with a value of 1,
           the might_break function throws a string object to the p
           handler, which prints caught something!.

           If p is called with 4, an int is thrown. Because p
           cannot catch values of type int, the search for a handler
           proceeds up the call stack until an appropriate handler
           can be found. If nothing on the stack can handle an int,
           program execution terminates immediately after calling the
           std::terminate function.

           C++ exception handling represents a termination model,
           which means that program execution never proceeds
           past a throw. For additional information, see the C++
           International Standard.


     8-2 Handling Exceptions

 



                                                     Handling Exceptions
                                             8.2 Run-Time Considerations

        8.2 Run-Time Considerations

              Compaq C++ optimizes the implementation of exception
              handling for normal execution, as follows:

              o  As much as possible, the overhead for exceptions is
                 incurred when throwing an exception.

              o  Applications that have try blocks and that run without
                 causing exceptions incur only slight overhead as
                 follows:

                 -  The size of an executable image increases 3 x 128
                    bits for a simple try-catch block because of tables
                    that describe the handlers.

                 -  When entering or exiting a handler, the frame
                    number is saved to be used for finding any exception
                    raised.

              Some functions without explicit handlers may have
              implicit handlers. The compiler creates a handler for
              each automatic object that has a destructor. The compiler
              also creates handlers for constructors that initialize
              subobjects that have destructors. In such a constructor,
              the compiler creates a handler for each member with a
              destructor, and a handler for each base class with a
              destructor.

              The -nocleanup option suppresses generation of such
              implicit handlers, which results in a slightly smaller
              executable file. Use the -nocleanup option for programs
              that do not use exception handling or do not require
              destruction of automatic objects during exception
              processing.

        8.3 Coding Recommendations

              Some recommendations for optimal results when using
              exception handling in Compaq C++ are:

              o  Use destructors where necessary, but avoid creating
                 them where they are not useful.

                 The existence of a destructor can cause the compiler
                 to create an implicit exception handler - as in
                 the example of an implicit exception handler for an
                 automatic object with a destructor.

                                                 Handling Exceptions 8-3

 



     Handling Exceptions
     8.3 Coding Recommendations

           o  Use fewer and larger try blocks, instead of many small
              try blocks, wherever possible.

              Whereas a single try block with several handlers may
              improve performance compared to several small try
              blocks with one handler each, the improvement may not
              always be enough to justify making awkward changes to
              your program logic.

     8.4 Mixed-Language Applications

           When C functions are intermixed with C++ functions, the
           compiler treats them as C++ functions without exception
           handlers. The C functions can have their own exception
           handlers. Each function within a program can point to its
           own language-specific handler.

     8.5 Finding Information about Exceptions

           To obtain more information about an exception that was
           thrown, you can call the function __cxx_exception_info
           from a catch(...) clause.

           The function returns the system_exrec_type defined in
           excpt.h, which points to the facility that raised the
           exception and to other information.

           The prototype is found in cxx_exception.h and is:

           system_exrec_type *__cxx_exception_info();

           For more information about the system_exrec_type, see the
           excpt reference page.

     8.6 Using the dlclose Routine

           The dlclose routine cannot be used to delete a shared
           object (.so) until after any handlers handling an
           exception, thrown from the shared object, have exited.
           This restriction is necessary because, when exiting from a
           handler, the C++ exception support needs to reference data
           structures that were defined at the throw point.



     8-4 Handling Exceptions

 



                                                     Handling Exceptions
                                   8.7 Catching Signals and C Exceptions

        8.7 Catching Signals and C Exceptions

              Compaq Tru64 UNIX and Linux Alpha report divides by zero
              and other "bad behavior" by libc as signals. To manage
              signals, you can install a signal handler.

              If you want C exceptions, you can install exc_raise_
              signal_exception as the handler for particular signals.
              When a signal occurs, a C exception is thrown.

              Although C++ catch clauses (catch(...)) recognize C
              exceptions, the exceptions are not coverted to exception
              as defined in <exception>.

              Consider the following example:

              #include <stdlib.h>
              #include <excpt.h> //new
              #include <signal.h> //new
              struct sigaction foo =   //new
               {(void (*)(int))exc_raise_signal_exception,0,0}; // new

              #include <iostream.h>
              #include <exception>

              int main()
              {
                double x, y, z;

                sigaction(SIGFPE,&foo,0); //new

                cerr << "testing divide by 0" << endl;
                try {
                  x = 0.0;
                  y = 1.0;
                  z = y / x;
                  cerr << "z is " << z << endl;
                }
                catch (exception e) {
                  cerr << "caught exception " << e.what() << endl;
                }
                catch(...) {
                  cerr << "caught ... exception" << endl;
                }
                return EXIT_SUCCESS;
              }

                                                 Handling Exceptions 8-5

 



     Handling Exceptions
     8.7 Catching Signals and C Exceptions

           The resulting output is as follows:

           tagged 1062% a.out
           testing divide by 0
           caught ... exception

     8.8 C++ Exceptions and Threads [Tru64]

           C++ exceptions are thread safe. This means that multiple
           threads within a process can throw and catch exceptions
           concurrently. However, exceptions do not propagate
           from one thread to another, nor can one thread catch an
           exception thrown by another thread.

           Because C++ exceptions are implemented using the exception
           handling facilities described in the Compaq Tru64 UNIX
           Calling Standard for Alpha System, C++ modules do work
           properly when they are part of a program that makes other
           uses of the same exception handling facilities.

           The raising and handling of DECthreads exceptions can
           result in the destruction of C++ automatic objects. If the
           handling of a DECthreads exception results in an unwind
           through a C++ function's stack frame, then destructors
           are called for automatic objects declared in that stack
           frame, just as though a C++ exception had been caught by a
           handler in an outer stack frame.

           The C++ exception handling facility can also be used to
           catch DECthreads exceptions that are raised independently
           of C++ throw expressions. A C++ catch( .. . ) handler
           catches both C++ thrown exceptions and DECthreads
           exceptions.

           However, C++ exception mechanisms (try, catch, throw)
           cannot be used within the same function as DECthreads
           exception mechanisms (TRY, CATCH, RAISE, and so forth).
           Because both exception mechanisms attempt to establish
           their own specific handlers, the results will be
           undefined.

           The set_terminate() and set_unexpected()  functions set
           the terminate() and unexpected()  handlers for the calling
           thread. Therefore, each thread in a program has its own
           terminate() and unexpected()  handlers.

     8-6 Handling Exceptions

 



                                                     Handling Exceptions
                                  8.8 C++ Exceptions and Threads [Tru64]

              If you want every thread in your program to use the same
              nondefault terminate() or unexpected() handlers, you must
              call the set_terminate() and set_unexpected() functions
              separately from each thread.

              For more information about threads and DECthreads
              exceptions, see the Guide to DECthreads manual.

              Note that the advantage of using C++ exceptions is that
              entering the try block is much faster than entering a
              pthread try block.

              The advantage of using pthread exceptions is that you
              can call pthread_exc_report_np(THIS_CATCH) to give more
              information about the exception caught, as shown in the
              following example.

              #include <pthread.h>
              #include <pthread_exception.h>
              #include <stdio.h>

              struct C {
               int i;
               static int count;
               C() : i(count++) { printf("ctor %d\n", i); }
               ~C() { printf("dtor %d\n", i); }
              };

              int C::count =0;

              int foo(int i, int j, int *p) {
                  int k = j / i;
                  *p = 25; /* illegal mem access */
                  return k;
              }

              // C++ version.
              void * theThread_cxx(void * arg)
              {
                int i = 0, j = 10, k, *p;

                printf("Enter thread\n");
                sleep(2);

                try {
                  k = foo(i,j,p);

                                                 Handling Exceptions 8-7

 



     Handling Exceptions
     8.8 C++ Exceptions and Threads [Tru64]

             } catch (...) {
                 printf("Caught some exception...\n");
                 // pthread_exc_report_np(THIS_CATCH);
             }

             printf("exit thread\n");
             return(0);
           }

           // Threads version.
           void * theThread(void * arg)
           {
             C d;
             int i = 0, j = 10, k, *p;

             printf("Enter thread\n");
             sleep(2);

             TRY
               k = foo(i,j,p);

              CATCH_ALL
                 printf("Caught some exception...\n");
                 pthread_exc_report_np(THIS_CATCH);
                 throw 5;
              ENDTRY

               printf("exit thread\n");
             return(0);
           }

           void * theThread_wrapper(void * arg)
           {
             try {
               theThread(arg);
             } catch (int) {
               printf("caught an int\n");
             }
             return 0;
           }

           int main()
           {
             pthread_t thread;
             pthread_attr_t attr;
             int status = 0;
             register int i;

     8-8 Handling Exceptions

 



                                                     Handling Exceptions
                                  8.8 C++ Exceptions and Threads [Tru64]

                printf("begin main\n");
                pthread_attr_init(&attr);

                // Make 3 copies of the pthread exception handling thread.
                for(i=0; i<3; i++) {
                    status = pthread_create(&thread, &attr, theThread_wrapper, 0);
                    if(status)
                      {
                        printf("***ERROR***, pthread_create failed\n");
                      }
                    pthread_join(thread, 0);
                  }

                // Make the C++ exception handling thread.
                status = pthread_create(&thread, &attr, theThread_cxx, 0);
                if(status)
                      {
                        printf("***ERROR***, pthread_create failed\n");
                      }
                pthread_join(thread, 0);
                printf("end main\n");

                return(0);
              }





















                                                 Handling Exceptions 8-9

 









                                                                       9
        ________________________________________________________________

                                              Using the Ladebug Debugger



              A debugger helps you find run-time errors by letting you
              observe and interactively manipulate execution step by
              step, until you discover where the program functions
              incorrectly.

              The language of the source program you are currently
              debugging determines the format you use to enter and
              display data. It also determines the format used for
              features, such as comment characters, operators, and
              operator precedence, which have language-specific
              settings. If you have modules written in another language,
              you can switch from one language to another during your
              debugging session.

              This chapter discusses debugging programs using the
              command line interface to the Ladebug Debugger. A
              graphical user interface is also available through DEC
              FUSE, which supports all of the Ladebug commands mentioned
              in this chapter.

              DEC FUSE is the integrated software development environ-
              ment for Compaq Tru64 UNIX systems. Besides the Ladebug
              commands described in this chapter, DEC FUSE provides
              the programmer with a class browser, call graph browser,
              and cross-referencing capability to assist in debugging
              Compaq C++ programs. For more information, see the DEC
              FUSE Debugger Manual.








                                          Using the Ladebug Debugger 9-1

 



     Using the Ladebug Debugger
     9.1 Debugging C++ Programs

     9.1 Debugging C++ Programs

           The Ladebug debugger is a source-level debugger that
           debugs C++ programs compiled with the Compaq C++ compiler.
           For general information on how to use the Ladebug
           debugger, see the Compaq Tru64 UNIX Ladebug Debugger
           Manual and the Ladebug(1) reference page.

           When debugging C++ code, the debugger supports the
           following features:

           o  C++ names and expressions, including:

              -  Using an explicit and implicit this pointer to refer
                 to class members

              -  The scope resolution operator (::)

              -  The member access operators, period (.) and right
                 arrow (->)

              -  Reference types

              -  Template instantiations

              -  C++ exception handling

           o  Setting breakpoints in:

              -  Member functions, including static and virtual
                 functions

              -  A member function in a particular object

              -  Overloaded functions

              -  Constructors and destructors

              -  Template instantiations

              -  Exception handlers

           o  Changing the current class scope to set breakpoints
              and examine static members of a class that are not
              currently in scope

           o  Calling overloaded functions

           o  Debugging programs containing a mixture of C and C++
              code

     9-2 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                                              9.1 Debugging C++ Programs

              The debugger interprets C++ names and expressions using
              the language rules described in the International C++
              Standard. C++ is a distinct language, rather than a
              superset of C. Where the semantics of C and C++ differ,
              the debugger provides the interpretation appropriate for
              the language of the program being debugged.

              To make the debugger more useful, the debugger relaxes
              some standard C++ name visibility rules. For example, you
              can reference both public and private class members.

        9.2 Using Absolute and Relative Path Names

              If your program supplies an absolute filename like
              two/two.cxx, the object file contains that name. For
              example:

              $ gemc_cxx -ptr ~/cxx_repository -I templates two/two.cxx
              $ a.out
              in is_zero(long) templates/template.hxx
              in is_zero(double) templates/template.hxx

              If you supply the full path name, the object file contains
              the full name:

              $ gemc_cxx -ptr ~/cxx_repository -I ~/templates two/two.cxx
              $ a.out
              in is_zero(long) /usr/users/smith/templates/template.hxx
              in is_zero(double) /usr/users/smith/templates/template.hxx

              There are advantages and disadvantages to using relative
              path names versus complete path names. With relative
              pathnames, you can move the development tree and continue
              to debug. With absolute path names, you can move your
              executable and continue to debug, and using multiple
              repositories is easier.

              Although moving development trees might not be common,
              mounting them on some other system is, and there is no
              reason why the mount points on the two systems need have
              the same name-for example, in a cluster.

              On sys1, /usr/users/smith points to
              /usr/var/ase/mnt/ab-nfs/ab-users/users4/smith.  On sys2,
              /usr/users/smith points to /tmp_mnt/var/users/smith.

                                          Using the Ladebug Debugger 9-3

 



     Using the Ladebug Debugger
     9.2 Using Absolute and Relative Path Names

           Consider what would happen if the compiler tried to save
           the complete path name of a file instead of the name
           as supplied. It would use something like getcwd() to
           complete the name. On sys1, the compiler would save the
           name

           /usr/var/ase/mnt/abcd-nfs/abcd_users/users45/smith/templates/template.hxx

           You would be unable to debug the program on sys2, which
           does not have access to

           /usr/var/ase/mnt/abcd-nfs/abcd_users/users45/smith/templates/template.hxx

           By saving the name the user supplies, the compiler gives
           the user control over how they access the files. If you
           want full path names, supply them on the command line. If
           you want relative path names, supply those instead.

     9.3 Debugging Programs Containing C and C++ Code

           The debugger lets you debug mixed-language programs.
           Program flow of control across functions written in
           different languages is transparent.

           The debugger automatically identifies the language of
           the current function or code segment based on information
           embedded in the executable file. If program execution is
           suspended in a C function, the current language is C. If
           the program executes a C++ function, the current language
           becomes C++.

           The current language determines the valid expression
           syntax for the debugger. When the current language is
           C, printing an expression such as S::foo causes an error,
           because scope resolution operators and class types are
           not valid in C expressions. The current language of the
           debugger also affects the semantics used to evaluate an
           expression. For example, in C, all character constants
           are of type int. In C++, single character constants are
           of type char. In C, sizeof('a') = sizeof(int). In C++,
           sizeof('a') = 1.

           The debugger sets the variable $lang to the language of
           the current function or code segment. By manually setting
           the debugger variable $lang, you can force the debugger to
           interpret expressions used in commands by the rules and

     9-4 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                        9.3 Debugging Programs Containing C and C++ Code

              semantics of a particular language. Example 9-1 shows how
              to switch between C++ and C modes while debugging.


              Example 9-1 Switching Between C++ and C Debugging Modes

              (Ladebug) print $lang
              "C++"
              (Ladebug) print sizeof('a')
              1
              (Ladebug) set $lang = "C"
              (Ladebug) print sizeof('a')
              4
              (Ladebug) print sizeof(int)
              4
              (Ladebug)

              When the debugger reaches the end of your program, the
              $lang variable is set to the language of the final
              function of your program, rather than the language of
              the _exit routine. The _exit routine is written in machine
              code and is the last function executed by every C or C++
              program.

        9.4 Setting the Class Scope

              The debugger maintains the concept of a current context
              in which to perform lookup of program variable names.
              The current context includes a file scope and either a
              function scope or a class scope. The debugger automati-
              cally updates the current context when program execution
              suspends.

              The class command lets you set the scope to a class in
              the program you are debugging. The syntax for the class
              command is as follows:

              class  class_name

              Explicitly setting the debugger's current context to a
              class allows visibility into a class to set a breakpoint
              in a member function, to print static data members, or
              to examine any data member's type. After the class scope
              is set, you can set breakpoints in the class's member

                                          Using the Ladebug Debugger 9-5

 



     Using the Ladebug Debugger
     9.4 Setting the Class Scope

           functions and examine data without explicitly mentioning
           the class name. If you do not want to affect the current
           context, you can use the scope resolution operator (::) to
           access a class whose members are not currently visible.

           There can be only one current context. If you set a class
           scope, you invalidate the current function scope. The
           opposite is also true: if you set a function scope, you
           invalidate the current class scope.

           To display the current class scope (if one exists), enter
           the class command with no argument.

           Example 9-2 shows the use of the class command to set the
           class scope to S to make member function foo visible so a
           breakpoint can be set in foo.

           Example 9-2 Setting the Class Scope

           (Ladebug) stop in main; run
           [#1: stop in main ]
           [1] stopped at [int main(void):26 0x120000744]
                26      int result = s.bar();
           (Ladebug) stop in foo
           Symbol foo not visible in current scope.
           foo has no valid breakpoint address
           Warning: Breakpoint not set
           (Ladebug)  class S
           class S  {
             int i;
             int j;
             S (void);
             ~S (void);
             int foo (void);
             virtual int bar (void);
           }

           (Ladebug) stop in foo
           [#2: stop in foo (void) ]
           (Ladebug)





     9-6 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                                        9.5 Displaying Class Information

        9.5 Displaying Class Information

              The whatis and print commands display information
              about a class. Use the whatis command to display static
              information about the classes. Use the print command to
              view dynamic information about class objects.

              The whatis command displays the class type declara-
              tion, including the data members, member functions,
              constructors, destructors, static data members, and
              static member functions. For classes that are derived
              from other classes, the data members and member functions
              inherited from the base class are not displayed. However,
              any member functions that are redefined from the base
              class are displayed.

              The whatis command used on a class name displays all class
              information, including constructors. To use this command
              on a constructor only, use the following syntax:

              whatis  class_name::class_name

              Constructors and destructors of nested classes must be
              accessed using one of the following syntaxes:

              class  class_name::(type signature)

              class  class_name::~(type signature)

              The print command lets you display the value of data
              members and static members.

              Information regarding the public, private, or protected
              status of class members is not provided because the
              debugger relaxes these rules to be more helpful to you.

              The type signatures of member functions, constructors, and
              destructors are displayed in a form that is appropriate
              for later use in resolving references to overloaded
              functions.

              Example 9-3 shows the whatis and print commands in
              conjunction with a class.

              Example 9-3 Displaying Class Information

                                                (continued on next page)

                                          Using the Ladebug Debugger 9-7

 



     Using the Ladebug Debugger
     9.5 Displaying Class Information

           Example 9-3 (Cont.) Displaying Class Information

           (Ladebug) list 1, 9
                 1 class S {
                 2 public:
                 3      int i;
                 4      int j;
                 5      S() { i = 1; j = 2; }
                 6      ~S() { }
                 7      int foo ();
                 8      virtual int bar();
                 9 };
           (Ladebug) whatis S
           class S  {
             int i;
             int j;
             S (void);
             ~S (void);
             int foo (void);
             virtual int bar (void);
           } S
           (Ladebug) whatis S :: bar
           int bar (void)
           (Ladebug) stop in S :: foo
           [#2: stop in S :: foo ]
           (Ladebug) run
           [2] stopped at [int S::foo(void):13 0x120000648]
                13      return i;

           (Ladebug) print S :: i
           1
           (Ladebug)

     9.6 Displaying Object Information

           The print and whatis commands also display information
           on instances of classes (objects). Use the whatis command
           to display the class type of an object. Use the print
           command to display the current value of an object. You can
           print an object's contents all at once using the following
           syntax:

           print  object


     9-8 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                                       9.6 Displaying Object Information

              You can also display individual object members using the
              member access operators, period (.) and right arrow (->)
              in a print command. Static data members are treated as
              members of objects, so you can reference them by object
              name. If the debugger stops in a member function of an
              object, you can access other members of that same object
              using the this pointer implicitly or explicitly.

              You can use the scope resolution operator (::) to
              reference global variables, to reference hidden members
              in base classes, to explicitly reference a member that
              is inherited, or to otherwise name a member hidden by the
              current context.

              When you are in the context of a nested class, you must
              use the scope resolution operator to access members of the
              enclosing class.

              Example 9-4 shows how to use the print and whatis commands
              to display object information.

              Example 9-4 Displaying Object Information

              (Ladebug) whatis s
              class S  {
                int i;
                int j;
                S (void);
                ~S (void);
                int foo (void);
                virtual int bar (void);
              } s
              (Ladebug) stop in S::foo; run
              [#1: stop in s.foo ]
              [1] stopped at [int S::foo(void):13 0x120000638]
                   35      return i;
              (Ladebug) print *this
              class {
                      i = 1;
                      j = 2;
                  }

                                                (continued on next page)


                                          Using the Ladebug Debugger 9-9

 



     Using the Ladebug Debugger
     9.6 Displaying Object Information

           Example 9-4 (Cont.) Displaying Object Information

           (Ladebug) print i, j
           1 2

           (Ladebug) print this->i, this->j
           1 2
           (Ladebug)

     9.7 Displaying Virtual and Inherited Class Information

           When you use the print command to display information on
           an instance of a derived class, the debugger displays both
           the new class members as well as the members inherited
           from a base class. Base class member information is nested
           within the inherited class information.

           Pointers to members of a class are not supported.
           Example 9-5 shows the format the debugger uses to print
           information on derived classes.

           Example 9-5 Printing Information on a Derived Class

                                             (continued on next page)





















     9-10 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                  9.7 Displaying Virtual and Inherited Class Information

              Example 9-5 (Cont.) Printing Information on a Derived
                                  Class

              (Ladebug) list 1, 23
                    1 class S {
                    2 public:
                    3      int i;
                    4      S() {i=1;};
                    5      ~S() {i=0;};
                    6      int foo();
                    7 };
                    8
                    9 S::foo()
                   10 {
                   11    i = i + 1;
                   12    return i;
                   13 }
                   14
                   15 class T : public S {
                   16 public:
                   17      int j;
                   18      T() {j=2;};
                   19      ~T() {i=0;};
                   20 };
                   21
                   22 S a;
                   23 T b;
              (Ladebug) stop in main ; run
              [#1: stop in main(void) ]
              [1] stopped at [main(void):27 0x1200007f4]
                   27    a.i = 1;
              (Ladebug) print b
              class {
                      S = class {
                          i = 1;
                      };
                      j = 2;
                  }

                                                (continued on next page)





                                         Using the Ladebug Debugger 9-11

 



     Using the Ladebug Debugger
     9.7 Displaying Virtual and Inherited Class Information

           Example 9-5 (Cont.) Printing Information on a Derived
                               Class

           (Ladebug) whatis b
           class T : S {
             int j;
             T (void);
             ~T (void);
           } b

           (Ladebug) whatis S
           class S  {
             int i;
             S (void);
             ~S (void);
             int foo (void);
           } S
           (Ladebug)

           The whatis b command in this example displays the class
           type of the object b. Descriptions of derived classes
           obtained with the whatis command do not include members
           inherited from base classes. Class T inherits the public
           members of class S; in this case, integer variable i and
           member function foo.

           If you have two members in an object with the same name
           but different base class types (multiple inheritance), you
           can refer to the members using the following syntax:

           object.class::member

           This syntax is more effective than using the object.member
           and object->member syntaxes, which can be ambiguous. In
           all cases, the Ladebug debugger uses the C++ language
           rules as defined in The Annotated C++ Reference Manual to
           determine which member you are specifying.

           Example 9-6 shows a case where the expanded syntax is
           necessary. In this example, two base classes, B and C
           inherit the public members of base class V. Derived class
           D inherits the public members of both class B and class
           C.


     9-12 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                  9.7 Displaying Virtual and Inherited Class Information

              Example 9-6 Resolving References to Objects of Multiple
                          Inherited Classes

              (Ladebug) whatis D
              class D : B, C {
                D (void);
                ~D (void);
                void g (void);
              } D
              (Ladebug) whatis C
              class C : virtual V {
                int ambig;
                C (void);
                ~C (void);
              } C
              (Ladebug) whatis B
              class B : virtual V {
                int x;
                int ambig;
                B (void);
                ~B (void);
                int f (void);
              } B
              (Ladebug) whatis V
              class V  {
                int v;
                int x;
                V (void);
                ~V (void);
                int f (void);
              } V
              (Ladebug) stop in main; run
              [#1: stop in main(void) ]
              [1] stopped at [main(void):59 0x120001024]
                   59   D dinst;
              (Ladebug) next
              stopped at [main(void):60 0x120001030]
                   60   V vinst;
              (Ladebug) <Return>
              stopped at [main(void):62 0x120001038]
                   62   printf("%d\en", dinst;

                                                (continued on next page)


                                         Using the Ladebug Debugger 9-13

 



     Using the Ladebug Debugger
     9.7 Displaying Virtual and Inherited Class Information

           Example 9-6 (Cont.) Resolving References to Objects of
                               Multiple Inherited Classes

           (Ladebug) print dinst.ambig
           Ambiguous reference
           Selecting 'ambig' failed!
           Error: no value for dinst.ambig
           (Ladebug) print dinst.B::ambig
           2
           (Ladebug)

           Trying to examine an inlined member function that is not
           called results in the following error:

           Member function has been inlined.

           Ladebug will report this error regardless of the
           settings of the -noinline_auto compilation switches. As a
           workaround, include a call to the given member function
           somewhere in your program. (The call does not need to be
           executed.)

           If a program is not compiled with the -g option, a
           breakpoint set on an inline member function may confuse
           the debugger.

     9.8 Modifying Class and Object Data Members

           When debugging C++ code, the debugger lets you modify
           a class's static data members and object data members
           as you would modify any other program variable by using
           the debugger's assign command. See the Compaq Tru64 UNIX
           Ladebug Debugger Manual for details on how to use the
           assign command to modify variable values. The following
           assignments are allowed by the debugger even though they
           are prohibited in the C++ language:

           o  Variables of type const may be assigned a new value.

           o  Variables declared as reference types (using a type&
              type definition) may be assigned a new value. The
              address referred to by a reference type may not be
              changed, but the value at that address may be changed.


     9-14 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                                 9.9 Member Functions on the Stack Trace

        9.9 Member Functions on the Stack Trace

              The implicit this pointer, which is a part of all
              nonstatic member functions, is displayed as the address
              on the stack trace. The class type of the object is also
              given.

              Sometimes the debugger does not see class type names with
              internal linkage. When this happens, the debugger gives
              the following error message:

              Name is overloaded.

              The stack trace in Figure 9-1 displays a member function
              foo of an object declared with class type S.

              Figure 9-1 A Stack Trace Displaying a Member Function







        9.10 Resolving Ambiguous References to Overloaded Functions

              In most cases, the debugger works with one specific
              function at a time. In the case of overloaded function
              names, you must specify the desired overloaded function.
              There are two ways to resolve references to overloaded
              function names. Both ways are under the control of the
              debugger variable $overloadmenu. The default setting of
              this debugger variable is 0.

              One way to specify the desired function name is to choose
              the correct reference from a selection menu. To enable
              menu selection of overloaded names, set the $overloadmenu
              variable to 1. If you use this method, whenever you
              specify a function name that is overloaded, a menu will
              appear with all the possible functions; you must select
              from this menu. In Example 9-7, a breakpoint is set in
              foo, which is overloaded.



                                         Using the Ladebug Debugger 9-15

 



     Using the Ladebug Debugger
     9.10 Resolving Ambiguous References to Overloaded Functions

           Example 9-7 Resolving Overloaded Functions by Selection
                       Menu

           (Ladebug) set $overloadmenu = 1
           (Ladebug) class S
           class S  {
             int i;
             float f;
             double d;
             char c;
             S (void);
             ~S (void);
             int foo (void);
             int foo ( S);
             int foo ( S *);
             int foo (int&);
             int foo (const int&);
             int foo (float*&);
             int foo (int, float, char *, unsigned short, long&, const char*&);
             int foo (const double *);
             int foo (char);
             void foo (short);
             void foo (unsigned);
             void foo (long);
             void foo (int, float, char *, unsigned short, long&, char*&);
             void foo (double);
             void foo (char *);
             void foo (const char *);
           }

                                             (continued on next page)














     9-16 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
             9.10 Resolving Ambiguous References to Overloaded Functions

              Example 9-7 (Cont.) Resolving Overloaded Functions by
                                  Selection Menu

              (Ladebug) stop in foo
              Enter the number of the overloaded function you want
              ----------------------------------------------------
                   1 int foo (void)
                   2 void foo (const char *)
                   3 void foo (char *)
                   4 void foo (double)
                   5 void foo (int, float, char *, unsigned short, long&, char*&)
                   6 void foo (long)
                   7 void foo (unsigned)
                   8 void foo (short)
                   9 int foo (char)
                  10 int foo (const double *)
                  11 int foo (int, float, char *, unsigned short, long&, const char*&)
                  12 int foo (float*&)
                  13 int foo (const int&)
                  14 int foo (int&)
                  15 int foo ( S *)
                  16 int foo ( S)
                  17 None of the above
              ----------------------------------------------------

              10
              [#1: stop in int S::foo(const double*) ]
              (Ladebug)

              The other way to resolve ambiguous overloaded function
              names is to enter the function name with its full
              type signature. If you prefer this method, set the
              $overloadmenu variable to 0. To see the possible type
              signatures for the overloaded function, first display all
              the declarations of an overloaded function by using one of
              the following syntax lines:

              whatis  function

              whatis  class_name::function





                                         Using the Ladebug Debugger 9-17

 



     Using the Ladebug Debugger
     9.10 Resolving Ambiguous References to Overloaded Functions

           You cannot select a version of an overloaded function that
           has a type signature containing ellipsis points. Pointers
           to functions with type signatures that contain parameter
           list or ellipsis arguments are not supported.

           Use one of the displayed function type signatures to refer
           to the desired version of the overloaded function. If a
           function has no parameter, include the parameter void as
           the function's type signature. In Example 9-8 the function
           context is set to foo(), which is overloaded.

           Example 9-8 Resolving Overloaded Functions by Type
                       Signature

           (Ladebug) print $overloadmenu
           0
           (Ladebug) class S
           class S  {
             int i;
             float f;
             double d;
             char c;
             S (void);
             ~S (void);
             int foo (void);
             int foo ( S);
             int foo ( S *);
             int foo (int&);
             int foo (const int&);
             int foo (float*&);
             int foo (int, float, char *, unsigned short, long&, const char*&);
             int foo (const double *);
             int foo (char);
             void foo (short);
             void foo (unsigned);
             void foo (long);
             void foo (int, float, char *, unsigned short, long&, char*&);
             void foo (double);
             void foo (char *);
             void foo (const char *);
           }

                                             (continued on next page)


     9-18 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
             9.10 Resolving Ambiguous References to Overloaded Functions

              Example 9-8 (Cont.) Resolving Overloaded Functions by
                                  Type Signature

              (Ladebug) whatis foo
              Overloaded Function. Functions are:
              int S::foo(void)
              int S::foo(S)
              int S::foo(S*)
              int S::foo(int&)
              int S::foo(const int&)
              int S::foo(float*&)
              int S::foo(int, float, char*, unsigned short, long&, const char*&)
              int S::foo(const double*)
              int S::foo(char)
              void S::foo(short)
              void S::foo(unsigned)
              void S::foo(long)
              void S::foo(int, float, char*, unsigned short, long&, char*&)
              void S::foo(double)
              void S::foo(char*)
              void S::foo(const char*)
              (Ladebug) func foo
              Error: foo is overloaded

              (Ladebug) func foo(double)
              S::foo(double) in c++over.C line No. 156:
                  156     printf ("void S::foo (double d = %f)\n", d);
              (Ladebug)

        9.11 Setting Breakpoints in Member Functions

              When you set a breakpoint in a C function, the debugger
              confirms the breakpoint by echoing the breakpoint command
              along with the status number for the breakpoint. When
              you set a breakpoint in a C++ function, the debugger also
              prints the type signature of the function in which the
              breakpoint was set.

              To set a breakpoint that stops in a member function, use
              one of the following syntax lines:

              stop in  function



                                         Using the Ladebug Debugger 9-19

 



     Using the Ladebug Debugger
     9.11 Setting Breakpoints in Member Functions

           stop in  class_name::function

           This form of specifying a breakpoint in a function uses
           the static class type information to determine the address
           of the function at which to set the breakpoint, and
           presumes that no run-time information from an object is
           needed.

           In Example 9-9 a breakpoint is set for member function bar
           of class S.

           Example 9-9 Setting Breakpoints in Member Functions

           (Ladebug) stop in S :: bar
           [#1: stop in S::bar(void) ]
           (Ladebug) status
           #1 PC==0x120000658 in S::bar(void) "c++ex.C":18 { break }
           (Ladebug) run
           [1] stopped at [S::bar(void):18 0x120000658]
                18      return j;
           (Ladebug) where
           >0  0x120000658 in ((S*)0x120000658)->bar() c++ex.C:18
           #1  0x120000750 in main() c++ex.C:26
           (Ladebug)

           If you need run-time information from the object to
           determine the correct virtual function at which to set
           a breakpoint, qualify the function name with the object
           using one of the following syntax lines:

           stop in  object.function

           stop in  objectpointer->function

           Setting the breakpoint in this way causes the debugger
           to stop at the member function in all objects declared
           with the same class type as the specified object. In
           Example 9-10, objects s and t are both declared to be
           of class type S. A breakpoint is set for member function
           bar. The first time the debugger stops at bar() is for
           object s. The second time the debugger stops in bar() for
           object t.



     9-20 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                            9.11 Setting Breakpoints in Member Functions

              Example 9-10 Setting Breakpoints in Virtual Member
                           Functions

              (Ladebug) stop in main
              [#1: stop in main(void) ]
              (Ladebug) run
              [1] stopped at [main(void):26 0x120000744]
                   26      int result = s.bar();
              (Ladebug) stop in s.bar
              [#2: stop in S::bar(void) ]
              (Ladebug) status
              #1 PC==0x120000744 in main(void) "c++ex.C":26 { break }
              #2 PC==0x120000658 in S::bar(void) "c++ex.C":18 { break }
              (Ladebug) print &s
              0x140000000
              (Ladebug) print &t
              0x140000008
              (Ladebug) cont
              [2] stopped at [S::bar(void):18 0x120000658]
                   18      return j;

              (Ladebug) where
              >0  0x120000658 in ((S*)0x140000000)->bar() c++ex.C:18
              #1  0x120000750 in main() c++ex.C:26
              (Ladebug) cont
              [2] stopped at [S::bar(void):18 0x120000658]
                   18      return j;
              (Ladebug) where
              >0  0x120000658 in ((S*)0x140000008)->bar() c++ex.C:18
              #1  0x12000076c in main() c++ex.C:27
              (Ladebug)

              To set a breakpoint that stops only in the member function
              for this specific object and not all instances of the
              same class type, you must specify this as an additional
              conditional clause to the stop command. Use one of the
              following syntax lines:

              stop in  object.function if & object == this

              stop in  objectpointer->function if & objectpointer ==
                       this



                                         Using the Ladebug Debugger 9-21

 



     Using the Ladebug Debugger
     9.11 Setting Breakpoints in Member Functions

           This form of the breakpoint command instructs the debugger
           to stop in the function only for the object specified by
           the this pointer. In Example 9-11, which is running the
           same program as Example 9-10, the breakpoint is set for
           the member function for object s only. After stopping
           in bar() for object s, further execution of the program
           results in the program running to completion.


           Example 9-11 Setting Breakpoints in Member Functions for
                        a Specific Object

           (Ladebug) stop in s.bar if &s==this
           [#2: stop in s.bar if &s==this ]
           (Ladebug) status
           #1 PC==0x120000744 in main(void) "c++ex.C":26 { break }
           #2 (PC==0x120000658 in S::bar(void) "c++ex.C":18 and if &s==this) {break}
           (Ladebug) print &s
           0x140000000
           (Ladebug) cont
           [2] stopped at [S::bar(void):18 0x120000658]
                18      return j;

           (Ladebug) where
           >0  0x120000658 in ((S*)0x10000010)->bar() c++ex.C:18
           #1  0x120000750 in main() c++ex.C:26
           (Ladebug) cont
           Thread has finished executing
           (Ladebug)

     9.11.1 Setting Breakpoints in Overloaded Functions

           To set a breakpoint in an overloaded function, you must
           provide the full type signature of the function. Use one
           of the following command syntax lines:

           stop in  function (type_signature)

           stop in  class_name::function (type_signature)

           If the desired version of the function has no param-
           eters, you must enter void for the type signature. In
           Example 9-12 the breakpoint is set for specific versions
           of the overloaded function foo.

     9-22 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                            9.11 Setting Breakpoints in Member Functions

              Example 9-12 Setting Breakpoints in Specific Overloaded
                           Functions

              (Ladebug) class S
              class S  {
                int i;
                float f;
                double d;
                char c;
                S (void);
                ~S (void);
                int foo (void);
                int foo ( S);
                int foo ( S *);
                int foo (int&);
                int foo (const int&);
                int foo (float*&);
                int foo (int, float, char *, unsigned short, long&, const char*&);
                int foo (const double *);
                int foo (char);
                void foo (short);
                void foo (unsigned);
                void foo (long);
                void foo (int, float, char *, unsigned short, long&, char*&);
                void foo (double);
                void foo (char *);
                void foo (const char *);
              }

                                                (continued on next page)















                                         Using the Ladebug Debugger 9-23

 



     Using the Ladebug Debugger
     9.11 Setting Breakpoints in Member Functions

           Example 9-12 (Cont.) Setting Breakpoints in Specific
                                Overloaded Functions

           (Ladebug) whatis foo
           Overloaded Function. Functions are:
           int S::foo(void)
           int S::foo(S)
           int S::foo(S*)
           int S::foo(int&)
           int S::foo(const int&)
           int S::foo(float*&)
           int S::foo(int, float, char*, unsigned short, long&, const char*&)
           int S::foo(const double*)
           int S::foo(char)
           void S::foo(short)
           void S::foo(unsigned)
           void S::foo(long)
           void S::foo(int, float, char*, unsigned short, long&, char*&)
           void S::foo(double)
           void S::foo(char*)
           void S::foo(const char*)

           (Ladebug) stop in foo(double)
           [#1: stop in void S::foo(double) ]
           (Ladebug) stop in foo(void)
           [#2: stop in int S::foo(void) ]
           (Ladebug) status
           #1 PC==0x120001508 in void S::foo(double) "c++over.C":156 { break }
           #2 PC==0x120000ef4 in int S::foo(void) "c++over.C":59 { break }
           (Ladebug)

           To set a breakpoint that stops in all versions of an
           overloaded function, use one of the following syntax
           lines:

           stop in all  function

           stop in all  class_name::function

           In Example 9-13 the breakpoint is set for all versions of
           the overloaded function foo.




     9-24 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                            9.11 Setting Breakpoints in Member Functions

              Example 9-13 Setting Breakpoints in All Versions of an
                           Overloaded Function

              (Ladebug) class S
              class S  {
                int i;
                float f;
                double d;
                char c;
                S (void);
                ~S (void);
                int foo (void);
                int foo ( S);
                int foo ( S *);
                int foo (int&);
                int foo (const int&);
                int foo (float*&);
                int foo (int, float, char *, unsigned short, long&, const char*&);
                int foo (const double *);
                int foo (char);
                void foo (short);
                void foo (unsigned);
                void foo (long);
                void foo (int, float, char *, unsigned short, long&, char*&);
                void foo (double);
                void foo (char *);
                void foo (const char *);
              }

              (Ladebug) stop in all foo
              [#1: stop in all foo ]
              (Ladebug)

              You can also set a breakpoint in an overloaded function by
              setting a breakpoint at the line number where the function
              begins. Be sure the current file context points to the
              file containing the function's source code before setting
              the breakpoint. In Example 9-14 the breakpoint is set for
              the overloaded functions by line number.






                                         Using the Ladebug Debugger 9-25

 



     Using the Ladebug Debugger
     9.11 Setting Breakpoints in Member Functions

           Example 9-14 Setting Breakpoints in Overloaded Functions
                        by Line Number

           (Ladebug) stop at 59
           [#1: stop at "c++over.C":59 ]
           (Ladebug) stop at 156
           [#2: stop at "c++over.C":156 ]

           (Ladebug) status
           #1 PC==0x120000ef4 in S::foo(void) "c++over.C":59 { break }
           #2 PC==0x120001508 in S::foo(double) "c++over.C":156 { break }
           (Ladebug)


     9.11.2 Setting Breakpoints in Constructors and Destructors

           To set a breakpoint in a constructor, use one of the
           following syntax lines:

           stop in  class_name::class_name [(type_signature)]

           stop in  class_name [(type_signature)]

           The type signature is necessary only to resolve the
           ambiguity for a constructor that is overloaded. In
           Example 9-15, a breakpoint is set in a constructor.

           Example 9-15 Setting Breakpoints in Constructors

           (Ladebug) class S
           class S  {
             int i;
             int j;
             S (void);
             ~S (void);
             int foo (void);
             virtual int bar (void);
           }
           (Ladebug) stop in S
           [#1: stop in S::S(void) ]
           (Ladebug) status
           #1 PC==0x1200005b8 in S::S(void) "c++ex.C":5 { break }
           (Ladebug)


     9-26 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                            9.11 Setting Breakpoints in Member Functions

              You can similarly set a breakpoint in a destructor using
              the following syntax:

              stop in  ~class_name

              In Example 9-16, the breakpoint is set for the destruc-
              tor.

              Example 9-16 Setting Breakpoints in Destructors

              (Ladebug) stop in ~S
              [#1: stop in S::~S(void) ]

              (Ladebug) status
              #1 PC==0x1200005f8 in S::~S(void) "c++ex.C":6 { break }
              (Ladebug)

              As with any function's type signature specification,
              constructors and destructors that have no parameters must
              be referenced with a type signature of void.

        9.12 Calling Overloaded Functions

              To call overloaded functions from the debugger, you must
              set $overloadmenu to 1. Then, use the following call
              command syntax:

              call  function ([parameter[, . . . ]])

              The debugger will call the function that you select
              from the menu of overloaded names. In Example 9-17 the
              overloaded function foo is called.

              Example 9-17 Calling an Overloaded Function

              (Ladebug) set $overloadmenu = 1
              (Ladebug) call foo(15)

                                                (continued on next page)






                                         Using the Ladebug Debugger 9-27

 



     Using the Ladebug Debugger
     9.12 Calling Overloaded Functions

           Example 9-17 (Cont.) Calling an Overloaded Function

           Enter the number of the overloaded function you want
           ----------------------------------------------------
                1 void foo (const char *)
                2 void foo (char *)
                3 void foo (double)
                4 void foo (float)
                5 void foo (unsigned)
                6 void foo (long)
                7 void foo (short)
                8 int foo (const double *)
                9 int foo (int, float)
               10 int foo (float*&)
               11 int foo (const int&)
               12 int foo (int&)
               13 int foo (char)
               14 int foo ( S *)
               15 int foo ( S)
               16 None of the above
           ----------------------------------------------------

           6
           global foo (long):              15
           (Ladebug)

     9.13 Using Typecasts to Display Program Expressions

           When debugging C++ programs, the debugger interprets casts
           as defined in the International C++ Standard. A cast has
           the following syntax:

           (type) variable

           The type is the type the debugger will use to interpret
           the program variable variable. The debugger does not allow
           cast conversion from an unsigned short type to a long int
           type.

           In Example 9-18, a variable of type float is interpreted
           as an integer.




     9-28 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                     9.13 Using Typecasts to Display Program Expressions

              Example 9-18 Using a Cast to Perform Data Coercion

              (Ladebug) whatis f
              float f
              (Ladebug) print f
              3.2

              (Ladebug) print (int)f
              3
              (Ladebug)

              You can also use casts to interpret a base class object
              as a derived class object, or to interpret a derived
              class object as a base class object. In Example 9-19,
              the class derived inherits the public members of class
              base. A pointer to an object of class derived is declared
              to be a pointer to an object of class base. A cast is used
              to display the object's contents using the correct class
              type.

              Example 9-19 Using Casts on a Derived Class Object

              (Ladebug) whatis bvar
               base * bvar
              (Ladebug) whatis derived
              class derived : base {
                int i;
                derived (void);
                ~derived (void);
                virtual int foo (void);
              } derived
              (Ladebug) whatis base
              class base  {
                int j;
                base (void);
                ~base (void);
                virtual int foo (void);
              } base
              (Ladebug) print *bvar
              class {
                      j = 0;
                  }

                                                (continued on next page)

                                         Using the Ladebug Debugger 9-29

 



     Using the Ladebug Debugger
     9.13 Using Typecasts to Display Program Expressions

           Example 9-19 (Cont.) Using Casts on a Derived Class
                                Object

           (Ladebug) print *(derived *)bvar
           class {
                   base = class {
                       j = 0;
                   };
                   i = 4195376;
               }
           (Ladebug)

           Example 9-20 shows how to use a type transfer to interpret
           a variable of type float as an integer.

           Example 9-20 Using a Cast with Pointer Notation to
                        Perform a Type Transfer

           (Ladebug) print &f
           0x11ffffe84

           (Ladebug) print *(int *)&f
           1078774989
           (Ladebug)

           You can also perform the type transfer shown in this
           example by using C++ reference types. Example 9-21 shows
           how to use reference type notation to perform a type
           transfer.

           Example 9-21 Using a Cast with Reference Type Notation to
                        Perform a Type Transfer

           (Ladebug) print &f
           0x11ffffe84

           (Ladebug) print (int&)f
           1078774989
           (Ladebug)






     9-30 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                             9.14 Class Templates and Function Templates

        9.14 Class Templates and Function Templates

              The debugger provides support for debugging class
              templates and function templates in much the same way as
              other classes and functions in C++, with the limitations
              described in this section.

              You can use the whatis command on an instantiation of the
              function template as shown in Example 9-22.

              Example 9-22 Example of a Function Template

              (Ladebug) list 1
                    1 // remember to compile with -define_templates
                    2 template<class T> int compare(T t1, T t2)
                    3 {
                    4         if (t1 < t2) return 0;
                    5         else         return 1;
                    6 }
                    7
                    8 main()
                    9 {
              >    10         int i = compare(1,2);
                   11 }

              (Ladebug) whatis compare
              int compare (int, int)
              (Ladebug)

              You can set a breakpoint in a template function as shown
              in Example 9-23.

              Example 9-23 Setting a Breakpoint in the Template
                           Function

              (Ladebug) stop in compare
              [#2: stop in compare(int, int) ]








                                         Using the Ladebug Debugger 9-31

 



     Using the Ladebug Debugger
     9.14 Class Templates and Function Templates


           (Ladebug) run
           [2] stopped at [compare(int, int):4 0x120000560]
                 4         if (t1 < t2) return 0;
           (Ladebug)

           As shown in Example 9-24, while inside the function
           template, you can set or ask for the current function con-
           text, and the instantiated function will be displayed.


           Example 9-24 Displaying the Current Function Context for
                        a Function Template

           (Ladebug) func
           compare(int, int) in c++functemp.C line No. 4:
                 4         if (t1 < t2) return 0;
           (Ladebug)

           For class templates, you cannot use the whatis command
           with the template name, but you can use the whatis command
           on a specific instantiation of the class template. This
           is the instantiated name that the debugger prints when
           it encounters variables of the template class type.
           Example 9-25 displays the class definition of a particular
           instantiation of a parameterized stack.

           Example 9-25 Displaying an Instantiated Class Template

                                             (continued on next page)















     9-32 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                             9.14 Class Templates and Function Templates

              Example 9-25 (Cont.) Displaying an Instantiated Class
                                   Template

              (Ladebug) list 1, 24
                    1 #include <iostream.h>
                    2
                    3 template <class T, int size> class stack {
                    4         T s[size];
                    5         int top;
                    6 public:
                    7         stack() { top = 0; }
                    8         void push(T item)
                    9              {
                   10               s[top++] = item;
                   11              }
                   12         T pop();
                   13 };
                   14
                   15 template<class T, int size> T stack<T,size>::pop()
                   16 {
                   17         return s[--top];
                   18 }
                   19
                   20 stack<int,10*10> S;
                   21 stack<double,10> F;
                   22
                   23 #pragma define_template stack<int,100>
                   24 #pragma define_template stack<double,10>

              (Ladebug) whatis stack<int,100>
              class stack<int,100>  {
                array [subrange 0 ... 99 of int] of int s;
                int top;
                stack<int,100> (void);
                void push (int);
                int pop (void);
              } stack<int,100>
              (Ladebug)

              Similarly, as shown in Example 9-26, you can use the
              whatis S command. The instance of S is displayed as
              stack<int,100> rather than just S.



                                         Using the Ladebug Debugger 9-33

 



     Using the Ladebug Debugger
     9.14 Class Templates and Function Templates

           Example 9-26 Displaying an Instantiated Class Template

           (Ladebug) whatis S
           class stack<int,100>  {
             array [subrange 0 ... 99 of int] of int s;
             int top;
             stack<int,100> (void);
             void push (int);
             int pop (void);
           } S
           (Ladebug)

           As shown in Example 9-27, you can set breakpoints in
           template functions and ask for the current function
           context while inside a template function.

           Example 9-27 Setting Breakpoints in an Instantiated Class
                        Function

           (Ladebug) stop in S.pop
           [#1: stop in stack<int,100>::pop(void) ]
           (Ladebug) run
           stopped at [stack<int,100>::pop(void):17 0x120001e0c]
                17         return s[--top];
           (Ladebug) func
           stack<int,100>::pop(void) in c++classtemp.C line No. 17:
                17         return s[--top];

           (Ladebug) print top
           2
           (Ladebug)

           You can explicitly set your current class scope to a
           particular instantiation of a class template if you
           are not in the proper class scope. See Example 9-28 and
           Example 9-29.

           Example 9-28 Setting Current Class Scope to an Instantiated
                        Class

                                             (continued on next page)




     9-34 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                             9.14 Class Templates and Function Templates

              Example 9-28 (Cont.) Setting Current Class Scope to an
                                   Instantiated Class

              (Ladebug) stop in push
              Symbol push not visible in current scope.
              push has no valid breakpoint address
              Warning: Breakpoint not set
              (Ladebug) class
              Current context is not a class
              (Ladebug) class S
              class stack<int,100>  {
                array [subrange 0 ... 99 of int] of int s;
                int top;
                stack<int,100> (void);
                ~stack<int,100> (void);
                void push (int);
                int pop (void);
              }
              (Ladebug) stop in push
              [#4: stop in stack<int,100>::push(int) ]

              (Ladebug) run
              [4] stopped at [stack<int,100>::push(int):10 0x120001cd0]
                   10               s[top++] = item;
              (Ladebug)

              Example 9-29 Alternate Method of Setting Current Class
                           Scope

              (Ladebug) class stack<int,100>
              class stack<int,100>  {
                array [subrange 0 ... 99 of int] of int s;
                int top;
                stack<int,100> (void);
                ~stack<int,100> (void);
                void push (int);
                int pop (void);
              }

                                                (continued on next page)





                                         Using the Ladebug Debugger 9-35

 



     Using the Ladebug Debugger
     9.14 Class Templates and Function Templates

           Example 9-29 (Cont.) Alternate Method of Setting Current
                                Class Scope

           (Ladebug) stop in push
           [#5: stop in stack<int,100>::push(int) ]
           (Ladebug)

           Additional limitations for debugging templates include:

           o  You cannot specify a template by name in a debugger
              command. You must use the name of the instantiation of
              the template.

           o  In C++, expressions in the instantiated template
              name can be full constant expressions such as
              stack<double,f*10>. This form is not yet supported
              in the Ladebug debugger; you must enter the value of
              the expression (for example, if f is 10 in the stack
              example, you must enter 100).

           o  Setting a breakpoint at a line number that is inside
              a template function will not necessarily stop at all
              instantiations of the function within the given file,
              but only a randomly chosen few. This limitation is
              due to the limited symbol information generated by the
              compiler for templates.

     9.15 Debugging C++ Exception Handlers

           You can debug C++ exception handlers in programs by
           setting breakpoints in the exception handler or in the
           predefined C++ functions that are used when exceptions
           occur. You can also examine and modify variables that are
           used in exception handlers.

     9.15.1 Setting Breakpoints in Exception Handlers

           As shown in Example 9-30, you can set a breakpoint in
           an exception handler by setting a breakpoint at the line
           number where the code for the exception handler begins.
           You can then step through the exception handler, examine
           or modify variables, or continue executing the program.



     9-36 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                                   9.15 Debugging C++ Exception Handlers

              Example 9-30 Setting Breakpoints in Exception Handlers

              (Ladebug) list 24
                   24     try
                   25     {
                   26          foo();
                   27     }
                   28     catch(char * str) { printf("Caught %s.\n",str); }
                   29     catch(...) { printf("Caught something.\n"); }
                   30
                   31 return 0;
                   32 }
              (Ladebug) stop at 24
              [#1: stop at "except.C":26 ]
              (Ladebug) stop in unexpected
              [#2: stop in unexpected ]
              (Ladebug) run
              [1] stopped at [int main(void):26 0x400370]
                   26          foo();
              (Ladebug) cont
              [2] stopped at [unexpected:631 0x4010a8]
              (Cannot find source file cxx_exc.c)
              (Ladebug) cont
              In my_unexpected().
              Caught HELP.
              Thread has finished executing
              (Ladebug)

              As this example shows, you can also set breakpoints in C++
              functions used to handle exceptions as follows:

              terminate   Gains control when any unhandled exception
                          occurs

              unexpected  Gains control when a function containing
                          an exception specification tries to throw
                          an exception that is not in the exception
                          specification







                                         Using the Ladebug Debugger 9-37

 



     Using the Ladebug Debugger
     9.15 Debugging C++ Exception Handlers

     9.15.2 Examining and Modifying Variables in Exception Handlers

           After you set a breakpoint to stop the execution in the
           exception handler, you can access the variables used in
           the exception handler the same way you would examine and
           modify other program variables.

     9.16 Advanced Program Information: Verbose Mode

           By default, the debugger gives no information on virtual
           base class pointers for the following:

           o  Derived classes

           o  Virtual pointer tables for virtual functions

           o  Compiler-generated function members

           o  Compiler-generated temporary variables

           o  Implicit parameters in member functions

           By setting the $verbose debugger variable to 1, you can
           request that this information be printed in subsequent
           debugger responses. This section explains the normally
           suppressed information that the debugger provides if the
           $verbose debugger variable is set to 1.

           When the $verbose debugger variable is set to 1 and you
           display the contents of a class using the whatis command,
           several of the class members listed are not in the source
           code of the original class definition. The following line
           shows sample output from the whatis command:

           array [subrange 0 ... 0 of int] of vtable * _\|_vptr;

           The vtable variable contains the addresses of all virtual
           functions associated with the class. Several other class
           members are generated by the compiler for internal use.
           When the $verbose debugger variable is set to 1, you
           can see these members and reference them as you would
           reference any other member function.

           The compiler generates additional parameters for nonstatic
           member functions. When the $verbose debugger variable is
           set to 1, these extra parameters are displayed as part of
           each member function's type signature.

     9-38 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                         9.16 Advanced Program Information: Verbose Mode

              If you are specifying a version of an overloaded function
              by entering its type signature and the $verbose variable
              is set to 1, you must include these parameters.

              If the $verbose debugger variable is set to 0, you should
              not include the compiler-generated parameters in the type
              signature. When the $verbose variable is set to 1, the
              output of the dump command includes not only standard
              program variables but also compiler-generated temporary
              variables.

              Example 9-31 prints class information using the whatis
              command when the $verbose variable is set to 1.

              Example 9-31 Printing a Class Description in Verbose Mode

              (Ladebug) print $verbose
              0
              (Ladebug) whatis S
              class S  {
                int i;
                int j;
                S (void);
                ~S (void);
                int foo (void);
                virtual int bar (void);
              } S
              (Ladebug) set $verbose = 1
              (Ladebug) print $verbose
              1

                                                (continued on next page)













                                         Using the Ladebug Debugger 9-39

 



     Using the Ladebug Debugger
     9.16 Advanced Program Information: Verbose Mode

           Example 9-31 (Cont.) Printing a Class Description in
                                Verbose Mode

           (Ladebug) whatis S
           class S  {
             int i;
             int j;
             array [subrange 0 ... 0 of int] of vtbl * _\|_vptr;
             S (S* const);
             S (S* const, const S&);
             ~S (S* const, int);
             int foo (S* const);
             S& operator = (S* const, const S&);
             virtual int bar (S* const);
           } S
           (Ladebug)

           When displaying information on virtual base classes, the
           debugger prints pointers to the table describing the
           base class for each virtual base class object member.
           This pointer is known as the base pointer bptr. The bptr
           pointer is printed after the class member information.
           Example 9-32 shows a print command that displays the bptr
           pointer information when the $verbose variable is set to
           1.

           Example 9-32 Printing Base Pointer Information

           (Ladebug) stop at 66
           [#1: stop at "c++multinher.C":66 ]
           (Ladebug) run
           0
           1
           3
           [1] stopped at [main(void):66 0x1200010b8]
                66   printf("%d\n", dinst.f());

                                             (continued on next page)







     9-40 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                         9.16 Advanced Program Information: Verbose Mode

              Example 9-32 (Cont.) Printing Base Pointer Information

              (Ladebug) whatis dinst
              class D : B, C {
                D (void);
                ~D (void);
                void g (void);
              } dinst
              (Ladebug) print dinst
              class {
                      B = class {
                          V = class {
                              v = 1;
                              x = 3;
                          };
                          x = 2;
                          ambig = 2;
                      };
                      C = class {
                          V = class {
                              v = 1;
                              x = 3;
                          };
                          ambig = 3;
                      };
                  }
              (Ladebug) set $verbose = 1

                                                (continued on next page)
















                                         Using the Ladebug Debugger 9-41

 



     Using the Ladebug Debugger
     9.16 Advanced Program Information: Verbose Mode

           Example 9-32 (Cont.) Printing Base Pointer Information

           (Ladebug) print dinst
           class {
                   B = class {
                       V = class {
                           v = 1;
                           x = 3;
                       };
                       x = 2;
                       ambig = 2;
                       _\|_bptr = 0x10001168;
                   };
                   C = class {
                       V = class {
                           v = 1;
                           x = 3;
                       };
                       ambig = 3;
                       _\|_bptr = 0x1000116c;
                   };
                   _\|_bptr = 0x10001168;
               }
           (Ladebug)

           When a class appears on the stack and the $verbose
           debugger variable is set to 0, the class's members are
           represented with an ellipsis { . . . }. When the $verbose
           debugger variable is set to 1, the debugger prints all
           members of classes on the stack trace.

           Example 9-33 shows that member functions on the stack
           trace are printed with their this pointer value explicitly
           when the $verbose variable is set to 1.

           Example 9-33 Printing a Stack Trace in Verbose Mode

                                             (continued on next page)







     9-42 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                         9.16 Advanced Program Information: Verbose Mode

              Example 9-33 (Cont.) Printing a Stack Trace in Verbose
                                   Mode

              (Ladebug) where
              >0  0x120000789in ((S*)0x10000010)->bar(t={ ... }) c++exv.C:42
              #1  0x1200008bc in main() c++exv.C:50
              (Ladebug) set $verbose = 1
              (Ladebug) where
              >0  0x120000789c in ((S*)0x10000010)->bar(this=0x10000010, t=class {
                      i = 1;
                      j = 2;
                      _\|_vptr = 0x10000960;
                      virtual T::tbar = (function [0x400290]);
                  }) c++exv.C:42
              #1  0x1200008bc in main() c++exv.C:50
              (Ladebug)


        9.17 Reducing Object File Size During Debugging

              With Version 5.6 and higher, the compiler reduces the
              amount of debugging information in object files when -g is
              specified. If the debugger describes a class as <opaque>
              or lacks debugging information, you may need to compile
              using the -gall option. See Section 9.17.1 for information
              on how to use the -gall option.

              Before Version 5.6, debug information for classes and
              structs was generated whenever they were processed by
              the compiler. Thus, debug information for particular
              classes and structs defined in header files often appeared
              in multiple object files, which increased the overall
              size of objects and executables. To reduce debuggable
              executable size, the compiler now attempts to generate
              debug information for a particular class or struct as few
              times as possible. Describing classes and structs this way
              has tremendous savings; reductions in executable sizes of
              up to 70% have been observed for some applications.







                                         Using the Ladebug Debugger 9-43

 



     Using the Ladebug Debugger
     9.17 Reducing Object File Size During Debugging

           In most cases, the object file that contains the debug
           information for a particular class is linked into the
           executable and is available to the debugger. However,
           there are some situations where this might not be the
           case:

           o  A class description may be in a library object
              file that is not linked into the final debuggable
              executable.

           o  A class description may be in a different shared object
              than the shared object you may be trying to debug.

           o  The object file that would have contained the class
              description does not because it was compiled without
              the -g option.

     9.17.1 Using the -gall and -gall_pattern Options

           If Ladebug describes a class or struct as <opaque>, you
           should compile the file in which the class or struct is
           described as <opaque> with the -gall option. Compiling a
           file with the -gall option generates debug information for
           all classes and structs that appear in that source file.

           You can generate complete debugging information when
           compiling a particular file by specifying the -gall option
           on the command line. You can also define a pattern using
           the -gall_pattern option so that a file is compiled with
           complete debugging only if the file name matches the
           pattern. Specifying -gall_pattern lets you compile all
           files with the same command and still have particular
           files compiled with the -gall option to generate complete
           debugging information. You can specify a pattern in two
           ways:

           o  Specify -gall_pattern on the command line

           o  Define environment variable CXX_GALL_PATTERN as the
              pattern

           The -gall_pattern option accepts a list of file names
           (with each file name separated by a comma or colon),
           filename patterns, or a combination of a file name list
           and filename patterns. See fnmatch(3) for valid filename
           patterns.

     9-44 Using the Ladebug Debugger

 



                                              Using the Ladebug Debugger
                         9.17 Reducing Object File Size During Debugging

              If you specify -gall, -g is assumed. The -gall_pattern
              option is ignored unless -g, -g2, or -g3 is also
              specified.

              Example:

              The following example shows how opaque_class is initially
              described as <opaque> by Ladebug, and how this is remedied
              by compiling the file opaque_file.cxx with the -gall
              option:

              Welcome to the Ladebug Debugger Version 4.0-48
               . . .

                   object file name: opaque_file
                   Reading symbolic information ...done
                   (Ladebug) # First, note the class is <opaque>
                   (Ladebug) whatis opaque_class
                   class opaque_class <opaque>

                   Information:  An <opaque> type was presented during execution of the previous
                   command.  For complete type information on this symbol, recompilation of the
                   program will be necessary.  Consult the compiler man pages for details on
                   producing full symbol table information using the -g (and -gall) for cxx)
                   flags.

                   (Ladebug) # Next, find the offending file with Ladebug's "file" command
                   (Ladebug) file
                   opaque_file.cxx
                   (Ladebug) # Quit to recompile opaque_file.cxx with the -gall option
                   (Ladebug) quit

              Recompile the file opaque_file.cxx with the -gall option
              in one of the following ways:

              o  Supply -gall on the command line (useful for hand
                 builds):

                      cxx -g -gall -O0 opaque_file.cxx

              o  Supply -gall_pattern (useful for a generic rule in a
                 makefile):

                      cxx -g -gall_pattern opaque_file.cxx -O0 opaque_file.cxx

                                         Using the Ladebug Debugger 9-45

 



     Using the Ladebug Debugger
     9.17 Reducing Object File Size During Debugging

              In a makefile, this may look something like the
              following:

                   CXX      = cxx
                   CXXFLAGS = -g -gall_pattern opaque_file.cxx -O0
                   $(CXX) $(CXXFLAGS) opaque_file.cxx

           o  Supply the pattern to the environment variable CXX_
              GALL_PATTERN (useful for not modifying the makefile):

                   setenv CXX_GALL_PATTERN "opaque_file.cxx"
                   cxx -g -O0 opaque_file.cxx

           Here are some alternate methods, showing the pattern
           capabilities of the -gall_pattern option:

           o  Compile both opaque_file.cxx and another_file.cxx with
              -gall_pattern:

              cxx -g -gall_pattern opaque_file.cxx,another_file.cxx -O0 opaque_file.cxx

           o  Compile any file starting with opaque or another with
              -gall_pattern:

                   setenv CXX_GALL_PATTERN "opaque*.cxx:another*.cxx"
                   cxx -g -O0 opaque_file.cxx

     9.17.2 Hints for Using the -gall Option Effectively

           For best debugging and smallest objects and executables,
           we recommend that you use the -gall option selectively as
           follows:

           o  Use the -gall option only when you see a class or
              struct described as <opaque>.

           o  Try to compile as few files with -gall as possible.

           o  Choose these few files wisely. If you are seeing
              <opaque> types in only one file, try compiling only
              that file with the -gall option. If you are seeing
              <opaque> types in many files, try compiling a file
              that includes many project header files with the -gall
              option. Doing so will increase the chance that <opaque>
              messages will disappear for the entire application.

     9-46 Using the Ladebug Debugger

 









                                                                       A
        ________________________________________________________________

                                              Class Library Restrictions



              This appendix describes known problems and restrictions
              for the Class Library. Please note that String Package,
              which is part of the 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.

              Note also that the task package is not supported on the
              Linux Alpha platform and will soon be retired from the
              Tru64 UNIX platform.

              The following restrictions apply for the C++ Class
              Library:

              o  Conflict with redefinition of clear()

                 If your program includes both <curses.h> and <iostream.hxx>,
                 Compaq C++ might 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.

              o  Because of a bug in the task package, if you are using
                 that package and you compiled your application with
                 Compaq C++ Version 6.n, your application may encounter
                 runtime errors such as segmentation faults. To avoid

                                          Class Library Restrictions A-1

 



     Class Library Restrictions


              these problems, recompile your application specifying
              the -preempt_symbol option. For more information about
              the -preempt_symbol option, see the cxx(1) reference
              page.

           o  Use of clog() and the iostream package's clog

              A single application is restricted from using both
              the math library function clog() and the iostream
              package's clog object. This restriction is necessary
              because libm and libcxx each contain a definition
              for the global symbol clog and these definitions are
              incompatible.

              For example, consider a program that makes use of the
              iostream clog object:

                   #include <stdlib.h>
                   #include <iostream.hxx>
                   int main()
                   {
                       clog << "abc";
                       return EXIT_SUCCESS;
                   }

              If you link with the math library first as:

                   cxx clog.cxx -lm -lcxx

              Executing the program results in a segmentation fault.
              The compiler links against shared object libraries
              by default. Identical symbols in subsequent object
              libraries are resolved to the first definition by the
              symbol preemption feature. So in this case use of clog
              from iostreams is resolved to the definition in libm.

              If you link -non_shared with the math library first as:

                  cxx clog.cxx -non_shared -lm -lcxx

              The linker gives a multiply defined message similar to
              the following:

                  ld:
                  /usr/lib/cmplrs/cxx/libcxx.a(iostream_globals.o): clog: multiply defined

     A-2 Class Library Restrictions

 



                                              Class Library Restrictions


                 In this case, if you link with the Class Library first,
                 the program executes correctly. As described earlier,
                 the compiler links against shared object libraries
                 by default. Identical symbols in subsequent object
                 libraries are resolved to the first definition by the
                 symbol preemption feature. So in this case use of clog
                 from iostreams is resolved to the definition in libcxx:

                      cxx clog.cxx -lcxx -lm

                 Therefore, applications that reference either of the
                 clog symbols should not include both -lcxx and -lm on
                 their ld command line.

              o  Displacing global operator new in C++ Standard
                 Library/Class Library

                 If a C++ program defines a global operator new() that
                 is intended to displace the version used by the C++
                 Standard Library, it must be compiled with the compiler
                 command line switch -stdnew. If a C++ program defines
                 a global operator new() which is intended to displace
                 the version used by the C++ Class Library, it must
                 be compiled with the compiler command line switch
                 -nostdnew.

              o  Restrictions on printing some cases of bool/wchar_t
                 Types with pre-ANSI Library

                 Objects of a class which contain a user defined
                 conversion operator to either bool or wchar_t can
                 not be output directly with cout when including
                 <iostream.h>. For example, the following program will
                 give compilation errors indicating that more than one
                 operator "<<" matches these operands:

                      #include <stdlib.h>
                      #include <iostream.h>
                      struct B {
                          operator bool() { return true; }
                      };
                      struct W {
                          operator wchar_t() { return L'0'; }
                      };

                                          Class Library Restrictions A-3

 



     Class Library Restrictions


                   int main() {
                       B b;
                       cout << b << endl;  // V6.1 ambiguity error
                       W w;
                       cout << w << endl;  // V6.1 ambiguity error
                       return EXIT_SUCCESS;
                   }

              If you try to output the subscript operator of
              vector<bool> directly with cout, you will encounter
              this problem in the library. The following will
              generate an ambiguity error:

              #include <stdlib.h>
              #include <iostream.h>
              #include <vector>

              int main ()
              {
                  vector<bool> vb;
                  // V6.1 ambiguity error
                  cout << vb[1] << endl;
                  return EXIT_SUCCESS;
              }

              The workaround is to cast your class to either (bool)
              or (wchar_t) respectively. You would code the previous
              programs as follows:

              #include <stdlib.h>
              int main() {
                  B b;
                  cout << (bool)b << endl;
                  W w;
                  cout << (wchar_t)w << endl;
                  return EXIT_SUCCESS;
              }

              int main ()
              {
                  vector<bool> vb;
                  cout << (bool)vb[1] << endl;
                  return EXIT_SUCCESS;
              }

     A-4 Class Library Restrictions

 



                                              Class Library Restrictions


              o  The Class Library does not include support for 128-bit
                 long doubles.

              o  The Class Library has many non-reserved names that are
                 declared in the global namespace. Using any name that
                 that includes the prefixes cxxl_ or decc$ or any of the
                 following names (except as they are intended to be used
                 from the Class Library) at global scope can lead to
                 unpredictable results and should be avoided:

        Mutex                String               InternalMutex

        Stopwatch            iostream             ostream

        istream              ostream_withassign   istream_withassign

        iostream_withassign  Iostream_init        fstream

        ifstream             ofstream             streambuf

        strstream            ios                  cout

        cin                  clog                 cerr

        lock                 unlock               setfill

        resetiosflags        dec                  hex

        octendl              ends                 flush

        ws                   setw                 smanip_*

        imanip_*             omanip_*             iomanip_*

        smanipref_*          imanipref_*          omainpref_*

        iomanipref_*         vector               stack

        Messages             Objection            setprecision

        setiosfill

                 If linking with complex: complex

                 If linking with task:

        task                 object               sched

        timer                qhead                qtail

        randint              urand                erand

        Interrupt_handler    histogram

                                          Class Library Restrictions A-5

 









                                                                       B
        ________________________________________________________________

                                                      Built-In Functions



              This appendix describes built-in functions available when
              you compile on Compaq Tru64 UNIX and Linux Alpha systems.
              These functions allow you to access hardware and machine
              instructions directly.

              Be sure to include the <machine/builtins.h> header
              file in your source program to access these built-in
              functions. Definitions for return types int64 and uint64
              are contained in the header file ints.h.

              Translation Macros

              Compaq C++ supports the following translation macros for
              built-in functions:

              _BBCCI(position, address)

              _BBSSI(position, address)

              In-line Assembly Code-ASMs

              The compiler supports in-line assembly code, commonly
              called ASMs on UNIX platforms.

              Like builtin-functions, ASMs are implemented with a
              function-call syntax. But unlike built-in functions,
              to use ASMs you must include the <c_asm.h> header file
              containing prototypes for the three types of ASMs, and the
              #pragma intrinsic preprocessor directive.

              These functions have the following format:

              __int64  asm(const char *, . . . );   /* for integer
        operations, like MULQ */
              float fasm(const char *, . . . );    /* for single
              precision float instructions, like MULS */
              double dasm(const char *, . . . );    /* for double
              precision float instructions, like MULT */

                                                  Built-In Functions B-1

 



     Built-In Functions


           #pragma intrinsic (asm, fasm, dasm)

           const char *
           The first argument to the asm, fasm, or dasm function
           contains the instruction(s) to be generated inline and
           the metalanguage that describes the interpretation of the
           arguments.

            . . .
           The source and destination arguments (if any) for the
           instruction being generated, and any other values used in
           the generated instructions.

           These values are made available to the instructions
           through the normal argument passing conventions of the
           calling standard (the first integer argument is available
           in register R16).

           The #pragma intrinsic directive in the <c_asm.h> header
           file is required when using ASMs. It notifies the compiler
           that:

           o  These functions are not user-defined functions.

           o  The special ASM processing should be applied to
              analyze at compile time the first argument and generate
              machine-code instructions as specified by the contents
              of the string.

           The metalanguage for the argument references has the
           following form:

           <metalanguage_sequence> : <register_alias>
                                   | <register_number>
                                   | <register_macro>
                                   ;

           <register_number>       : "$" number
                                   ;

           <register_macro>        : "%" <macro_sequence>
                                   ;



     B-2 Built-In Functions

 



                                                      Built-In Functions


              <macro_sequence>        : number
                                      | <register_name>
                                      | "f" number | "F" number
                                      | "r" number | "R" number
                                      ;

              <register_name> :     /* argument registers: R16-R21 */
                                   "a0" | "a1" | "a2" | "a3" | "a4" | "a5"

                                   /* return value: R0 or F0, depending on type */
                                 | "v0"

                                   /* scratch registers: R1, R22-R24, R28 */
                                 | "t0" | "t1" | "t2" | "t3" | "t4"

                                   /* save registers: R2-R15 */
                                 | "s0" | "s1" | "s2" | "s3" | "s4"  | "s5"  | "s6"  | "s7"
                                 | "s8" | "s7" | "s8" | "s9" | "s10" | "s11" | "s12" | "s13"

                                   /* stack pointer: R30 */
                                 | "sp" | "SP" | "$sp" | "$SP"

                                 | "RA" | "ra"           /* return addr:        R26  */
                                 | "PV" | "pv"           /* procedure value:    R27  */
                                 | "AI" | "ai"           /* arg info:           R25  */
                                 | "FP" | "fp"           /* frame pointer:      R29  */
                                 | "RZ" | "rz" | "zero"  /* sink/source: R31 == zero */

              Syntactically, the metalanguage can appear anywhere within
              an instruction sequence.

              The literal string that contains instructions, operands,
              and metalanguage must follow the general form:

                                      <string_contents>       :  <instruction_seq>
                                      |  <string_contents> ";" <instruction_seq>
                                      |  error
                                      |  <string_contents> error
                                      ;

              <instruction_seq>       :  instruction_operand
                                      |  directive
                                      ;

              An instruction_operand is generally recognized as an
              assembly language instruction separated by whitespace
              from a sequence of comma-separated operands.

                                                  Built-In Functions B-3

 



     Built-In Functions


           You can code multiple instruction sequences into one
           literal string, separating them by semicolons.

           Because adjacent string literals are concatenated into
           a single string, successive instructions can be written
           as separate strings, one per line (as is normally done
           in assembly language) as long as each instruction is
           terminated by a semicolon (as shown in the examples).

           There are semantic and syntax rules associated with ASMs:

              The first argument to an ASM call is interpreted as
              the instructions to be assembled in the metalanguage,
              and must be fully understood by the compiler at compile
              time. Therefore, it must be a literal string (or a
              macro expanding to a literal string) and must not be
              a run-time value containing a string. Therefore, the
              following are not allowed: indirections, table lookups,
              structure dereferences, and so on.

              The remaining arguments are loaded into the argument
              registers like normal function arguments, except that
              the second argument to the ASM call is treated as the
              first argument for purposes of the calling standard.

              For example, in the following test, the six arguments
              are loaded into arg registers a0 through a5, and the
              result of each subexpression is stored in the value
              return register v0. Since v0 is the calling standard's
              return value register (R0 for an integer function), the
              result of the final MULQ is the value returned by the
              "call":

                 if (asm("mulq %a0, %a1,  %v0;"
                         "mulq %a2, %v0,  %v0;"
                         "mulq %a3, %v0,  %v0;"
                         "mulq %a4, %v0,  %v0;"
                         "mulq %a5, %v0,  %v0;", 1, 2, 3, 4, 5, 6) != 720){
                   error_cnt++;
                   printf ("Test failed\n");
                      }




     B-4 Built-In Functions

 



                                                      Built-In Functions


                 The following example does not work. There is no
                 value loaded into the floating-point return register.
                 Furthermore, it results in a compile-time warning
                 stating that r2 is used before it is set, because the
                 arguments are loaded into the arg registers and not
                 into r2:

                 z =  fasm("mulq %r2, %a1 %r5", x=10, y=5);

                 The correct way of doing this is to specify an argument
                 register number in place of r2. A correct version of
                 the above would be:

                 z = fasm("mulq   %a0, %a1, %a1;"
                          "stq    %a1, 0(%a2);"
                          "ldt    %f0, 0(%a2);"
                          "cvtqf  %f0, %f0;",  x=10, y=5, &temp);

                 Note that the memory location used for the transfer
                 from integer to floating-point register is made
                 available to the asm code by passing as an argument
                 the address of a variable allocated in the C code for
                 that purpose.

              o  A return register must be specified in the metalanguage
                 for the result to appear in the expected place.

              o  For intructions that do not take any argument and do
                 not have a return type, leave out the arguments. For
                 example:

                 asm("MB");

              Privileged Architecture Library Code Instructions

              The following Privileged Architecture Library Code
              (PALcode) instructions are available as built-in
              functions:

              __PAL_GENTR
              __PAL_HALT
              __PAL_BPT
              __PAL_BUGCHK
              __PAL_DRAINA

                                                  Built-In Functions B-5

 



     Built-In Functions


           __PAL_BPT

           This function is provided for program debugging. It
           switches the processor to kernel mode and pushes registers
           R2 to R7, the updated PC, and PS onto the kernel stack. It
           then dispatches to the address in the breakpoint vector,
           which is stored in a control block.

           This function has the following format:

           void  __PAL_BPT (void);

           __PAL_BUGCHK

           This function is provided for error reporting. It switches
           the processor to kernel mode and pushes registers R2 to
           R7, the updated PC, and PS onto the kernel stack. It then
           dispatches to the address in the bugcheck vector, which is
           stored in a control block.

           This function has the following format:

           void  __PAL_BUGCHK (unsigned long);

           __PAL_DRAINA

           This function stalls instruction issuing until all prior
           instructions are guaranteed to complete without incurring
           aborts.

           This function has the following format:

           void  __PAL_DRAINA (void);

           __PAL_GENTRAP

           This function is used for reporting run-time software
           conditions.

           This function has the following format:

           void  __PAL_GENTRAP (uint64 encoded_software_trap);

           encoded_software_trap
           The particular software condition that has occurred.

     B-6 Built-In Functions

 



                                                      Built-In Functions


              __PAL_HALT

              This function halts the processor when executed by a
              process running in kernel mode. This is a privileged
              function.

              This function has the following format:

              void  __PAL_HALT (void);

              Absolute Value ( __ABS)

              The __ABS built-in is functionally equivalent to its
              counterpart, abs, in the standard header file <stdlib.h>.

              Its format is also the same:

              #include <stdlib.h>
              int  __ABS (int x);

              This built-in function does, however, offer performance
              improvements because there is less call overhead
              associated with its use.

              If you include <stdlib.h>, the built-in function is
              automatically used for all occurrences of abs. To disable
              the built-in function, use #undef abs.

              Add Aligned Word Interlocked ( __ADAWI)

              The __ADAWI function adds its source operand to the
              destination. This function is interlocked against similar
              operations by other processors or devices in the system.

              This function has the following format:

              int  __ADAWI (short src, short *dest);

              src
              The value to be added to the destination.

              dest
              A pointer to the destination. The destination must be
              aligned on a word boundary. (You can achieve alignment
              using the _align storage-class modifier.)

              The __ADAWI function returns a simulated VAX processor
              status longword (PSL).

                                                  Built-In Functions B-7

 



     Built-In Functions


           Add Atomic Longword ( __ADD_ATOMIC_LONG)

           The __ADD_ATOMIC_LONG function adds the specified
           expression to the longword data segment pointed to by the
           address parameter within a load-locked/store-conditional
           code sequence.

           This function has the following format:

           int  __ADD_ATOMIC_LONG int fnc(volatile void *, int,
     ...);

           address
           The address of the data segment.

           expression
           An integer expression.

            . . .
           An optional retry count of type int. If specified, the
           retry count indicates the number of times the operation
           is attempted. If the operation cannot be performed
           successfully in the specified number of retries, a value
           of 0 is returned.

           A value of 1 is returned upon successful completion.

           Add Atomic Quadword ( __ADD_ATOMIC_QUAD)

           The __ADD_ATOMIC_QUAD function adds the specified
           expression to the quadword data segment pointed to by the
           address parameter within a load-locked/store-conditional
           code sequence.

           This function has the following format:

           int  __ADD_ATOMIC_QUAD (void *address, int expression,
     ...);

           address
           The address of the data segment.

           expression
           An integer expression.

     B-8 Built-In Functions

 



                                                      Built-In Functions


               . . .
              An optional retry count of type int. If specified, the
              retry count indicates the number of times the operation
              is attempted. If the operation cannot be performed
              successfully in the specified number of retries, a value
              of 0 is returned.

              A value of 1 is returned upon successful completion.

              AND Atomic Longword ( __AND_ATOMIC_LONG)

              The __AND_ATOMIC_LONG function performs a bit-wise or
              arithmetic AND of the specified expression with the
              longword data segment pointed to by the address parameter
              within a load-locked/store-conditional code sequence.

              This function has the following format:

              int  __AND_ATOMIC_LONG (void *address, int expression,
        ...);

              address
              The address of the data segment.

              expression
              An integer expression.

               . . .
              An optional retry count of type int. If specified, the
              retry count indicates the number of times the operation
              is attempted. If the operation cannot be performed
              successfully in the specified number of retries, a value
              of 0 is returned.

              A value of 1 is returned upon successful completion.

              AND Atomic Quadword ( __AND_ATOMIC_QUAD)

              The __AND_ATOMIC_QUAD function performs a bit-wise or
              arithmetic AND of the specified expression with the
              aligned quadword pointed to by the address parameter
              within a load-locked/store-conditional code sequence.

              This function has the following format:

              int  __AND_ATOMIC_QUAD (void *address, int expression,
        ...);

                                                  Built-In Functions B-9

 



     Built-In Functions


           address
           The address of the aligned quadword.

           expression
           An integer expression.

            . . .
           An optional retry count of type int. If specified, the
           retry count indicates the number of times the operation
           is attempted (which will be at least once, even if the
           count argument is 0). If the operation cannot be performed
           successfully in the specified number of retries, a value
           of 0 is returned.

           A value of 1 is returned upon successful completion.

           Atomic Add Longword (__ATOMIC_ADD_LONG)

           The __ATOMIC_ADD_LONG function adds the specified
           expression to the aligned longword pointed to by the
           address parameter within a load-locked/store-conditional
           code sequence and returns the value of the longword before
           the addition was performed.

           This function has one of the following formats:

           int  __ATOMIC_ADD_LONG (volatile void *address, int
     expression);

           int  __ATOMIC_ADD_LONG_RETRY (volatile void *address, int
           expression, int retry, int *status);

           address
           The longword-aligned address of the data segment.

           expression
           An integer expression.

           retry
           A retry count of type int that indicates the number
           of times the operation is attempted (which is at least
           once, even if the retry argument is 0). If the operation
           cannot be performed successfully in the specified number
           of retries, the function returns without updating the
           longword.

     B-10 Built-In Functions

 



                                                      Built-In Functions


              status
              A pointer to an integer that is set to 0 if the operation
              did not succeed within the specified number of retries,
              and set to 1 if the operation succeeded.

              Atomic Add Quadword (__ATOMIC_ADD_QUAD)

              The __ATOMIC_ADD_QUAD function adds the specified
              expression to the aligned quadword pointed to by the
              address parameter within a load-locked/store-conditional
              code sequence and returns the value of the quadword before
              the addition was performed.

              This function has one of the following formats:

              int  __ATOMIC_ADD_QUAD (volatile void *address, int
        expression);

              int  __ATOMIC_ADD_QUAD_RETRY (volatile void *address, int
              expression, int retry, int *status);

              address
              The quadword-aligned address of the data segment.

              expression
              An integer expression.

              retry
              A retry count of type int that indicates the number
              of times the operation is attempted (which is at least
              once, even if the retry argument is 0). If the operation
              cannot be performed successfully in the specified number
              of retries, the function returns without updating the
              quadword.

              status
              A pointer to an integer that is set to 0 if the operation
              did not succeed within the specified number of retries,
              and set to 1 if the operation succeeded.






                                                 Built-In Functions B-11

 



     Built-In Functions


           Atomic AND Longword (__ATOMIC_AND_LONG)

           The __ATOMIC_AND_LONG function performs a bit-wise or
           arithmetic AND of the specified expression with the
           aligned longword pointed to by the address parameter
           within a load-locked/store-conditional code sequence and
           returns the value of the longword before the operation was
           performed.

           This function has one of the following formats:

           int  __ATOMIC_AND_LONG (volatile void *address, int
     expression);

           int  __ATOMIC_AND_LONG_RETRY (volatile void *address, int
           expression, int retry, int *status);

           address
           The longword-aligned address of the data segment.

           expression
           An integer expression.

           retry
           A retry count of type int that indicates the number
           of times the operation is attempted (which is at least
           once, even if the retry argument is 0). If the operation
           cannot be performed successfully in the specified number
           of retries, the function returns without updating the
           longword.

           status
           A pointer to an integer that is set to 0 if the operation
           did not succeed within the specified number of retries,
           and set to 1 if the operation succeeded.

           Atomic AND Quadword (__ATOMIC_AND_QUAD)

           The __ATOMIC_AND_QUAD function performs a bit-wise or
           arithmetic AND of the specified expression with the
           aligned quadword pointed to by the address parameter
           within a load-locked/store-conditional code sequence and
           returns the value of the quadword before the operation was
           performed.

     B-12 Built-In Functions

 



                                                      Built-In Functions


              This function has one of the following formats:

              int  __ATOMIC_AND_QUAD (volatile void *address, int
        expression);

              int  __ATOMIC_AND_QUAD_RETRY (volatile void *address, int
              expression, int retry, int *status);

              address
              The quadword-aligned address of the data segment.

              expression
              An integer expression.

              retry
              A retry count of type int that indicates the number
              of times the operation is attempted (which is at least
              once, even if the retry argument is 0). If the operation
              cannot be performed successfully in the specified number
              of retries, the function returns without updating the
              quadword.

              status
              A pointer to an integer that is set to 0 if the operation
              did not succeed within the specified number of retries,
              and set to 1 if the operation succeeded.

              Atomic OR Longword (__ATOMIC_OR_LONG)

              The __ATOMIC_OR_LONG function performs a bit-wise or
              arithmetic OR of the specified expression with the
              aligned longword pointed to by the address parameter
              within a load-locked/store-conditional code sequence and
              returns the value of the longword before the operation was
              performed.

              This function has one of the following formats:

              int  __ATOMIC_OR_LONG (volatile void *address, int
        expression);

              int  __ATOMIC_OR_LONG_RETRY (volatile void *address, int
              expression, int retry, int *status);


                                                 Built-In Functions B-13

 



     Built-In Functions


           address
           The longword-aligned address of the data segment.

           expression
           An integer expression.

           retry
           A retry count of type int that indicates the number
           of times the operation is attempted (which is at least
           once, even if the retry argument is 0). If the operation
           cannot be performed successfully in the specified number
           of retries, the function returns without updating the
           longword.

           status
           A pointer to an integer that is set to 0 if the operation
           did not succeed within the specified number of retries,
           and set to 1 if the operation succeeded.

           Atomic OR Quadword (__ATOMIC_OR_QUAD)

           The __ATOMIC_OR_QUAD function performs a bit-wise or
           arithmetic OR of the specified expression with the
           aligned quadword pointed to by the address parameter
           within a load-locked/store-conditional code sequence and
           returns the value of the quadword before the operation was
           performed.

           This function has one of the following formats:

           int  __ATOMIC_OR_QUAD (volatile void *address, int
     expression);

           int  __ATOMIC_OR_QUAD_RETRY (volatile void *address, int
           expression, int retry, int *status);

           address
           The quadword-aligned address of the data segment.

           expression
           An integer expression.

           retry
           A retry count of type int that indicates the number
           of times the operation is attempted (which is at least
           once, even if the retry argument is 0). If the operation

     B-14 Built-In Functions

 



                                                      Built-In Functions


              cannot be performed successfully in the specified number
              of retries, the function returns without updating the
              quadword.

              status
              A pointer to an integer that is set to 0 if the operation
              did not succeed within the specified number of retries,
              and set to 1 if the operation succeeded.

              Atomic Increment Longword (__ATOMIC_INCREMENT_LONG)

              The __ATOMIC_INCREMENT_LONG function increments by 1
              the aligned longword pointed to by the address parameter
              within a load-locked/store-conditional code sequence and
              returns the value of the longword before the operation was
              performed.

              This function has the following format:

              int  __ATOMIC_INCREMENT_LONG (volatile void *address);

              address
              The longword-aligned address of the data segment.

              Atomic Increment Quadword (__ATOMIC_INCREMENT_QUAD)

              The __ATOMIC_INCREMENT_QUAD function increments by 1
              the aligned quadword pointed to by the address parameter
              within a load-locked/store-conditional code sequence and
              returns the value of the quadword before the operation was
              performed.

              This function has the following format:

              int  __ATOMIC_INCREMENT_QUAD (volatile void *address);

              address
              The quadword-aligned address of the data segment.

              Atomic Decrement Longword (__ATOMIC_DECREMENT_LONG)

              The __ATOMIC_DECREMENT_LONG function decrements by 1
              the aligned longword pointed to by the address parameter
              within a load-locked/store-conditional code sequence and
              returns the value of the longword before the operation was
              performed.

              This function has the following format:

              int  __ATOMIC_DECREMENT_LONG (volatile void *address);

                                                 Built-In Functions B-15

 



     Built-In Functions


           address
           The longword-aligned address of the data segment.

           Atomic Decrement Quadword (__ATOMIC_DECREMENT_QUAD)

           The __ATOMIC_DECREMENT_QUAD function decrements by 1
           the aligned quadword pointed to by the address parameter
           within a load-locked/store-conditional code sequence and
           returns the value of the quadword before the operation was
           performed.

           This function has the following format:

           int  __ATOMIC_DECREMENT_QUAD (volatile void *address);

           address
           The quadword-aligned address of the data segment.

           Atomic Exchange Longword (__ATOMIC_EXCH_LONG)

           The __ATOMIC_EXCH_LONG function stores the value of the
           specified expression into the aligned longword pointed
           to by the address parameter within a load-locked/store-
           conditional code sequence and returns the value of the
           longword before the operation was performed.

           This function has one of the following formats:

           int  __ATOMIC_EXCH_LONG (volatile void *address, int
     expression);

           int  __ATOMIC_EXCH_LONG_RETRY (volatile void *address,
           int expression, int retry, int *status);

           address
           The longword-aligned address of the data segment.

           expression
           An integer expression.

           retry
           A retry count of type int that indicates the number
           of times the operation is attempted (which is at least
           once, even if the retry argument is 0). If the operation
           cannot be performed successfully in the specified number
           of retries, the function returns without updating the
           longword.

     B-16 Built-In Functions

 



                                                      Built-In Functions


              status
              A pointer to an integer that is set to 0 if the operation
              did not succeed within the specified number of retries,
              and set to 1 if the operation succeeded.

              Atomic Exchange Quadword (__ATOMIC_EXCH_QUAD)

              The __ATOMIC_EXCH_QUAD function stores the value of the
              specified expression into the aligned quadword pointed
              to by the address parameter within a load-locked/store-
              conditional code sequence and returns the value of the
              quadword before the operation was performed.

              This function has one of the following formats:

              int  __ATOMIC_EXCH_QUAD (volatile void *address, int
        expression);

              int  __ATOMIC_EXCH_QUAD_RETRY (volatile void *address,
              int expression, int retry, int *status);

              address
              The quadword-aligned address of the data segment.

              expression
              An integer expression.

              retry
              A retry count of type int that indicates the number
              of times the operation is attempted (which is at least
              once, even if the retry argument is 0). If the operation
              cannot be performed successfully in the specified number
              of retries, the function returns without updating the
              quadword.

              status
              A pointer to an integer that is set to 0 if the operation
              did not succeed within the specified number of retries,
              and set to 1 if the operation succeeded.

              Allocate Bytes from Stack ( __ALLOCA)

              The __ALLOCA function allocates n bytes from the stack.

              This function has the following format:

              void  *__ALLOCA (unsigned int n);

                                                 Built-In Functions B-17

 



     Built-In Functions


           n
           The number of bytes to be allocated.

           A pointer to the allocated memory is returned.

           Single-Precision, Floating-Point Arithmetic Built-in
           Functions

           The following built-in functions provide single-precision,
           floating-point chopped arithmetic:

           __ADDF_   __ADDS_   __SUBF_   __SUBS_C
           C         C         C

           __MULF_   __MULS_   __DIVF_   __DIVS_C
           C         C         C

           They have the following format:

           float  __op{F,S}_C (float operand1, float operand2);

           Where op is one of ADD, SUB, MUL, DIV, and {F,S}
           represents VAX or IEEE floating-point arithmetic.

           The result of the arithmetic operation is returned.

           Double-Precision, Floating-Point Arithmetic Built-in
           Functions

           The following built-in functions provide double-precision,
           floating-point chopped arithmetic:

           __ADDG_   __ADDT_   __SUBG_   __SUBT_C
           C         C         C

           __MULG_   __MULT_   __DIVG_   __DIVT_C
           C         C         C

           They have the following format:

           double  __op{G,T}_C (double operand1, double operand2);

           Where op is one of ADD, SUB, MUL, DIV, and {G,T}
           represents VAX or IEEE floating-point arithmetic.

           The result of the arithmetic operation is returned.

     B-18 Built-In Functions

 



                                                      Built-In Functions


              Copy Sign Built-in Functions

              Built-in functions are provided to copy selected portions
              of single- and double-precision, floating-point numbers.

              These built-in functions have the following format:

              float   __CPYSF (float operand1, float operand2);
              double  __CPYS (double operand1, double operand2);

              float   __CPYSNF (float operand1, float operand2);
              double  __CPYSN (double operand1, double operand2);

              float   __CPYSEF (float operand1, float operand2);
              double  __CPYSE (double operand1, double operand2);

              The copy sign built-in functions (__CPYSF and __CPYS)
              fetch the sign bit in operand1, concatenate it with the
              exponent and fraction bits from operand2, and return the
              result.

              The copy sign negate built-in functions (__CPYSNF and
              __CPYSN) fetch the sign bit in operand1, complement it,
              concatenate it with the exponent and fraction bits from
              operand2, and return the result.

              The copy sign exponent built-in functions (__CPYSEF and
              __CPYSE) fetch the sign and exponent bits from operand1,
              concatenate them with the fraction bits from operand2, and
              return the result.

              Compare Store Longword ( __CMP_STORE_LONG)

              The __CMP_STORE_LONG function has the following format:

              int  __CMP_STORE_LONG (void *source, int old_value, int
        new_value, void *dest);

              This function compares the value pointed to by source with
              the longword old_value. If they are equal, the longword
              new_value is stored into the value pointed to by dest.

              The function returns 0 if the two values are unequal, and
              returns 1 if the two values are equal.

                                                 Built-In Functions B-19

 



     Built-In Functions


           Compare Store Quadword ( __CMP_STORE_QUAD)

           The __CMP_STORE_QUAD function has the following format:

           int  __CMP_STORE_QUAD (void *source, int64 old_value,
     int64 new_value, void *dest);

           This function compares the value pointed to by source with
           the quadword old_value. If they are equal, the quadword
           new_value is stored into the value pointed to by dest.

           The function returns 0 if the two values are unequal, and
           returns 1 if the two values are equal.

           Cosine ( __COS)

           The __COS built-in function is functionally equivalent
           to its counterpart, cos, in the standard header file
           <math.h>.

           Its format is also the same:

           #include <math.h>
           double  __COS (double x);

           x
           A radian value.

           This built-in function does, however, offer performance
           improvements because there is less call overhead
           associated with its use.

           If you include <math.h>, the built-in function is
           automatically used for all occurrences of cos. To disable
           the built-in function, use #undef cos.

           Convert G_Floating to F_Floating Chopped ( __CVTGF_C)

           The __CVTGF_C function converts a double-precision, VAX
           G_floating-point number to a single-precision, VAX F_
           floating-point number. This conversion chops to single-
           precision; then the 8-bit exponent range is checked for
           overflow or underflow.

           This function has the following format:

           float  __CVTGF_C (double operand);

     B-20 Built-In Functions

 



                                                      Built-In Functions


              operand
              A double-precision, VAX floating-point number.

              Convert G-Floating to Quadword ( __CVTGQ)

              The __CVTGQ function rounds a double-precision, VAX
              floating-point number to a 64-bit integer value and
              returns the result.

              This function has the following format:

              int64  __CVTGQ (double operand);

              operand
              A double-precision, VAX floating-point number.

              Convert IEEE T_Floating to IEEE S_Floating Chopped
              ( __CVTTS_C)

              The __CVTTS_C function converts a double-precision, IEEE
              T_floating-point number to a single-precision, IEEE S_
              floating-point number. This conversion chops to single-
              precision; then the 8-bit exponent range is checked for
              overflow or underflow.

              This function has the following format:

              float  __CVTTS_C (double operand);

              operand
              A double-precision, IEEE floating-point number.

              Convert IEEE T-Floating to Quadword ( __CVTTQ)

              The __CVTTQ function rounds a double-precision, IEEE-
              floating-point number to a 64-bit integer value and
              returns the result.

              This function has the following format:

              int64  __CVTTQ (double operand);

              operand
              A double-precision, IEEE T-floating-point number.

                                                 Built-In Functions B-21

 



     Built-In Functions


           Floating-Point Absolute Value ( __FABS)

           The __FABS built-in function is functionally equivalent
           to its counterpart, fabs, in the standard header file
           <math.h>.

           Its format is also the same:

           #include <math.h>
           double  __FABS (double x);

           x
           A floating-point number.

           This built-in function does, however, offer performance
           improvements because there is no call overhead associated
           with its use.

           If you include <math.h>, the built-in function is
           automatically used for all occurrences of fab. To disable
           the built-in function, use #undef fab.

           Longword Absolute Value ( __LABS)

           The __LABS built-in function is functionally equivalent
           to its counterpart, labs, in the standard header file
           <stdlib.h>.

           Its format is also the same:

           #include <stdlib.h>
           long int  __LABS (long int x);

           x
           An integer.

           This built-in function does, however, offer performance
           improvements because there is less call overhead
           associated with its use.

           If you include <stdlib.h>, the built-in function is
           automatically used for all occurrences of labs. To disable
           the built-in function, use #undef labs.


     B-22 Built-In Functions

 



                                                      Built-In Functions


              Memory Barrier ( __MB)

              The __MB function directs the compiler to generate a
              memory barrier instruction.

              This function has the following format:

              void  __MB (void);

              Memory Copy and Set Functions ( __MEMCPY, __MEMMOVE,
              __MEMSET)

              The __MEMCPY, __MEMMOVE, and __MEMSET  built-in functions
              are functionally equivalent to their counterparts in the
              standard header file <string.h>.

              Their format is also the same:

              #include <stdlib.h>
              void  *__MEMCPY (void *s1, const void *s2, size_t size);
              void  *__MEMMOVE (void *s1, const void *s2, size_t size);
              void  *__MEMSET (void *s, int value, size_t size);

              These built-in functions do, however, offer performance
              improvements because there is less call overhead
              associated with their use.

              If you include <string.h>, the built-in functions are
              automatically used for all occurrences of memcpy, memmove,
              and memset. To disable the built-in functions, use #undef
              memcpy, #undef memmove, and #undef memset.

              Read Process Cycle Counter ( __RPCC)

              The __RPCC function reads the current process cycle
              counter.

              This function has the following format:

              int64  __RPCC (void);

              Sine ( __SIN)

        The __SIN built-in function is functionally equivalent to its
        counterpart in the standard header file <math.h>.
              Its format is also the same:

              #include <stdlib.h>
              double  __SIN (double x);

                                                 Built-In Functions B-23

 



     Built-In Functions


           x
           A radian value.

           This built-in function does, however, offer performance
           improvements because there is less call overhead
           associated with its use.

           If you include <math.h>, the built-in function is used
           automatically for all occurrences of sin. To disable the
           built-in function, use #undef sin.

           Test for Bit Clear then Clear Bit Interlocked
           ( __TESTBITCCI)

           The __TESTBITCCI function performs the following
           operations in interlocked fashion:

           o  Returns the complement of the specified bit before
              being cleared

           o  Clears the bit

           This function has the following format:

           int  __TESTBITCCI (void *address, int position, ...);

           address
           The base address of the field.

           position
           The position within the field of the bit that you want
           cleared.

            . . .
           An optional retry count of type int. If specified, the
           retry count indicates the number of times the operation
           is attempted. If the operation cannot be performed
           successfully in the specified number of retries, a value
           of 0 is returned.

           Test for Bit Set then Set Bit Interlocked ( __TESTBITSSI)

           The __TESTBITSSI function performs the following
           operations in interlocked fashion:

           o  Returns the value of the specified bit before being set

           o  Sets the bit

     B-24 Built-In Functions

 



                                                      Built-In Functions


              This function has the following format:

              int  __TESTBITSSI (void *address, int position, ...);

              address
              The base address of the field.

              position
              The position within the field of the bit that you want
              set.

               . . .
              An optional retry count of type int. If specified, the
              retry count indicates the number of times the operation
              is attempted. If the operation cannot be performed
              successfully in the specified number of retries, a value
              of 0 is returned.

              Trap Barrier Instruction ( __TRAPB)

              The __TRAPB function allows software to guarantee that,
              in a pipeline implementation, all previous arithmetic
              instructions will be completed without incurring any
              arithmetic traps before any instructions after the TRAPB
              instruction are issued.

              This function has the following format:

              void  __TRAPB (void);

              Unsigned Quadword Multiply High ( __UMULH)

              The __UMULH function performs a quadword multiply high
              instruction.

              This function has the following format:

              uint64  __UMULH (uint64 operand1, uint64 operand2);

              operand1
              A 64-bit unsigned integer.

              operand2
              A 64-bit unsigned integer.

              The two operands are multiplied as unsigned integers to
              produce a 128-bit result. The high order 64-bits are
              returned. Note that uint64 is a typedef for the Compaq
              Tru64 UNIX and Linux Alpha data type unsigned  __int64.

                                                 Built-In Functions B-25

 



     Built-In Functions


           Other Builtins

           int64 _popcnt(unsigned long);
           Returns the number of "1" bits in the argument (0 to 64).
           For example, _popcnt(12) returns 2.

           int64 _poppar(unsigned long);
           Returns "1" if the number of "1" bits in the argument is
           odd; otherwise, returns "0". otherwise. For example: _
           poppar(12) returns 0.

           int64 _leadz(unsigned long);
           Returns the number of leading zeroes (starting at the most
           significant bit position) in the argument. For example,
           _leadz(1) returns 63. Note that _leadz(0) returns 64.

           int64 _trailz(unsigned long);
           Returns the number of trailing zeroes (counting after the
           least significant set bit to the least significant bit
           position) in the argument: For example, _trailz(2) returns
           1. Note that _trailz(0) returns 64.
























     B-26 Built-In Functions

 









                                                                       C
        ________________________________________________________________

                                                   Third Degree Messages



              This appendix describes Third Degree messages generated
              by the C++ Class and Standard Libraries. None of the
              following messages contribute to memory corruption
              in programs or cause memory depletion in long running
              applications.

              1. Third degree 576 byte leak and 16 byte leak messages
                 from __init_cxx_exc

                 When you instrument a Compaq C++ program with Third
                 degree, the tool might generate 576 byte leak and 16
                 byte leak messages like the following from the Class
                 Library routine __init_cxx_exe:

                 576 bytes in 1 leak created at:
                     malloc                         libc.so
                     pc = 0x3ff81d35c04             libcxx.so
                     pc = 0x3ff81d35e20             libcxx.so
                     __init_cxx_exc                 libcxx.so

                 16 bytes in 1 leak (including 1 super leak) created at:
                     malloc                         libc.so
                     pc = 0x3ff81d35c04             libcxx.so
                     pc = 0x3ff81d35ca4             libcxx.so
                     pc = 0x3ff81d35dfc             libcxx.so
                     __init_cxx_exc                 libcxx.so

                 A program like the following would generate the
                 previous messages:

                 int main () {return 0;}

                 These two leaks are generated by the C++ exception
                 handling code. This storage is memory allocated to
                 process exception handling during program startup
                 and is deleted by the operating system when the
                 program exits. Third degree reports a leak because

                                               Third Degree Messages C-1

 



     Third Degree Messages


              the operating system, rather than C++ code, deletes the
              storage. The operating system deletes this storage for
              these reasons:

              o  The compiler does not slow down exit for all C++
                 programs.

              o  After the program terminates, the compiler verifies
                 that no additional C++ exceptions need handling.

           2. Third degree 8/24/48 byte leak messages from __init_
              cxx_exc

              When you instrument a Compaq C++ program with Third
              degree, the tool might generate four 8, four 24, and
              four 48 byte leak messages like the following from the
              Class Library routine __init_cxx_exe:

              48 bytes in 1 leak created at:
                  malloc                         libc.so
                  __cma_tis_mutex_create         libc.so
                  AllocateInternalMutex(void)    libcxx.so
                  Mutex::Mutex(void)             libcxx.so
                  Iostream_init::initialize(void) libcxx.so
                  Iostream_init::Iostream_init(void) libcxx.so
                  __init_cxxl_init142DB80C       libcxx.so

              24 bytes in 1 leak created at:
                  operator new(unsigned long)    libcxx.so
                  AllocateInternalMutex(void)    libcxx.so
                  Mutex::Mutex(void)             libcxx.so
                  Iostream_init::initialize(void) libcxx.so
                  Iostream_init::Iostream_init(void) libcxx.so
                  __init_cxxl_init142DB80C       libcxx.so

              8 bytes in 1 leak (including 1 super leak) created at:
                  operator new(unsigned long)    libcxx.so
                  Iostream_init::initialize(void) libcxx.so
                  Iostream_init::Iostream_init(void) libcxx.so
                  __init_cxxl_init142DB80C       libcxx.so

              A program like the following would generate the
              previous messages:

              int main () {return 0;}

     C-2 Third Degree Messages

 



                                                   Third Degree Messages


                 The messages originate from the creation of Class
                 Library Iostream mutexes for cin, cout, clog, and cerr,
                 which are created at program startup. The operating
                 system cleans up the memory rather than deleting it at
                 program exit from C++.

              3. Additional Third degree 48/24 byte leak messages from
                 __init_cxx_exc

                 When you instrument a Compaq C++ program with Third
                 degree, the tool might generate an additional 24 and 48
                 byte leak messages like the following from the Class
                 Library routine __init_cxx_exe:

                 48 bytes in 1 leak created at:
                     malloc                         libc.so
                     __cma_tis_mutex_create         libc.so
                     AllocateInternalMutex(void)    libcxx.so
                     Mutex::Mutex(void)             libcxx.so
                     Iostream_init::Iostream_init(void) libcxx.so
                     __init_cxxl_init142DB80C       libcxx.so

                 24 bytes in 1 leak created at:
                     operator new(unsigned long)    libcxx.so
                     AllocateInternalMutex(void)    libcxx.so
                     Mutex::Mutex(void)             libcxx.so
                     Iostream_init::Iostream_init(void) libcxx.so
                     __init_cxxl_init142DB80C       libcxx.so

                 A program like the following would generate the
                 previous messages:

                 int main () {return 0;}

                 The messages also come from a mutex used in Iostream
                 locking; they are created at program startup and are
                 cleaned up by the operating system rather than being
                 deleting at program exit by C++.

              4. Third degree 48 byte leak messages from __init_cxxl_
                 initxxxxxxxx

                 When you instrument a Compaq C++ program with Third
                 degree, the tool might generate an additional 48 byte
                 leak message like the following from the Class Library
                 routine __init_cxxl_initxxxxxxxx:

                                               Third Degree Messages C-3

 



     Third Degree Messages


              48 bytes in 1 leak (including 1 super leak) created at:
                  malloc                         libc.so
                  __cma_tis_mutex_create         libc.so
                  pc = 0x3ff81d3a46c             libcxx.so
                  __cma_tis_once                 libc.so
                  __cxx_test_and_set_atomic      libcxx.so
                  __init_cxxl_init142DB80C       libcxx.so

              A program like the following would generate the
              previous message:

              int main () {return 0;}

              This message comes from the mutex used to initialize
              the Class Library; the mutex is created at program
              startup and is deleted by the operating system rather
              than by C++ code at program exit.

           5. Third degree fon warning message from __init_cxx_exe

              When you instrument a C++ program with Third degree,
              the tool might generate a fon warning like the
              following from the C++ Class Library routine __init_
              cxx_exe:

              ------------------------------------------------ fon -- 0 --
              calling free(0)
                  free                           fon
                  pc = 0x120068090               fon
                  __init_cxx_exc                 fon

              --------------------------------------------------------------

              A program like the following would generate the
              previous message:

              int main () {return 0;}

              The message, freeing a NULL pointer, is only a warning.
              In this case, the library does in fact free a NULL
              pointer, but this is valid behavior. You can ignore the
              message.

           6. Third degree wis error from __vec_new_eh

     C-4 Third Degree Messages

 



                                                   Third Degree Messages


                 When you instrument a C++ program with Third degree,
                 the tool might generate a wis error like the following
                 from the C++ Standard Library routine __vec_new_eh:

                 ------------------------------------------------ wis -- 1 --
                 wis.cxx: 5: writing invalid stack at byte 64 of 64 in frame of
                 array_new_general
                 (void*, int, unsigned long, void*, void (*)(void*, int), void*
                 (*)(unsigned long),
                 void (*)(void*), int, int, unsigned int)
                 array_new_general(void*, int, unsigned long, void*, void (*)(void*,
                 int), void*
                 (*)(unsigned long), void (*)(void*), int, int, unsigned int)
                                                    wis
                     __vec_new_eh                   wis

                 --------------------------------------------------------------

                 A program like the following would generate the
                 previous message:

                 struct C {C() {};};
                 int main () {
                     C* pc = new C[5];
                     delete []pc;
                     return 0;
                     }

                 Programs using global array new can generate the
                 message when Third degree encounters a special
                 scheduling instruction. This false positive message
                 has been reported to Third degree.

              7. Third degree rin error message

                 The following error message is generated in programs
                 that use exception handling in the Class Library.
                 This false positive message has been reported to Third
                 degree.

                 rin.c: 7: reading invalid stack at byte 656 of 656 in frame of main
                     proc_at_0x12000e350            rin
                     __exc_virtual_unwind           rin
                     exc_virtual_unwind             rin
                     main                           rin, rin.c, line 7
                     __start                        rin

                                               Third Degree Messages C-5

 



     Third Degree Messages


           8. Third degree might report false positive uninitiated
              memory errors

              As of Atom 2.47, Third degree might report false
              positive uninitiated memory errors where variables
              of less than 32 bits are involved. Note that bool data
              types, which the Standard Library uses extensively,
              fall into this category.

              For example, when you instrument a C++ program with
              Third degree, the tool might generate a rus error with
              Atom version 2.47 in the STL map class. The error would
              be generated by a program like the following:

              #include <map>
              main() {
                  map <int, int> the_test_map;
                  the_test_map[1] = 1;
                  the_test_map[2] = 2;
              }

              The following is an example of a small, self-contained
              program (reduced from the above program) that generates
              the same error.

              struct tree
              {
                  bool       b;
                  void init () {;}
                  tree(const int i = 3, bool b = true) : b(b)
                  {
                    init();
                  }
              };
              void main() {
                   tree t;
              }








     C-6 Third Degree Messages

 













     ________________________________________________________________

                                                                Index


     A                                    Arguments
     ___________________________           mechanisms for passing,
     __ABS built-in function,                 2-25
        B-7                               asm intrinsic function,
     Access                                 B-1
       member, 4-9                        ASMs, B-1
     __ADAWI built-in function,           assign debugger command,
        B-7                                 9-14
     __ADDF_C built-in function,          Assignment
        B-18                               to the this pointer,  4-15
     __ADDG_C built-in function,          __ATOMIC_ADD_LONG built-in
        B-18                                function,  B-10
     Additive operators,  2-28            __ATOMIC_ADD_QUAD built-in
     __ADDS_C built-in function,            function,  B-11
        B-18                              __ATOMIC_AND_LONG built-in
     __ADDT_C built-in function,            function,  B-12
        B-18                              __ATOMIC_AND_QUAD built-in
     __ADD_ATOMIC_LONG built-in             function,  B-12
        function, B-8                     __ATOMIC_DECREMENT_LONG
     __ADD_ATOMIC_QUAD built-in             built-in function,  B-15
        function, B-8                     __ATOMIC_DECREMENT_QUAD
     __ALLOCA built-in function,            built-in function,  B-16
        B-17                              __ATOMIC_EXCH_LONG built-in
     __AND_ATOMIC_LONG built-in             function,  B-16
        function, B-9                     __ATOMIC_EXCH_QUAD built-in
     __AND_ATOMIC_QUAD built-in             function,  B-17
        function, B-9                     __ATOMIC_INCREMENT_LONG
     Application                            built-in function,  B-15
       deploying, 1-6                     __ATOMIC_INCREMENT_QUAD
     Applications                           built-in function,  B-15
       mixed-language, 8-4



                                                              Index-1

 






     __ATOMIC_OR_LONG built-in            Built-in functions (cont'd)
        function, B-13                     __ATOMIC_INCREMENT_LONG,
     __ATOMIC_OR_QUAD built-in                B-15
        function, B-14                     __ATOMIC_INCREMENT_QUAD,

                                              B-15
     B__________________________           __ATOMIC_OR_LONG,  B-13

     Base class initializers,              __ATOMIC_OR_QUAD,  B-14
        4-9                                __CMP_STORE_LONG,  B-19
     64-bit coding guidelines,             __CMP_STORE_QUAD,  B-20
        4-18                               Copy sign functions,  B-19
     bptr pointer,  9-40                   __COS,  B-20
     Breakpoints                           __CPYS,  B-19
       in C++ exception handlers           __CPYSE,  B-19
         ,  9-36                           __CPYSEF,  B-19
       in constructors and                 __CPYSF,  B-19
         destructors,  9-26                __CPYSN,  B-19
       in overloaded functions,            __CPYSNF,  B-19
         9-22                              __CVTGF_C,  B-20
       in templates, 9-31                  __CVTGQ,  B-21
     Buffer, output                        __CVTTQ,  B-21
       flushing, 4-15                      __CVTTS_C,  B-21
     Built-in functions,  B-1,             __DIVF_C,  B-18
                                           __DIVG_C,  B-18
        B-26                               __DIVS_C,  B-18
       __ABS,  B-7                         __DIVT_C,  B-18
       __ADAWI,  B-7                       Double-precision,
       __ADDF_C,  B-18                        floating-point
       __ADDG_C,  B-18                        arithmetic,  B-18
       __ADDS_C,  B-18                     __FABS,  B-22
       __ADDT_C,  B-18                     __LABS,  B-22
       __ADD_ATOMIC_LONG,  B-8             _leadz,  B-26
       __ADD_ATOMIC_QUAD,  B-8             __MB,  B-23
       __ALLOCA,  B-17                     __MEMCPY,  B-23
       __AND_ATOMIC_LONG,  B-9             __MEMMOVE,  B-23
       __AND_ATOMIC_QUAD,  B-9             __MEMSET,  B-23
       __ATOMIC_ADD_LONG,  B-10            __MULF_C,  B-18
       __ATOMIC_ADD_QUAD,  B-11            __MULG_C,  B-18
       __ATOMIC_AND_LONG,  B-12            __MULS_C,  B-18
       __ATOMIC_AND_QUAD,  B-12            __MULT_C,  B-18
       __ATOMIC_DECREMENT_LONG,            PALcodes,  B-5, B-7
         B-15                              __PAL_BPT,  B-6
       __ATOMIC_DECREMENT_QUAD,            __PAL_BUGCHK,  B-6
         B-16                              __PAL_DRAINA,  B-6
       __ATOMIC_EXCH_LONG,  B-16           __PAL_GENTRAP,  B-6
       __ATOMIC_EXCH_QUAD,  B-17           __PAL_HALT,  B-7

     Index-2

 






        Built-in functions (cont'd)         __CMP_STORE_LONG  built-in
         _popcnt,  B-26                        function, B-19
         _poppar,  B-26                     __CMP_STORE_QUAD  built-in
         __RPCC,  B-23                         function, B-20
         __SIN  built-in function,          Coding recommendations,
            B-23                               8-3
         Single-precision,                  Common instantiation
            floating-point                     library
            arithmetic,  B-18                 creating,  5-17
         __SUBF_C,  B-18                    __COMPAQ_CXX_VER__
         __SUBG_C,  B-18                       predefined macro, 2-22
         __SUBS_C,  B-18                    Compatibility,  3-13
         __SUBT_C,  B-18                    Compatibility macros,  2-21
         __TESTBITCCI,  B-24                Compiler,  1-1
         __TESTBITSSI,  B-24                  cxx command,  1-1
         _trailz,  B-26                          -nocleanup option,  8-3
         __TRAPB,  B-25                          -std ansi option,  4-1
         __UMULH,  B-25                          -std arm option,  4-1
                                                 -std cfront option,
        C__________________________                 4-3
        C++ predefined function                  -std gnu option,  4-3
         terminate,  9-37                        -std ms option,  4-3
         unexpected,  9-37                       -std strict_ansi
        call debugger command,                      option, 4-3
          9-27                                   -std strict_ansi_
        cfront                                      errors option, 4-4
         porting to Compaq C++                mixed pointer size
            from,  4-1 to 4-17                   options, 3-9
        Class                                 template
         friend declarations,  4-9               advanced program
         function definitions,                      development, 5-15
            4-10                                 automatic
         implementation details,                    instantiation, 5-2
            4-9                                  compatibility with
         initializer,  4-9                          earlier versions,
         library packages,  1-5                     5-24
         member access,  4-9                     creating common
         pointer conversions,  4-11                 instantiation
        class debugger command,                     library, 5-17
          9-5                                    creating libraries,
        Class Library, 1-4                          5-16
         Third Degree Messages,                  dependency management,
            C-1                                     5-15


                                                                 Index-3

 






     Compiler                             __CPYSF built-in function,
       template (cont'd)                    B-19
          implicit inclusion,             __CPYSN built-in function,
            5-4                             B-19
          linking Version                 __CPYSNF built-in function,
            5.n applications                B-19
            against Version 6.n           __CVTGF_C built-in function
            repositories,  5-26             ,  B-20
          linking with Version            __CVTGQ built-in function,
            5.n instantiations,             B-21
            5-25                          __CVTTQ built-in function,
          mixing automatic and              B-21
            manual instantiation          __CVTTS_C built-in function
            ,  5-15                         ,  B-21
          overview, 5-1                   cxx compiler command, 1-1
          repositories, 5-20              /cxx_repository directory,
       template instantiation               5-2
         options,  5-21                   /cxx_repository
     Constant                               instantiation file,  5-2
       in function returns, 4-11          <c_asm.h> header file, B-1

       pointer to, 4-12
     Constructors and                     D__________________________

        Destructors, setting              dasm intrinsic function,
        breakpoints in, 9-26                B-1
     Conversion                           Debugger, assignments
       explicit type, 2-27                  allowed by,  9-14
       floating-point number,             Debugger commands
         2-26, 2-27                        assign,  9-14
       integer, 2-26                       call,  9-27
       pointer, 4-11                       class,  9-5
     Copy sign built-in                    displaying class
        functions, B-19                       information,  9-7
     __COS built-in function,              print
        B-20                                  displaying base
     __CPYS built-in function,                   pointer information,
        B-19                                     9-40
     __CPYSE built-in function,            stop in,  9-19, 9-21, 9-26
        B-19                               whatis,  9-7, 9-17, 9-31,
     __CPYSEF built-in function,              9-38
        B-19                              Debugging, 1-5, 9-2 to
                                            9-46
                                           absolute and relative
                                              path names,  9-3

     Index-4

 






        Debugging (cont'd)                  Directive (cont'd)

         class and function scope,            #pragma environment,  2-3
            9-6                               #pragma ident,  2-5
         class and function                   #pragma instantiate,  2-2
            templates,  9-31                  #pragma message,  2-9
         displaying type signature            #pragma module,  2-10
            ,  9-7                            #pragma once,  2-11
         examining data members,              #pragma pack,  2-11
            9-5                               #pragma pointer_size,
         examining inlined member                2-13, 3-9
            functiona,  9-14                  #pragma required_pointer_
         exception handler support               size, 3-9
            ,  9-36                           #pragma required_vptr_
         member functions on stack               size, 2-15, 3-10
            trace,  9-15                      #pragma weak,  2-16
         mixed C and C++ programs,            #pragma [no]inline,  2-6
            9-4                               #pragma [no]member_
         resolving ambiguous                     alignment, 2-7
            references,  9-15                 #pragma [no]standard,
         resolving references to                 2-16
            objects,  9-12                  __DIVF_C  built-in function,
         setting breakpoints in                B-18
            member functions,  9-19         __DIVG_C  built-in function,
         setting class scope,  9-5             B-18
         setting language mode,             Division operator,  2-28
            9-4                             __DIVS_C  built-in function,
         type casting,  9-28                   B-18
         type transfer,  9-30               __DIVT_C  built-in function,
         verbose mode,  9-38                   B-18
        __DECCXX_VER predefined             Double-precision, floating-
          macro,  2-22                         point arithmetic built-
        Declarations                           in functions, B-18

         friend,  4-9
        define_template pragma,             E__________________________

          2-2                               Enumerated types
        delete operator                       incrementing,  4-17
         size-of-array argument             environment pragma,  2-3
            to,  4-15                       Equality operators,  2-29
        demangle command, 1-3               Error message
        Dialect macro, 2-21                   missing parenthesis,  4-16
        Directive
         #pragma define_template,
            2-2

                                                                 Index-5

 






     Exception handling,  2-33,
        8-1                               G__________________________
       catching signals and C             goto statement, 4-13
         excpetions,  8-5                 Guiding declarations, 2-38
       finding information, 8-4
       structure for, 8-1 to 8-2          H__________________________
       threads, 8-6                       Header file
     Explicit type conversion,             protecting,  2-16
        2-27                              Header files
     Explicit type conversion,             <float.h>,  2-24
        language extension, 2-27           <limits.h>,  2-24
     Extended Truncated Address            modifying,  3-1 to 3-2
        Support Option (XTASO),            <stdio.h>,  4-18
        3-9                                using existing,  3-1
     Extensions                           header files and
       source file, 4-17                    inheritance,  2-35
     extern specifier,  3-1

     F                                    I__________________________
     ___________________________          Identifiers, 2-26
     __FABS built-in function,            ident pragma, 2-5
        B-22                              #ifdef preprocessor
     fasm intrinsic function,               directive,  4-14
        B-1                               Implementation extensions,
     Faults                                 2-25 to 2-26
       segmentation, 4-16                 Implementation features,
     File inclusion directive,              2-25 to 2-26
        #include, 2-34 to 2-35            #include directive, 2-34
     <float.h> header file,                 to 2-35
        2-24                              #include_next pragma, 2-35
     Floating-point arithmetic            Inheritance, 9-29
        built-in functions, B-18          inheritance and header
     Floating-point number                  files,  2-35
       converting to and from an          Initializers
         integer,  2-26                    using base class name
     Friend declarations,  4-9                with,  4-9
     Function                             Initializing references,
       constant in returns, 4-11            4-13
       definitions, 4-10                  In-line assembly code
     Function returns                       (ASMs),  B-1
       constants in, 4-11                 inline pragma, 2-6
     Functions,  4-10                     instantiate pragma, 2-2



     Index-6

 






        Instantiation                       <limits.h> header file,
         automatic                             2-24
            linking with,  5-6              Linkage
         directives,  5-9                     between C and C++,  3-1
            #pragma define_                   specification,  2-32, 3-4
               template,  5-9               Linkage specifications,
            #pragma do_not_                    3-4
               instantiate,  5-13           Link compatibility,  3-15
            #pragma instantiate,            Linker,  1-2
               5-13                         Local Virtual function
         manual,  5-8                          table
         mixed automatic and                  using to implement
            manual,  5-15                        polymorphism, 2-39
         template,  5-1 to 5-26
        Instantiation file, 5-2 to          M__________________________
          5-6                               Macro names
        Integer                               predefined,  2-18
         converting to and from a           __MB  built-in function,
            floating-point number,             B-23
            2-26                            Member access,  4-9
        Integral conversions, 2-26          __MEMCPY  built-in function,
        Intrinsic functions                    B-23
         ASMs,  B-1                         __MEMMOVE  built-in function
        intrinsic pragma, 2-6                  , B-23

        K                                   Memory management,  4-15
        ___________________________         __MEMSET  built-in function,
        Keywords                               B-23
         conflict resolution,  3-2          Message control option,
                                               2-41, 2-42
        L__________________________         Missing parenthesis error
        __LABS built-in function,              message, 4-16
          B-22                              Mixed-Language applications
        Ladebug debugger, 9-2 to               , 8-4
          9-46                              Mixed-language programs,
        Language mode, setting for             debugging, 9-4
          debugging,  9-4                   __MULF_C  built-in function,
        $lang variable, 9-4                    B-18
        ld linker command, 1-2              __MULG_C  built-in function,
        Limits                                 B-18
         numerical,  2-24                   __MULS_C  built-in function,
         translation,  2-24                    B-18



                                                                 Index-7

 






     Multiplicative operators,            __PAL_BPT built-in function
        2-28                                ,  B-6
     __MULT_C built-in function,          __PAL_BUGCHK built-in
        B-18                                function,  B-6
                                          __PAL_DRAINA built-in
     N__________________________            function,  B-6
     Name demangling,  1-2                __PAL_GENTRAP built-in
     Nested enums,  2-36                    function,  B-6
     noinline pragma,  2-6                __PAL_HALT built-in
     Non-C++ code, access to,               function,  B-7

        3-4                               PCH file

     [no]standard pragma,  2-16            See Precompiled header
     Numerical limits,  2-24                  file

                                          Pointer, 4-11
     O__________________________           bound to member function,
     Object                                   4-11
       temporary, 2-32                     conversions,  4-11
       volatile, 4-14                      mixing 32-bit and 64-bit
     Object construction                      sizes,  3-9
       implementing polymorphism           to constants,  4-12
         ,  2-39                          pointer_size pragma, 2-13,
     once pragma,  2-11                     3-9
     OpenMP,  1-9                         Polymorphism
     Operators                             implementing,  2-39
       additive, 2-28                     Porting
       delete, 4-15                        from cfront to Compaq
       division, 2-28                         C++,  4-1 to 4-17
       equality, 2-29                     Pragma
       multiplicative, 2-28                See also Preprocessor
       remainder, 2-28                        directive
       shift, 2-28                         define_template,  2-2
       sizeof, 2-27                        environment,  2-3
     Output buffer                         ident,  2-5
       flushing, 4-15                      inline,  2-6
     $overloadmenu variable,               instantiate,  2-2
        9-15                               [no]standard,  2-16
                                           once,  2-11
     P__________________________           pack,  2-11
     pack pragma,  2-11                    pointer_size,  2-13, 3-9
     PALcode built-in functions,           #pragma message,  2-9
        B-5, B-7                           #pragma module,  2-10
                                           #pragma [no]member_
                                              alignment,  2-7

     Index-8

 






        Pragma (cont'd)                     Preprocessor directive
         required_pointer_size,               #ifdef,  4-14
            3-9                               #pragma,  2-1 to 2-16
         required_vptr_size,  2-15,           #pragma intrinsic,  2-6
            3-10                            Preprocessor directives
         weak,  2-16                          #pragma intrinsic,  B-1
        pragma #include_next, 2-35          print debugger command
        #pragma ident preprocessor            displaying base pointer
          directive,  2-5                        information, 9-40
        #pragma intrinsic                     displaying class
          preprocessor directive,                information, 9-7
          B-1                               Printing base pointer
        #pragma intrinsic                      information, 9-40
          preprocessor directive,           Product support,  xvi
          2-6                               Programs
        #pragma once preprocessor             compiling,  1-1
          directive,  2-11                    linking,  1-2
        #pragma pack preprocessor           Protecting header files,
          directive,  2-11                     2-16

        Pragmas                             R
         intrinsic,  2-6                    ___________________________
        #pragma [no]inline                  Reader's comments, sending,
          preprocessor directive,              xvi
          2-6                               References
        Precompiled header file,              initializing,  4-13
          6-1 to 6-9                        Remainder operator,  2-28
         automatic processing,  6-2         required_pointer_size
         controlling,  6-7                     pragma, 3-9
         manual processing,  6-6            required_vptr_size pragma,
         options,  6-8                         2-15, 3-10
         performance issues,  6-7           Return mechanisms,  2-25
        Predefined macro, __COMPAQ_         __RPCC  built-in function,
          CXX_VER__,  2-22                     B-23

        Predefined macro, __DECCXX_         RTTI
          VER,  2-22                          See Run-Time Type
        Predefined macro,                        Identification
          compatibility,  2-21              Run compatibility,  3-16
        Predefined macro, dialect,          Run-Time Type
          2-21                                 Identification (RTTI),
        Predefined macro names,                2-39
          2-18


                                                                 Index-9

 






                                          Standard Template Library
     S__________________________           building programs with,

     Segmentation faults,  4-16               7-11
     Shift operators,  2-28               Statement
     Signal                                goto,  4-13
       exception handling, 8-5             switch,  4-13
     __SIN built-in function,             Static object
        B-23                                initialization
     Single-precision, floating-           order of,  2-26
        point arithmetic built-           -std ansi mode, 4-1
        in functions, B-18                -std arm mode, 4-1
     Size-of-array argument               <stdio.h> header file,
       to delete operator, 4-15             4-18
     sizeof operator,  2-27               stop in debugger command,
     Source compatibility,  3-14            9-19, 9-21, 9-26
     Source file extensions,              -strict_ansi mode, 4-1
        4-17                              -strict_ansi_errors mode,
     Specification                          4-1
       linkage, 2-32, 3-4                 String Library
     Specifiers                            building programs with,
       extern, 3-1                            7-11
       type, 2-29, 2-31                   __SUBF_C built-in function,
       typedef, 4-12                        B-18
     Standard Library,  1-4               __SUBG_C built-in function,
       building programs with,              B-18
         7-11                             __SUBS_C built-in function,
       compatibility issues, 7-3            B-18
         to 7-11                          __SUBT_C built-in function,
          global array new and              B-18
            delete,  7-10                 switch statement, 4-13
          -[no]using_std
            compatibility switch          T__________________________
            ,  7-3                        Template instantiation,
          overriding                        5-1 to 5-26
            operator(new),  7-8           Templates
          pre-ANSI/ANSI                    debugging limitations,
            iostreams                         9-36
            compatibility,  7-4           Temporary objects, 2-32
          pre-ANSI and ANSI               terminate C++ predefined
            operator(new),  7-6             function,  9-37
       Third Degree Messages,
         C-1


     Index-10

 






        __TESTBITCCI built-in               __unaligned  type specifier,
          function,  B-24                      2-31
        __TESTBITSSI built-in               unexpected C++ predefined
          function,  B-24                      function, 9-37
        Third Degree
         C++ Class and Standard             V__________________________
            Library Messages,  C-1          Variable
        this pointer, 9-9, 9-15,              declared on for statement
          9-21, 9-42                             , 4-17
        this pointer                        $verbose variable,  9-38
         assignment to,  4-15               Virtual function table
         system default size,  3-11           local,  2-39
        Thread safety, 7-11                 Volatile object,  4-14
        Translation limits, 2-24            volatile type specifier,
        __TRAPB built-in function,             2-29
          B-25
        Type conversion                     W
         explicit,  2-27                    ___________________________
        typedef specifier, 4-12             weak pragma,  2-16
        Type specifier                      whatis debugger command,
         __unaligned,  2-31                    9-7, 9-17, 9-31, 9-38

         volatile,  2-29
                                            X__________________________

        U__________________________         XTASO

        __UMULH built-in function,            See Extended Truncated
          B-25                                   Address Support Option
















                                                                Index-11
