Borland_C++_Version_5_Users_Guide_1997 Borland C Version 5 Users Guide 1997
Borland_C++_Version_5_Users_Guide_1997 Borland_C++_Version_5_Users_Guide_1997
User Manual: Borland_C++_Version_5_Users_Guide_1997
Open the PDF directly: View PDF .
Page Count: 651
Download | |
Open PDF In Browser | View PDF |
VERSION 5 c++ User's Guide Borland C++ ® Borland International, Inc., 100 Borland Way P.O. Box 660001, Scotts Valley, CA 95067-0001 Refer to the file REDIST.TXT in the \BCS\DOC directory for a list of files that you can redistribute in accordance with the No-Nonsense License Statement. Borland may have patents and/or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. \ COPYRIGHT © 1996 Borland International. All rights reserved. All Borland products are trademarks or registered trademarks of Borland International, Inc. Other brand and product names are trademarks or registered trademarks of their respective holders. Printed in the U.S.A. lEOR0196 WBC1350WW21770 97989900-9 8 7 6 5 4 D2 ISBN 0-672-30922-X Contents Introduction 1 How this book is organized. . . . . . . . . . . . 1 Typefaces and icons used in this book . . . . . 1 Part I The integrated development 3 Chapter 1 Getting started 5 Starting the Borland C++ IDE. . . . . . . . . . . 5 The IDE menu system . . . . . . . . . . . . . . 6 The IDE SpeedBar. . . . . . . . . . . . . . . . . 7 Using SpeedMenus in the IDE . . . . . . . . . . 7 Using the Edit window . . . . . . . . . . . . . . 7 Creating a new file.. . . . . . . . . . . . . . . . 8 Working with simple projects . . . . . . . . . . 8 Creating a DOS program using EasyWin. . . 9 Creating a Windows program . . . . . . . . 10 Modifying the program target . . . . . . . . 11 Single file programs. .-. . . . . . . . . . . . . 12 Customizing the IDE. . . . . . . . . . . . . . . .12 Configuring the IDE editor . . . . . . . . . . 13 Syntax highlighting. . . . . . . . . . . . . . . 14 Customizing the SpeedBars. . . . . . . . . . 14 Setting IDE preferences . . . . . . . . . . . . 16 Saving your IDE settings. . . . . . . . . . . . 16 Running other programs from the IDE . . . . .16 Using online Help in Borland C++ . . . . . . . . 16 Online Help Organization. . . . . . . . . . . 17 Getting Help in Borland C++ . . . . . . . . . 17· Getting context-sensitive Help . . . . . . . . 18 Accessing and using contents screens. . . . 18 Using the index . . . . . . . . . . . . . . . . . 18 Searching for keywords . . . . . . . . . . . . 18 Help SpeedMenus . . . . . . . . . . . . . . . 19 Using Windows Help . . . . . . . . . . . . . . .19 Chapter 2 Managing projects 21 What is project management? . . . . . . . . . .21 Using the Project Manager . . . . . . . . . . . .22 Project Manager reference. . . . . . . . . . '. 23 Creating a project. . . . . . . . . . . . . . . . .24 Setting target options with the New Target dialog box . . . . . . . . . . . . . . . 24 . Specifying the source node types . . . . . . 27 Opening existing projects. . . . . . . . . . . 27 Adding source nodes to your project . . . . .27 Deleting source nodes. . . . . . . . . . . . . 28 Adding files without relative path information . . . . . . . . . . . . . . . . . . .28 Editing source node attributes . . . . . . . . .28 Adding target nodes to your project. . . . . .29 Deleting target nodes.. . . . . . . . . . . . . 29 Editing target attributes using TargetExpert. . . . . . . . . . . . . . . . . . .30 Moving nodes within a project. . . . . . . . .30 Copying nodes in a project . . . . . . . . . . .30 Converting project files into makefiles . . . .31 Customizing the Project window . . . . . . .31 Grouping sets of files with Source Pools. . . . 32 Creating a Source Pool. . . . . . . . . . . . . .33 Translators, viewers, and tools .. . . . . . . . 33 Adding translators, viewers, and tools to the IDE . . . . . . . . . . . . . . . . . 34 Chapter 3 Specifying project options and compiling 37 Setting project options . . . . . . . . . . . . . . 37 Using Style Sheets . . . . . . . . . . . . . . . . 38 Predefined Style Sheets . . . . . . . . . . . . 38 The default project options . . . . . . . . . . 38 Managing Style Sheets. . . . . . . . . . . . . 38 Attaching Style Sheets to a node. . . . . . . 39 Sharing Style Sheets between projects . . . 40 Project Description Language files. . . . . . 40 Setting local overrides. . . . . . . . . . . . . 41 Viewing project options. . . . . . . . . . . . .42 Compiling projects . . . . . . . . . . . . . . . . .43 Compiling part of a project. . . . . . . . . . 44 Fixing compile-time errors. . . . . . . . . . . . 44 Viewing errors . . . . . . . . . . . . . . . . . .45 Fixing errors. . . . . . . . . . . . . . . . . . . .45 Project options reference . . . . . . . . . . . . . 45 16-bit compiler options. . . . . . . . . . . . . . 45 Uninitialized data (BSS class) . . . . . . . 56 Uninitialized data (BSS group) . . . . . . 56 Uninitialized data (BSS segment) . . . . . 56 Segment names far data. " . . . . . . . . . .56 Far data . . . . . . . . . . . . . . . . . . . . . 56 Far data class . . ; . . . . . . . . . . . . . 56 Far data group. . . . . . . . . . . . . . . . 56 Far data segment . . . . . . . . . . . . . . 56 Far virtual tables . . . . . . . . . . . . . . . . 57 Virtual table class. . . . . . . . . . . . . . 57 Virtual table segment. . . . . . . . . . . . 57 32-bit compiler options . . . . . . . . . . . . . . 57 Use Borland optimizing compiler . . . .57 Use Intel optimizing compiler . . . . . . . . . 57 32-bit compiler options . . . . . . . . . . . . .57 Calling conventions . . . . . . . . . . . . . . 58 C . . . . . . . . . . . . . . . . . . . . . . . . 58 Pascal . . . . . . . . . . . . . . . . . . . . . 58 Register. . . . . . . . . . . . . . . . . . . . 58 Standard Call (32-bit compiler onlyf .. 58 Processor. . . . . . . . . . . . ... . . . . . . . 59 32-bit instruction set . . . . . . . . . . . . 59 Build Attributes options . . . . . . . . . . . . . 60 Always build . . . . . . .60 Build when out of date. .60 Can't build. . . . . . . .60 Exclude from parent. . .60 Never build . . . . . . . . . . . . . . . . . . . .60 C++ options . . . . . . . . . . . . . . . . . . . . . 60 C++ compatibility . . . . . . . . . . . . . . . . 61 'deep'virtualbases . . . . . . . . . . . . . . . 61 Calling convention mangling compatibility . . . . . . . . . . . . . . . . . 61 Disable constructor displacements . . . . . 61 Do not treat 'char' as distinct type . . . . . . 61 Don't restrict scope of 'for'loop expression variables. . . . . . . . . . . . . 62 Pass class values via reference to temporary . . . . . . . . . . . . . . . . . . . 62 Push 'this' first for Pascal member functions. . . . . . . . . . . . . . . . . . . . 62 Treat 'far' classes as 'huge' . . . . . . . . . . 63 Virtual base pointers. . . . . . . . . . . . . . 63 Always near. . . . . . . . . . . . . . . . . 63 Same size as 'this' pointer . . . . . . . . . 63 Vtable pointer follows data members. . . . 64 Exception handling / RTTI. . . . . . . . . . .64 Enable exceptions . . . . . . . . . . . . . . . 64 Enable run-time type information. . . . . . 64 Enable compatible exceptions . . . . . . . 64 Enable destructor cleanup. . . . . . . . . 65 Enable exception location information . 65 Enable fast exception prologs. . . . . . . 65 Calling Conventions. . . . . . . . . . . . . . .45 C . . . . . . . . . . . . . . . . . . . . . . . . . . .46 Pascal . . . . . . . . . . . . . . . . . . . . . . .46 Register . . . . . . . . . . . . . . . . . . . . . .46 Entry/Exit code . . . . . . . . . . . . . . . . . . 46 Windows all functions exportable . . . . . . .46 Windows explicit functions exported. . . . .47 Windows smart callbacks, all functions exportable. . . . . . . . . . . . . . . . . . . .47 Windows smart callbacks, explicit functions exportable . . . . . . . . . . . . . . .48 Windows DLL, all functions exportable . . . . . . . . . . . . . . . . . . . .48 Windows DLL, explicit functions exported. . . . . . . . . . . . . . . . . . . . .48 Memory model. . . . . . . . . . . . . . . . . .48 Assume SS equals DS . . . . . . . . . . . . . .49 Always (DOS only) . . . . . . . . . . . . .49 Default for memory model. . . . . . . . .49 Never. . . . . . . . . . . . . . . . . . . . . . 49 . Automatic far data. . . . . . . . . . . . . . . .49 Far data threshold . . . . . . . . . . . . . . . .50 Far virtual tables . . . . . . . . . . . . . . . . .50 Fast huge pointers . . . . . . . . . . . . . . . .50 Model . . . . . . . . . . . . . . . . . . . . . . .51 Compact . . . . . . . . . . . . . . . . . . . . 51 Huge . . . . . . . . . . . . . . . . . . . . . . 51 Large . . . . . . . . . . . . . . . . . . . . . . 51 Medium . . . . . . . . . . . . . . . . . . . . 51 Small. " . . . . . . . . . . . . . . . . . . . . 52 Tiny. . . . . . . . . . . . . . . . . . . . . . . 52 Put considlli ::;irlllg,::; III cuue ::;eg,UlellL::; . . . .J2 Processor. . . . . . . . . . . . . . . . . . . . . .52 16-bit instruction set. . . . . . . . . . . . . . .52 80186 . . . . . . . . . . . . . . . . . . . . . . 52 80286 . . . . . . . . . . . . . . . . . . . . . . 53 80386 . . . . . . . . . . . . . . . . . . . . . . 53 8086 . . . . . . . . . . . . . . . . . . . . . . . 53 i486 . . . . . . . . . . . . . . . . . . . . . . . 53 Data alignment. . . . . . . . . . . . . . . . . .53 Byte alignment . . . . . . . . . . . . . . . .53 Double word (4-byte) . . . . . . . . . . . . 53 Quad word (8-byte) . . . . . . . . . . . . . 54 Word alignment (2-byte) . . . . . . . . . . 54 Segment names code. . . . . . . . . . . . . . .54 Code . . . . . . . . . . . . . . . . . . . . . . . .54 Code class. . . . . . . . . . . . . . . . . . .54 Code group . . . . . . . . . . . . . . . . . . 54 Code segment . . . . . . . . . . . . . . . . . 54 Segment names data. . . . . . . . . . . . . . .55 Initialized Data . . . . . . . . . . . . . . . . . .55 Initialized data class . . . . . . . . . . . . .55 Initialized data group . . . . . . . . . . . . 55 Initialized data segment. . . . . . . . . . . 55 Uninitialized data . . . . . . . . . . . . . . . .55 ii General . . . . . . . . . . . . . . . . . . . . . . 65 Zero-length empty base classes . . . . . . . 65 Member pointers . . . . . . . . , . . . . . . . 66 Honor precision of member pointers . . . . 66 Member pointer representation . . . . . . . 66 Smallest for class . . . . . . . . . . . . . . 66 Support all cases . . . . . . . . . . . . . . 66 Support multiple inheritance . . . . . . . 66 Support single inheritance . . . . . . . . . 66 Templates . . . . . . . . . . . . . . . . . . . . 67 Templates instance generation . . . . . . . . 67 External. . . . . . . . . . . . . . . . . . . . 67 Global. . . . . . . . . . . . . . . . . . . . . 67 Smart . . . . . . . . . . . . . . . . . . . . . 67 Virtual Tables . . . . . . . . . . . . . . . . . . 68 Virtual tables linkage . . . . . . . . . . . . . 68 External. . . . . . . . . . . . . . . . . . . . 68 Local . . . . . . . . . . . . . . . . . . . . . 68 Public . . . . . . . . . . . . . . . . . . . . . 68 Smart . . . . . . . . . . . . . . . . . . . . . 68 Compiler options. . . . . . . . . . . . . . . . . .69 Defines . . . . . . . . . . . . . . . . . . . . . . . 69 Defining macros from the IDE . . . . . . . . 69 Defining macros on the command line . . . 69 Code generation. . . . . . . . . . . . . . . . . 69 Allocate enums as ints. . . . . . . . . . . . . 70 Duplicate strings merged . . . . . . . . . . . 70 fastthis . . . . . . . . . . . . . . . . . . . . . . 70 Register variables. . . . . . . . . . . . . . . . 71 Automatic . . . . . . . . . . . . . . . . . . 71 None . . . . . . . . . . . . . . . . . . . . . 71 Register keyword. . . . . . . . . . . . . . 71 Unsigned characters . . . . . . . . . . . . . . 72 Floating point . . . . . . . . . . . . . . . . . . 72 Correct Pentium FDN flaw. . . . . . . . . . 72 Fast floating point . . . . . . . . . . . . . . . 73 No floating point. . . . . . . . . . . . . . . . 73 Compiler output. . . . . . . . . . . . . . . . . 73 Autodependency information . . . . . . . . 73 Generate COMDEFs. . . . . . . . . . . . . . 74 Generate underscores . . . . . . . . . . . . . 74 Source . . . . . . . . . . . . . . . . . . . . . . . 74 Identifierlength . . . . . . . . . . . . . . . . . 74 Language compliance . . . . . . . . . . . . . 75 ANSI ... , . . . . . . . . . . . . . . . . . 75 Borland extensions . . . . . . . . . . . . . 75 Kernighan and Ritchie. . . . . . . . . . . 75 UNIX V'. . . . . . . . . . . . . . . . . . . . 75 MFC compatibility. . . . . . . . . . . . . . . 75 Nested comments . . . . . . . . . . . . . . . 76 Debugging . . . . . . . . . . . . . . . . . . . . 76 Browser reference information in OBJs . . . 76 Debug information in OBJs. . . . . . . . . . 77 Line numbers. . . . . . . . . . . . . . . . . . 77 Out-of-line inline functions. . . . . . . . . . 77 Standard stack frame . . . . . . . . . . . . . 78 Test Stack Overflow . . . . . . . . . . . . . . 78 Precompiled headers. . . . . . . . . . . . . . .78 Cache precompiled header. . . . . . . . . . 79 Precompiled header name . . . . . . . . . . 79 Precompiled headers . . . . . . . . . . . . . 79 Do not generate or use. . . . . . . . . . . 79 Generate and use . . . . . . . . . . . . . . 79 Use but do not generate . . . . . . . . . . 79 Stop precompiling after header file . . . . . 80 Directories options. . . . . . . . . . . . . . . . . 80 Source directories. . . . . . . . . . . . . . . . .80 Include . . . . . . . . . . . . . . . . . . . . . . 80 Library . . . . . . . . . . . . . . . . . . . . . . 80 Source . . . . . . . . . . . . . . . . . . . . . . 80 Specifying multiple directories . . . . . . . . 81 File search algorithms . . . . . . . . . . . . . .81 #include-file search algorithms . . . . . . . . 81 Library file search algorithms . . . . . . . . 81 Output Directories . . . . . . . . . . . . . . . .82 Intermediate. . . . . . . . . . . . . . . . . . . 82 Final . . . . . . . . . . . . . . . . . . . . . . . 82 Guidelines for entering directory names . . . . . . . . . . . . . . . . . . . . . 82 Librarian options. . . . . . . . . . . . . . . . . . 83 Case-sensitive library . . . . . . . 83 Create extended dictionary . . .83 Generate list file. . . . . . . . . . . 83 Library page size . . . . . . . . . .83 Purge comment records. . . . . . . . . . . . .84 Linker options . . . . . . . . . . . . . . . . . . . 84 16-bit linker . . . . . . . . . . . . .. . . . . . . 84 Discard nonresident name table. . . . . . . 84 Enable 32-bit processing. . . . . . . . . . . . 84 Inhibit optimizing far call to near . . . . . . 84 Initialize segments . . . . . . . . . . . . . . . 85 Linker goodies . . . . . . . . . . . . . . . . . 85 Segment alignment. . . . . . . . . . . . . . . 85 Transfer resident names to nonresident names table . . . . . . . . . . . . . . . . . . 85 16-bit optimizations . . . . . . . . . . . . . . .86 Chain fixups. . . . . . . . . . . . . . . . . . . 86 Iterate data . . . . . . . . . . . . . . . . . . . 87 Minimize resource alignment . . . . . . . . 87 Minimize segment alignment . . . . . . . . 87 32-bit linker . . . . . . . . . . . . . . . . . . . . 87 Allow import by ordinal . . . . . . . . . . . 88 Committed stack size (in hexadecimal). . . 88 Committed stack size (in hexadecimal). . . 88 iii File alignment (in hexadecimal) . . . . . . . 88 Image base address (in hexadecimal) . . . . 89 Image is based . . . . . . . . . . . . . . . . . 89 Maximum linker errors . . . . . . . . . . . . 89 Object alignment (in hexadecimal) . . . . . . 89 Reserved heap size (in hexadecimal) . . . : 90 Reserved stack size (in hexadecimal) . . . . 90 Verbose. . . . . . . . . . . . . ~ . . . . . . . . 90 General . . . . . . . . . . . . . . . . . . . . . . 91 Case-sensitive exports and imports . . . . . 91 Case-sensitive link . . . . . . . . . . . . . . . 91 Code pack size . . . . . . . . . . . . . . . . . 91 Default libraries. . . . . . . . . . . . . . . . . 91 Include debug information . . . . . . . . . . 92 Pack code segments . . . . . . . . . . . . . . 92 Subsystem version (major.minor) . . . . . . 92 Command-line usage . . . . . . . . . . . 93 Map file . . . . . . . . . . . . . . . . . . . . . . 93 Include source line numbers . . . . . . . . . 93 Map file . . . . . . . . . . . . . . . . . . . . . 93 Off . . . . . . . . . . . . . . . . . . . . . . . 93 Publics . . . . . . . . . . . . . . . . . . . . 94 Segments. . . . . . . . . . . . . . . . . . . 94 Print mangled names in map file. . . . . . . 95 Warnings. . . . . . . . . . . . . . . . . . . . . 95 "No stack" warning. . . . . . . . . . . . . . . 95 32-bit warnings. . . . . . . . . . . . . . . . . 95 Warn duplicate symbol in .LIB . . . . . . . . 95 Make options . . . . . . . . . . . . . . . . . . . .96 Autodependencies . . . . . . . . . . . . . . . 96 Cache . . . . . . . . . . . . . . . . . . . . . . . 96 Cache and display . . . . . . . . . . . . . . . 96 None . . . . . . . . . . . . . . . . . . . . . . . 96 Use . . . . . . . . . . . . . . . . . . . . . . . . 96 Break make on. . . . . . : . . . . . . . . . . . 96 Errors . . . . . . . . . . . . . . . . . . . . . . . 96 Fatal errors. . . . . . . . . . . . . . . . . . . . 96 Warnings . . . . . . . . . . . . . . . . . . . . 97 New node path . . . . . . . . . . . . . . . . . 97 Messages options. . . . . . . . . . . . . . . . . .97 ANSI Violations. . . . . . . . . . . . . . . . . 97 Display warnings. . . . . . . . . . . . . . . . 98 All . . . . . . . . . . . . . . . . . . . . . . . . . 98 None . . . . . . . . . . . . . . . . . . . . . . . 98 Selected . . . . . . . . . . . . . . . . . . . . . 98 General . . . . . . . . . . . . . . . . . . . . . . 98 User-defined warnings . . . . . . . . . . . . 99 Inefficient C++ coding . . . 99 Inefficient coding . . . . . . 99 Obsolete C++ . . .100 Portability . . . . . . . . . .100 Potential C++ Errors. . . . .. 100 Potential errors. . . . . . . . . 101 Stop after ... errors . . . . . . . . . . . .. . 101 Stop after ... warnings . . . . . . . . . . . . . 102 Optimization options . . . . . . . . . . . . . . 102 General settings. . . . . . . . . . . . . . . . . 102 16 and 32-bit. . . . . . . . . . . . . . . . . . . 102 Common subexpression. .. . . . . . . . . . .102 No optimization. . . . . . . . . . . . . . .102 Optimize Globally . . . . . . . . . . . . .103 Optimize locally. . . . . . . . . . . . . . . 103 Induction variables . . . . . . . . . . . . . . . 103 Inline intrinsic functions. . . . . . . . . . . .104 16-bit . . . . . . . . . . . . . . . . . . . . . . . 104 Assume no pointer aliasing. . . . . . . . . .104 Copy propagation . . . . . . . . . . . . . . .105 Dead code elimination. . . . . . . . . . . . .105 Global register allocation . . . . . . . . . . . 105 Invariant code motion. . . . . . . . . . . . .105 Jump optimization . . . . . . . . . . . . . . . 106 Loop optimization . . . . . . . . . . . . . . . 106 Suppress redundant loads . . . . . . . . . . 107 Windows prolog/ epilog . . . . . . . . . . .107 32-bit . . . . . . . . . . . . . . . . . . . . . . . 107 Cache hit optimizations (Intel compiler only) . . . . . . . . . . . . . 107 Optimize across function boundaries (Intel compiler only) . . . . . . . . . . . . . 107 Pentium instruction scheduling . . . . . . . 108 General optimization settings . . . . . . . . 109 Disable all optimizations . . . . . . . . . . . 109 Optimize for size. . . . . . . . . . . . . . . . 109 .Optimize for speed . . . . . . . . . . . . . . . 109 Use selected optimizations . . . . . . . . . . 110 Resources options . . . . . . . . . . . . . . . . 110 16-bit Resources. . . . . . . . . . . . . . . . . 110 Target windows version . . . . . . . . . .. 110 Windows 3.1. . . . . . . . . . . . . . ... 110 Windows 95 . . . . . . . . . . . . . . . . . 110 Pack fastload area . . . . . . . . . . . . . . . 111 Librarian. . . . . . . . . . . . . . . .. . . . . . 111 Case-sensitive library . . . . . . . . . . . . . 111 Create extended dictionary. . . . . . . . . .111 Generate list file . . . . . . . . . . . . . . . . 111 Library page size. . . . .. . . . . . . . . . .111 Purge comment records. . . . . . . . . . . .112 32-bit Resources . . . . . . . . . . . . . . . . . 112 Language . . . . . . . . . . . . . . . . . . . .112 Major . . . . . . . . . . . . . . . . . . . . . 112 Minor . . . . . . . . . . . . . . . . . . . . . 112 Target Windows version . . . . ..... 112 Command-line only options. . . . . . . . . . 113 iv Application I Basic Options . . . . . . . . . 129 Target Name . . . . . . . . . . . . . . . . . .129 Base Directory . . . . . . . . .. . . . . . . .130 Application I Basic Options I Features to Include . . . . . . . . . . . . . . . . . . . 130 Dockable Toolbar. . . . . . . . . . . . . . .. 130 Status Line. . . . . . . . . . . . . . . . . . . . 130 Recently Used Files List . . . . . . . . . . . . 130 Registry Support. . . . . . . . . . . . . . . . 130 Drag/Drop . . . . . . . .. . . . . . . . . . . .130 Printing . . . . . . . . . . . . . . . . . . . . . 130 Mail Support . . . . . . . . . . . . . . . . . .130 Help File Support . . . . . . . . . . . . . .. 131 Help File Name. . . . . . . . . . . . . . . .. 131 Application I Advanced Options . . . . . . 131 Application Startup State. . . . . . . . . .. 131 Control Style . . . . . . . . . . . . . . . . . .131 Application I Advanced Options I Application Startup State . . . . . . . . . . 131 Normal (sizeable). . . . . . . . . ; . . . . .. 131 Minimized (iconic). . . . . . . . . . . . . . .131 Maximized (entire screen) . . . . . . . . . . 132 Application I Advanced Options I Control Style . . . . . . . . . . . 132 Standard Windows . . . . . . . . . . . . . .132 Borland BWCC. . . . . . . . . . . . . .... 132 MS Control 3D . . . . . . . . . . . . . . . . .132 Application I OLE 2 Options. . . . . . . . . 132 OLE 2 Container Options. . . . . . . . . . .132 OLE 2 Server Options. . . . . . . . . . . . .132 Enable Automation in the Application . . .132 Server ill. . . . . . . . . . . . . . . . . . . . .132 Application I Code Generation Control . . 133 Target Name . . . . . . . . . . . . . . . . . .133 Base Directory . . . . . . . . . . . . . . . . .133 Source Directory . . . . . . . . . . . . . . . .133 Header Directory. . . . . . . . . . . . . . . .133 Main Source File . . . . . . . ~. . . . . . . .133 Main Header File. . . . . . . . . . . . . . ... 133 Application Class. . . . . . . . . . . . . . . .133 About Dialog Class . . . . . . . . . . . . . .134 Use Long File Names . . . . . . . . . . . .. 134 Comments. . . . . . . . . . . . . . . . . . .. 134 Terse . . . . . . . . . . . . . . . . . . . . . 134 Verbose. . . . . . . . . . . . . . . . . . . .134 Application I Administrative Options . . . 134 Version Number . . . . . . . . . . . . . . . .134 Copyright . . . . . . • . . . . . . . . . . . . .134 Description . . . . . . . . . . . . . . . . . . . 134 Author . . . . . . . . . . . . . . . . . . . . . . 134 Company . . . . . . . . . . . . . . . . . . .. 135 Object search paths . . . . . . . . . . . . . . .113 16 and 32-bit command-line switches . . . .113 C++ compile. . . . . . . . . . . . . . . . . . .113 Compile .OBJ to filename . . . . . . . . . . . 114 Compile to .ASM, then assemble . . . . . . . 114 Compile to .OBJ, no link . . . . . . . . . . . . 114 Compile to assembler . . . . . . . . . . . . . 114 Create a mapfile . . . . . . . . . . . . . . . . 114 Pass option to linker . . . . . . . . . . . . . .114 Specify assembler. . . . . . . . . . . . . . . .114 Specify assembler option . . . . . . . . . . .115 Specify executable file name . . . . . . . . .115 Undefine symbol. . . . . . . . . . . . . . . .115 16-bit command-line switches. . .. . . . . .115 Compile to DOS .COM . . . . . . . . . . . .115 Compile to DOS .EXE . . . . . . . . . . ... 115 Compile to DPMI .EXE . . . . . . . . . . . .115 Enable backward compatibility options .. 115 Expanded memory swapping . . . . . . ..116 Extended memory swapping. . . . . . . . .116 Generate 8087 instructions . . . . . . . . . .116 Generate overlay code. . . . . . . . . . . . .116 Link DOS .COM . . . . . . . . . . . . . . . .116 Link OOS .EXE . . . . . . . . . . . . . . . . .116 Link DPMI.EXE . . . . . . . . . . .. . . . .117 Link Windows .DLL . . . . . . . . '. . . . . . 117 Link Windows .EXE . . . . . . . . . . . . . .117 Overlay the compiled files . . . . . . . . . .117 Overlay the compiled files . . . . . . . . . .J,J7 Specify option to RLINK . . . . . . . . . . .117 32-bit command-line switches. . . . . . . . .117 Generate a multi-threaded target . . . . . .118 Link 32-bit.DLL file . . . . . . . . . . . . . . 118 Link 32-bit.EXE file . . . . . . . . . . . . . . 118 Link for 32-bit console application. . . . . .118 Link using 32-bit Windows API . . . . . . .118 Command-line options by function . . . . . 118 Command-line options quick reference. . . 124 Chapter 4 Building Applications with AppExpert 127 Steps for Creating an Application with AppExpert. . . . . . . . . . . . . . . . . 128 Application options. . . . . . . . . . . . . . . . 128 Application I Window Model . . . . . . . .129 MDI (Multiple Document Interface) ..... 129 SDI (Single Document Interface). . . . . . .129 Dialog Client . . . . . . . . . . . . . . . . . .129 Document/View. . . . . . . . . . . . . . . .129 v ChapterS Main Window options. . . . . . . . . . . . . . 135 Window Title . . . . . . . . . . . . . . . . . . 135 Main Window I Background Color . . . . .135 Use Default Color . . . . . . . . . . . . . . . 135 Use System Color Constant. . . . . . . . . .135 Use Specified Color . . . . . . . . . . . . . .135 Main Window I Basic Options. . . . . . . .135 Window Styles . . . . . . . . . . . . . . . . .136 Caption. . . . . . . . . .. . . . . . . . . .136 Border . . . . . . . . . . . . . . . . . . . . 136 Max Box . . . . . . . . . . . . . . . . . . . 136 MinBox . . . . . . . . . . . . . . . . . . . 136 Vertical Scroll . . . . . . . . . . . . . . . . 136 Horizontal Scroll . . . . . . . . . . . . . .136 System Menu . . . . . . . . . . . . . . . .136 Visible . . . . . . . . . . . . . . . . . . . .136 Disabled . . . . . . . . . . . . . . . . . . . 136 Thick Frame. . . . . . . . . . . . . . . . .136 Clip Siblings: . . . . . . . . . . . . . . . .137 Clip Children . . . . . . . . . . . . . . . .137 Main Window I SDI Client Window . . . .137 Client/View Class . . . . . . . . . . . . . . .137 Document Class . . . . . . . . . . . . . . . .137 Description . . . . . . . . . . . . . . . . . . .137 Filters. . . . . . . . . . . . . . . . . . . . . . .137 Default Extension. . . . . . . . . . . . . . . .137 Class Name . . . . . . . . . . . . . . . . . . .137 Source File. . . . .. . . . . . . . . . . . . . . .138 Header File . . . . . . . . . . . . . . . . . . .138 Client/View Class . . . . . . . . . . . . . . .138 Main Window I MDI Client Window. . . .138 Client Class . . . . . . . . . . . . . . . . . . .138 Source File. . . . . . . . . . . . . . . . . . . .138 Header File . . . . . . . . . . . . . . . . . . .139 Main Window I Dialog Client Window . .139 Client Class . . . . . . . . . . . . . . . . . . .139 Source File. . . . . . . . . . . . . . . . . . . .139 Header File . . . . . . . . . . . . . . . . . . .139 Dialog ID. . . . . . . . . . . . . . . . . . . . .139 Include a Menu Bar . . . . . . . . . . . . . .139 MDI Child/View Options. . . . . . . . . . . . 139 MDI Child Class . . . . . . . . . . . . . . . . . 140 Source File . . . . . . . . . . . . . . . . . . . . 140 Header File. . . . . . . . . . . . . . . . . . . . 140 MDI Child/View I Basic Options . . . . . . 140 MDI Client/View Class . . . . . . . . . . . . 140 Document Class . . . . . . . . . . . . . . . .140 Description . . . . . . . . . . . . . . . . . . . 141 Filters. . . . . . . . . . . . . . . . . . . . . . .141 Default Extension . . . . . . . . . . . . . . . . 141 Class Name . . . . . . . . . . . . . . . . . . . 141 Source File . . . . . . . . . . . . . . . . . . . . 141 Header File . . . . . . . . . . . . . . . . . . .141 Managing classes with ClassExpert 143 Starting ClassExpert. . . . . . . . . . . . . . . 143 ClassExpert Classes pane . . . . . . . . . . . 144 Classes pane SpeedMenu. . . . . . . . . . . 144 Add New Class. . . . . . . . . . . . ... 144 Automate Class. . . . . . . . . . . . . . .144 Delete Automation . . . . . . . . . . . . . 144 View Document Templates . . . . . . . . 144 View Class Info . . . . . . . . . . . . .. .144 Edit Source . . . . . . . . . . . . . . . . . . 145 Edit Header . . . . . . . . . . . . . . . . . 145 Edit Dialog . . . . . . . . . . . . . . . . . . 145 Edit Menu . . . . . . . . . . . . . . . . . .145 ClassExpert Events pane . . . . . . . . . . . 145 Events pane SpeedMenu . . . . . . . . . . .145 Add Handler . . . . . . . . . . . . . . . .146 Delete Handler . . . . . . . . . . . . . . .146 Add Instance Variable . . . . . . . . . . .146 Delete Instance Variable ........... 147 Add Data . . . . . . . . . . . . . . . . . . . . 147 Delete Data . . . . . . . . . . . . .. . . . 147 View Data . . . . . . . . . . . . . . . . . .147 Add Method. . . . . . . . . . . . . . . .. 147 Delete Method. . . . . . . . . . . . . . . .148 View Method . . . . . . . . . . . . . . . .148 Add Property . . . . . . . . . . . . . . . .148 Delete Property . . . . . . . . . . . . . . . 148 View Property. . . . . . . . . . . . . . . .148 Events I Automation . . . . . . . . . . . . .149 Events I Command Notifications. . . . . . 149 Events I Control Notifications . . . . . . . . 149 Events I Virtual Functions . . . . . . . . . .149 Events I Windows Messages . . . . . . . . . 149 ClassExpert Edit pane . . . . . . . . . . . . . 150 Edit pane SpeedMenu. . . . . . . . . . . . .150 Use Class. . . . . . . . . . . . . . . . . . .150 Using Rescan. . . . . . . . . . . . . . . . . . . 150 Deleting a class . . . . . . . . . . . . . . . . . 150 Moving a class . . . . . . . . . . . . . . . . . 151 Renaming an AppExpert element. . . . . . 151 Importing a class . . . . . . . . . . . . . . . . 151 Rebuilding the .APX database file. . . . . . 152 Chapter 6 Browsing through your code vi 153 Using the Browser. . . . . . . . . . . . . . . . 153 Starting the Browser . . . . . . . . . . . . . . 154 Browser views . . . . . . . . . . . . . . . . .154 Browsing objects (class overview) . . . . . . 154 Browsing global symbols . . . . . . . . . . . 154 Search . . . . . . . . . . . . . . . . . . . . . . 155 Browser SpeedMenu. . . . . . . . . . . . . .155 Viewing and editing code at a breakpoint . 171 Viewing code at a breakpoint . . . . . ... 171 Editing code at a breakpoint . . . . . . . . .171 Resetting invalid breakpoints. . . . . . . . . 172 Using breakpoint groups . . . . . . . . . . . 172 Creating a breakpoint group. . . . . . . . .172 Disabling or enabling a breakpoint group . . . . . . . . . . . . . . . . . . . . . . 172 Using breakpoint option sets . . . . . . . . . 172 Creating a breakpoint option set. . . . . . .173 Associating a breakpoint with an option set . . . . . . . . . . . . . . . . . . . 173 Changing breakpoint options. . . . . . . . . 173 Changing the color of breakpoint lines . . . 173 Using the Breakpoints window . . . . . . . 174 Aboutthe Breakpoints window . . . . . . . 174 Integrated debugger features . . . . . . . . . 175 Add breakpoint. . . . . . . . . . . . . . . . .175 Qualifiers . . . . . . . . . . . . . . . . . . . . 175 Other . . . . . . . . . . . . . . . . . . . . . . . 175 Source breakpoint . . . . . . . . . . . . . . . 175 Address breakpoint . . . . . . . . . . . . . .176 Data watch breakpoint . . . . . . . . . . .. 176 C++ exception breakpoint . . . . . . . . . . 176 as exception breakpoint . . . . . . . . . . . 177 Thread breakpoint. . . . . . . . . . . . . . .177 Module breakpoint. . . . . . . . . . . . . .. 177 Breakpoint Conditions/ Action Options .. 177 Names . . . . . . . . . . . . . . . . . . . . . . 178 Conditions . . . . . . . . . . . . . . . . . . .178 Expr. True. . . . . . . . . . . . . . . . . . .. 178 Thread ID . . . . . . . . . . . . . . . . . . . .179 Pass Count . . . . . . . . . . . . . . . . . . . 179 Actions . . . . . . . . . . . . . . . . . . . . .179 Break . . . . . . . . . . . . . . . . . . . . . . . 180 Stop Log. . . . . . . . . . . . . . . . . . . . .180 Start Log . . . . . . . . . . . . . . . . . . . . 180 Log Expr ....................180 Eval Expr . . . . . . . . . . . . . ... . . . . .180 Log Message . . . . . . . . . . . . . . . . . .180 Disable Group . . . . . . . . . . . . . . . . .181 Enable Group .................181 Add Breakpoint Conditions / Action Option Set.... . . . . . . . . . . . .181 Edit Breakpoint dialog box . . . . . . . . . .181 Examining program data values . . . . . . . 181 ModifYing program data values. . . . . . . 182 Understanding watch expressions. . . . . . 182 Using the Watches window . . . . . . . . . 182 Formatting watch expressions . . . . . . . . 183 Adding a watch. . . . . . . . . . . . . . . . . 183 Add Watch dialog box. . . . . . . . . . . . .183 Browsing symbols in your code . . . . . . . 155 Symbol declaration window . . . . . . . . .155 Browsing references . . . . . . . . . . . . . .156 Class inspection window . . . . . . . . . . .156 Browser filters and letter symbols . . . . . . . 156 To view all instances of a particular type of symbol. . . . . . . . . . . . . . . . . . . . 157 To hide all instances of a particular type of symbol. . . . . . . . . . . . . . . . . . . . 157 To change several filter settings at once ... 157 Customizing the Browser . . . . . . . . . . . . 157 Chapter 7 USing the integrated debugger 159 Types of bugs . . . . . . . . . . . . . " .,. 159 Run-time errors . . . . . . . . . . . . . . . . .159 Logic errors . . . . . . . . . . . . . . . . . . . 160 Planning a debugging strategy. . . . . . . . . 160 Starting a debugging session . . . . . . . . . . 160 Compiling with debug information . . .. .161 Running your program in the IDE . . . . . .161 Specifying program arguments . . . . . . .162 Controlling program execution. . . . . . . . . 162 Running to the cursor location . . . . . . . . 163 The execution point. . . . . . . . . . . . . . .163 Finding the execution point. . . . . . . . . .163 Stepping through code. . . . . . . . . . . . . 164 Statement Step Into . . . . . . . . . . . . . . . 164 Statement Step Over. . . . . . . . . . . . . .166 Debugging member functions and external code . . . . . . . . . . . . . . . . .166 Running to a breakpoint. . . . . . . . . . . . 166 Pausing the program. . . . . . . . . . . . . . 166 Terminating the program . . . . . . . . . . . 167 Using breakpoints . . . . . . . . . . . . . . . . 167 Debugging with breakpoints . . . . . . . . . 167 Setting breakpoints. . . . . . . . . . . . . . .168 Setting an unconditional breakpoint . . . .168 Setting a conditional breakpoint. . . . . . .168 Setting other breakpoints . . . . . .. . . . .168 Setting breakpoints after program execution begins . . . . . . . . . . . . . . .169 Creating conditional breakpoints. . . . . . . 169 Removing breakpoints. . . . .. . . . . . . . .170 From an Edit window. . . . . . . . . . . . .170 From an Edit window or the Disassembly pane of the CPU window. . . . . . . . .. 170 From the Breakpoints window. . . . . . . .170 Disabling and enabling breakpoints. . . . .171 vii Command-line compiler syntax . . . . . . . 198 Default settings . . . . . . . . . . . . . . . . . 198 Command-line options . . . . . . . . . . . . 198 Option precedence rules . . . . . . . . . . . 199 Using compiler configuration files. . . . . . 199 Using response files . . . . . . . . . . . . . . 199 Entering directories for command-line options . . . . . . . . . . . . . . . . . . . . . 200 Using TLINK and TLINK32. . . . . . . . . . 201 !LINK command-line syntax. . . . . . . . . 201 Linker configuration files . . . . . . . . . . . 203 Linker response files. . . . . . . . . . . . . . 203 Using the linkers with the command-line compilers. . . . . . . . . . . . . . . . . . . . 204 Linking libraries . . . . . . . . . . . . . . . . 204 Module definition file reference. . . . . . . . 205 Module definition file defaults . '. . . . . . . 206 CODE statement . . . . . . . .. . . . . . . . 206 DATA statement . . . . . . . . . . . . . . . . 207 DESCRIPTION statement. . . . . . . . . . . 207 EXETYPE statement . . . . . . . . . . . . . . 207 EXPORTS statement. . . . . . . . . . . . . . 208 HEAPSIZE statement . . . . . . . . . . . . . 209 IMPORTS statement. . . . . . . . . . . . . . 209 LIBRARY statement . . . . . . . . . . . . . . 210 NAME statement. . . . . . . . . . . . . . . . 210 SECTIONS statement . . . . . . . . . . . . . 211 SEGMENTS statement. . . . . . . . . . . . . 211 STACKSIZE statement. . . . . . . . . . . . . 212 STUB statement. . . . . . . . . . . . . . . . . 213 , SUBSYSTEM statement . .'. . . . . . . . . . 213 Example module definition file. . . . . . . . 214 Changing watch properties . . . . . . . . . . 184 Edit Watch dialog box. . . . . . . . . . . . .185 Disabling and enabling watches . . . . . . . 185 Deleting a watch. . . . . . . . . . . . . . . . . 185 Evaluating and modifying expressions . . . 185 Evaluating expressions . . . . . . . . . . . .186 Modifyjng the values of variables . . . . . .187 Inspecting data elements . . . . . . . . . . . . 188 Displaying low-level information about a running program . . . . . . . . . . . . . . . 189 Resizing the CPU window panes. . . . . . .189 Listing addresses of disassembled instructions. . . . . . . . . . . . . . . . . . . 189 The Disassembly pane SpeedMenu . . ... 190 Run to . . . . . . . . . . . . . . . . . . . . . . 190 Toggle Breakpoint . . . . . . . . . . . . . . . 190 Goto address . . . . . . . . . . . . . . . . . . 190 Goto current Pc. . . . . . . . . . . . . . ... 190 Goto source . . . . . . . . . . . . . . . . . . .191 Change thread . . . . . . . . . . . . . . . . . 191 Displaying raw values in addressable areas . of your program. . . . . . . . . . . . . . . . 191 The Dump pane SpeedMenu. . . . . . . .. 191 Displayas . . . . . . . . . . . . . . . . . . . . 192 Displaying raw values in your program stack ... " . . . . . . . . . . . . . . . . . . . 192 The Stack pane SpeedMenu. . . . . . .... 192 Goto top frame . . . . . . . . . . . . . . . . .193 Goto top of stack . . . . . . . . . . . . . . . .193 Displaying CPU registers . . . . . . . . . . . 193 The Registers pane SpeedMenu . . . . . .. 193 Change Thread . . . . . . . . . . . . . . . . .193 Increment register . . . . . . . . . . . . ... 193 Decrement register. .. . . . . . . . . . . .. 193 Zero register. . . . . . . . . . . . . . . . . . .193 Change register. . . . . . . . . . . . . . . . .194 Show old registers/Show current registers. 194 Displaying flags and current information. .194 The Flags pane SpeedMenu. . . . . . . . .. 194 Toggle flag . . . . . . . . . . . . . . . . . . . . 195 Viewing function calls. . . . . . . . . . . . . . 195 Navigating to function calls. . . . . . . . . .195 Debugging dynamic-link libraries. . . . . . . 196 Part II Resource Workshop user's guide Chapter 9 Getting started with Resource Workshop What is a resource? . . . . . . . . . . .. . . . Why you should link resources to your applications. . . . . . . . . . . . . . . . . . . What is a resource script(.RC) file? . . . . . What is a binary resource (.RES) file? . . . . Setting preferences. _. . . . . . . . . . . . . . . Undoing mistakes. . . . . . . . . . . . . . . . Chapter 8 Compiling and linking from the command line 217 197 Using the command-line compilers . . . . . : 197 viii 219 219 220 220 221 221 221 Edit I Undo . . . . . . . . . . . . . . . . . . . 222 Edit I Redo . . . . . . . . . . . . . . . . . . . . 222 Starting Resource WorkShop. . . . . . . . . . 222 Working with icons. . . . . . . . . . . . . . . 237 Creating a new icon. . . . . . . . . . . . . . . 237 Creating a new icon in a standalone file. . . 238 Editing an existing icon. . . . . . . . . . . . . 238 Design issues . . . . . . . . . . . . . . . . . . 238 Drop shading. . . . . . . . . . . . . . . . . .239 Adding an image to an icon resource . . . . 239 Changing the attributes of an icon . . . . . . 239 Copying an icon image to a new color format. . . . . . . . . . . . . . . . . . . 239 Deleting an icon resource or image. . . . . . 240 Deleting an icon resource . . . . . . . . . . . 240 Deleting an icon image . . . . . . . . . . . . 240 Testing an icon . . . . . . . . . . . . . . . . . . 241 Progra:rnmmg an icon with ObjectWindows 241 Progra:rnmmg an icon with the Windows API. . . . . . . . . . . . . . . . . . 241 Chapter 10 Working with resource p,rojects 223 Creating a new resource project . . . . . . .223 Opening an existing resource project . . . .224 Saving a resource project. . . . . . . . . . . .224 Embedding a resource in a resource project 225 Linking a resource to a resource project. . .225 Using the Resource Project window. . . . .226 Embedded and linked resources. . . . . . .226 Status line . . . . . . . . . . . . . . . . . . . .226 Chapter 11 Creating bitmaps, cursors, and icons J 229 Chapter 12 Working with bitmaps. . . . . . . . . . . . . . 229 Creating a new bitmap. . . . . . . . . . . . . . 229 Creating a new bitmap in a standalone file. . 230 Editing an existing bitmap . . . . . . . . . . . 230 Changing the attributes of a bitmap. . . . . . 231 Deleting a bitmap resource . . . . . . . . . . . 231 Testing a bitmap . . . . . . . . . . . . . . . . . 231 Programming a bitmap with OWL . . . . . . 231 Progra:rnmmg a bitmap with the Windows API . . . . . . . . . . . . . . . . . . 232 Working with cursors . . . . . . . . . . . . . . 232 Creating a new cursor . . . . . . . . . . . . . . 233 Creating a new cursor in a standalone file. . 233 Editing an existing cursor. . . . . . . . . . . . 233 Design issues. . . . . . . . . . . . . . . . . . .234 Setting the hot spot for a cursor. . . . . . . . . 234 Deleting a cursor . . . . . . . . . . . . . . . . . 234 Deleting a cursor resource. . . . . . . . . . .235 Deleting a cursor image . . . . . . . . . . . .235 Testing a cursor. . . . . . . . . . . . . . . . . . 235 Adding an image to a cursor resource. . . . . 235 Changing the attributes of a cursor . . . . . . 236 Copying a cursor image to a new color format . . . . . . . . . . . . . . . . . . . . . . . 236 Progra:rnmmg a cursor with OWL. . . . . . . 236 Progra:rnmmg a cursor with the Windows API . . . . . . . . . . . . . . . . . . . 237 Using the Graphics editor 243 Using the Color palette. . . . . . . . . . . . . 244 Selecting a foreground color. . . . . . . . . . 244 Selecting a background color . . . . . . . . . 244 ,Transparent and inverted areas. . . . . . . . 245 Hiding and showing the Color palette. . . . 246 Choosing the number of colors for a resource . . . . . . . . . . . . . . . . . . . . 246 Customizing colors . . . . . . . . . . . . . . . 246 Modifying the Color palette . . . . . . . . . 246 Selecting a pen style. . . . . . . . . . . . . . . 247 Selecting a brush shape. . . . . . . . . . . . . 247 Selecting a paint pattern . . . . . . . . . . . . 248 Drawing and painting . . . . . . . . . . . . . 248 Drawing a line. . . . . . . . . . . . . . . . . . 248 Drawing a shape. . . . . . . . . . . . . . . . . 249 Filling an area with color. . . . . . . . . . . . 249 Adding text. . . . . . . . . . . . . . . . . . . . 249 Erasing an area . . . . . . . . . . . . . . . . . 250 Selecting an area. .,. . . . . . . . . . : . . . . 250 Aligning an area.. . . . . . . . . . . . . . . . 251 Moving or resizing an area. . . . . . . . . . . 251 Copying an area . . . . . . . . . . . . . . . . . 251 Removing an area. . . . . . . . . . . . . . . . 252 Zooming in or out. . . . . . . . . . . . . . . . 252 ix Moving a graphic around in the drawing area. . . . . . . . . . . . . . . . . . . 253 Tool palette. . . . ... . . . . . . . . . .. . . . . 253 Hiding and showing the Tool palette. . . . . 254 Pick Rectangle tool . . . . . . . . . . . . . . . . 254 Scissors tool . . . . . . . . . . . . . . . . . . . . 254 Zoom tool . . . . . . ; . . . . . . . . . . . . . . 255 Eraser tool . . . . . . . . . . . . . . . . . . . . . 255 Pen tool. . . . . . . . . . . . . . . . . . . . . . . 255 Paintbrush tool . . . . . . . . . . . . . . . . . . 256 Airbrush tool . . . . . . . . . . . . . . . . . . . 256 Paint Can tool . . . . . . . . . . . . . . . . . . . 256 Line tool . . . . . . . . . . . . . . . . . . . . . . 257 Text tool . . . . . . . '.' . . . . . . . . . . . . . 257 Empty frame tools . . . . . . . . . . . . . . . . 258 Ellipse tool . . . . . . . . . . . . . . . . . . . .258 Rectangle tool . . . . . . . . . . . . . . . . . .258 Rounded Rectangle tool . . . . . . . . . . . .258 Filled-in frame tools . . . . . . . . . . . . . . . 258 Filled Rectangle tool . . . . . . . . . . . . . .259 Filled Rounded Rectangle tool . . . . . . . .259 Filled Ellipse tool . . . . . . . . . . . . . . . .259 Eye Dropper tool . . . . . . . . . . . . . . .. . 259 Arc tool. . . . . . . . . . . . . . . . . . . . . . . 260 Hand tool. . . . . . . . . . . . . . . . . . . . . . 260 Pattern style tool . . ~ . . . . . . . . . . . . . . 261 Pen style tool. . . . . . . . . . . . . . . . . . . . 261 Airbrush shape tool. . . . . . . . . . . . . . . . 261 Paintbrush shape tool . . . . . . . . . . . . . . 262 Saving a bitmapped resource as a file. . . . 268 Editing a resource as text . . . . . . . . . . . 268 Chapter 14 Working with dialog boxes Using DLGINIT resources. . . . . . . . . . Creating a new dialog box. . . . . . . . . . Creating a new dialog box in a resource script file. . . . . . . . . . . . . . . . . . . . Editing an existing dialog box. . . . . . . . Adding a caption to a dialog box. . . . . . Including a menu in a dialog box. . . . . . Choosing a window type, frame style, and dialog box style. . . . . . . . . . . . . . . . Specifying dialog box fonts . . . . . . . . . Assigning a custom class to a dialog box . Setting the position of a dialog box. . . . . Testing a dialog box. . . . . . . . . . . . . . Programming a dialog box with OWL. . . Programming a dialog box with the Windows API. . . . . . . . . . . . . . . . . Working with controls . . . . . . . . . . . . Adding controls to a dialog box. . . . . . . Working with custom controls . . . . . . . Duplicating a control . . . . . . . . . . . . . Moving and resizing a single control. . . . Selecting multiple controls. . . . . . . . . . Aligning multiple controls. . . . . . . . . . Resizing multiple controls . . . . . . . . . . Reordering controls. . . . . . . . . . . . . . Grouping controls. . . . . . . . . . . . . . . Specifying which controls are tab stops . . Editing control properties . . . . . . . . . . Chapter 13 Working with resources 263 Resource file types . . . . . . . . . . . . . . . . 264 Executable and dynamic-link library files . . 264 Working with binary files . . . . . . . . . . .264 Opening and saving .EXE, .DLL, and .RES files . . . . . . . . . . . . . .. . . . . .265 Using a resource editor . . . . . . . . . . . . . 265 Renaming a resource. . . . . . . . . . . . . ; 265 Deleting a resource . . . . . . . . . . . . . . .266 Specifying resource memory options . . . .266 Moving a resource . . . . . . . . . . . . . . .266 16-bit vs. 32-bit resources . . . . . . . . . . . 266 Saving a resource . . . . . . . . . . . . . . . .267 Saving a resource in a resource script file . .267 271 . 271 . 272 . . . . 272 272 273 273 . . . . . . 273 274 274 275 275 275 . . . . . . . . . . . . . 276 276 276 277 278 278 279 279 280 281 281 282 282 Chapter 15 Using the Dialog editor 283 Using the Property Inspector . . . . . . . . . 283 The modal Property Inspector . . . . . . . . 283 . The modeless Property Inspector . . . . . . 284 Displaying the Property Inspector . . . . . . 284 About the Control palette . . . . . . . . . . . 285 Moving the Control palette. . . . . . . . . . 285 Hiding and showing the Control palette . . 285 To place a control. . . . . . . . . . . . . . . . 285 Standard page of the Control palette. . . . . 286 x Selector tool . . . . . . . . . . . . . . . . . . . . 286 Push Button tool . . . . . . . . . . . . . . . . . 286 Radio Button tool. . . . . . . . . . . . . . . . . 287 Check Box tool. . . . . . . . . . . . . . . . . . . 287 Static Text tool . . . . . . . . . . . . . . . . . . . 287 Text Edit tool . . . . . . . . . . . . . . . . . . . 288 List Box tool . . . . . . . . . . . . . . . . . . . . 288 Combo Box tool. . . . . . . . . . . . . . . . . . 288 Horizontal Scroll Bar tool . . . . . . . . . . . . 288 Vertical Scroll Bar tool . . . . . . . . . . . . . . 289 Group Box tool . . . . . . . . . . . . . . . . . . 289 Static Frame tool . . . . . . . . . . . . . . . . . 289 Static Rectangle tool . . . . . . . . . . . . . . . 289 Horizontal Static Line tool. . . . . . . . . . . . 289 Vertical Static Line tool. . . . . . . . . . . . . . 289 Static Picture tool . . . . . . . . . . . . . . . . . 290 Common page of the Control palette . . . . . 290 Animation tool . . . . . . . . . . . . . . . . . . 290 Tab Controltool. . . . . . . . . . . . . . . . . . 290 Tree View tool. . . . . . . . . . . . . . . . . . . 291 List View tool . . . . . . . . . . . . . . . . . . . 291 Hot Key tool. . . . . . . . . . . . . . . . . . . . 291 Progress Bar tool . . . . . . . . . . . . . . . . . 291 Up-Down tool. . . . . . . . . . . . . . . . . . . 291 Track Bar tool . . . . . . . . . . . . . . . . . . . 292 Header tool . . . . . . . . . . . . . . . . . . . . 292 Rich Text Edit tool . . . . . . . . . . . . . . . . 292 Status Window tool. . . . . . . . . . . . . . . . 292 Tool Bar tool. . . . . . . . . . . . . . . . . . . . 292 BWCC page of the Control palette. . . . . . . 293 BWCC Push Button tool. . . . . . . . . . . . . 293 Adding a bitmap to a BWCC pushbutton. .293 BWCC Check Box tool. . . . . . . . . . . . . . 294 BWCC Group Box tool. . . . . . . . . . . . . . 294 BWCC Horizontal Line tool. . . . . . . . . . . 294 BWCC Radio Button tool. . . . . . . . . . . . 295 BWCC Vertical Line tool. . . . . . . . . . . . . 295 BWCC Static Text tool . . . . . . . . . . . . . . 295 Custom page of the Control palette . . . . . . 295 Data Access page of the Control palette. . . . 295 Data Aware page of the Control palette. . . . 295 Tool palette. . . . . . . . . . . . . . . . . . . . . 296 Left Sides tool . . . . . . . . . . . . . . . . . . . 296 Horizontal Centers tool . . . . . . . . . . . . . 296 Right Sides tool. . . . . . '. . . . . Horizontal Center in Dialog tool Tops tool . . . . . . . . . . . . . . Vertical Centers tool. . . . . . . . Bottoms tool . . . . . . . . . . . . Vertical Centers in Dialog tool. . Space Horizontally Equal tool. . Space Vertically Equal tool. . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 297 297 297 297 297 297 297 Chapter 16 About menus 299 Terminology . . . . . . . . . . . . . . . . . . . Working with menus. . . . . . . . . . . . . . Using the menu editor . . . . . . . . . . . . . Edit window . . . . . . . . . . . . . . . . . . . Creating a new menu. . . . . . . . . . . . . . Editing an existing menu. . . . . . . . . . . . Moving and copying menu statements . . . Undoing errors. . . . . . . .. . . . . . . . . . Adding menu items and separators . . . . . Editing a menu item. . . . . . . . . . . . . . . Deleting a menU item. . . . . . . . . . . . . . Creating a pop-up menu .. . . . . . . . . . . Adding accelerator text to menus. . . . . . . Adding accelerator resources to menus . . . Testing a menu. . . . . . . . . . . . . . . . . . Testing for duplicate menu items . . . . . . . Programming menus and accelerators with OWL. . . . . . . . . . . . . . . . . . . . Programming menus and accelerators with the Windows API . . . . . . . . . . . . 299 299 300 300 300 300 301 301 301 302 302 302 303 303 303 303 304 304 Chapter 17 xi Working with identifiers 305 Identifiers. . . . . . . . . . . . . . . . . . . . . Identifier files. . . . . . . . . . . . . . . . . . . Creating an identifier file. . . . . . . . . . . . Adding identifiers. . . . . . . . . . . . . . . . Editing identifiers . . . . . . . . . . . . . . . . Moving identifiers from one file to another. Deleting identifiers . . . . . . . . . . . . . . . Listing identifiers . . . . . . . . . . . . . . . . Managing identifiers . . . . . . . . . . . . . . 305 306 306 306 306 307 307 308 308 Chapter 18 Using the Text editor Using a macro . . . . . . '. . . . . . . . . . . . 329 String substitutions in macros . . . . . . . . 330 Default MAKE macros. . . . . . . . . . . . . 330 Modifying default macros. . . . . . . . . . . 331 Using MAKE directives. . . . . . . . . . . . . 331 .autodepend. . . . . . . . .. . . . . . . . . . . 332 !error . . . . . . . . . . . . . . . . . . . . . . . 332 Summing up error-checking controls. . . . 332 !if and other conditional directives. . . . . . 333 !include. . . . . . . . . . . . . . . . . . . . . . 334 !message . . . . . . . . . . . . . . . . . . . . . 334 .path.ext . . . . . . . . . . . . . . . . . . . . . 334 .precious . . . . . . . . . . . . . . . . . . . . . 335 .suffixes. . . . . . . . . . . . . . . . . . . . . . 335 !undef.. '. . . . . . . . . . . . . . . . . . . . . 335 Using macros in directives . . . . . . . . . . 336 Null macros . . . . . . . . . . . . . . . . . . . 336 309 Saving your changes. . . . . . . . . . . . . . . 309 Compiling a text version of a resource . . . . 309 Creating resources with the Text editor .... 310 Writing resource scripts . . . . . . . . . . . . . 310 Chapter 19 Working with user-defined resources 313 Creating a resource type. . . . . . . . . . . . . 313 Adding a user-defined resource . . . . . . . . 314 Using the RCDATA resource type . . . . . . . 314 Editing a user-defined resource . . . . . . . . 315 Embedding resource data in a project file. . . 315 Entering data in the resource script . . . . . . 315 Testing a user-defined resource . . . . . . . . 316 Chapter 21 Part III Borland C++ tools and utilities 317 Using command-line resource tools 319 Resource compiler (BRCC32) . . . . . . . . . 337 Resource linkers (RLINK and RL1NK32) . . 339 Resource shell (BRC32). . . . . . . . . . . . . 340 Chapter 20 Using MAKE , MAKE basics . . . . . . . . . . . . . . . . . . . 319 BUlLTINS.MAK . . . . . . . . . . . . . . . . . 320 Using TOUCH.EXE. . . . . . . . . . . . . . .321 MAKE options. . . . . . . . . . . . . . . . . .321 Setting options on as defaults . . . . . . . . . 322 Compatibility with Microsoft's NMAKE. .323 Using makefiles. . . . . . . . . . . . . . . . . . 323 Symbolic targets. . . . . . . . . . . . . . . . .324 Rules for symbolic targets. . . . . . . . . . .324 Explicit and implicit rules. . . . . . . . . . . . 324 Explicit rule syntax . . . . . . . . . . . . . . . 324 Single targets with multiple rules . . . . . .325 Implicit rule syntax. . . . . . . . . . . . . . .326 Explicit rules with implicit commands . . .326 Commands syntax . . . . .. . . . . . . . . .326 Command prefixes. . . . . . . . . . . . . . .327 Using@ . . . . . . . . . . . . . . . . . . . . . 327 Using -num and - . . . . . . . . . . . . . . .327 Using& ...................... 327 Command operators. . . . . . . . . . . . . .328 Debugging with temporary files. . . . . . .328 Using MAKE macros. . . . . . . . . . . . . . . 328 Defining macros. . . . . . . . . . . . . . . . .329 337 Chapter 22 WinSight 343 Starting and stopping screen updates . . . . 343 Turning off message tracing . . . . . . . . . 344 Choosing a view. . . . . . . . . . . . . . . . . 344 Class List view. . . . . . . . . . . . . . . . . . 344 Using the Class List view . . . . . . . . . . . 345 Spying on classes. . . . . . . . . . . . . . . . 345 Window Tree view . . . . . . . . . . . . . . . 345 Finding a window . . . . . . . . . . . . . . . 346 Leaving Find Window mode. . . . . . . . .346 Spying on windows . . . . . . . . . . . . . . 347 Choosing messages to trace . . . . . . . . . . 347 Using the Message Trace view. . . . . . . . 347 . Other tracing options . . . . . . . . . . . . .347 Chapter 23 WinSpector 353 Configuring WINSPCTR.LOG . . . . . . . . 354 WINSPCTR.LOG reference . . . . . . . . . . 355 Disassembly section . . . . . . . . . . . . . . 356 xii Choosing menu commands from the keyboard. . . .. . . . . . . . . . . . . . . .382 SpeedMenus. . . .. . . . .. . .. . . . .382 Choosing menu commands with the mouse . . . . . . . . . . . . . . . . . . . . . 382 Shortcuts. . . . . . . . . . . . . . . . . . . . . 382 Turbo Profiler windows. . . . . . . . . . . . 383 Window management. . . . . . . . . . . .. 383 The status line. . . . . . . . . . . . . . . . . . 384 Dialog boxes. . . . . . . . . . . . . . . . . . . 385 Part 2: The menu reference. . . . . . . . . . . 385 == menu (System) . . . . . . . . . . . . . . . . 385 Repaint Desktop . . . . . . . . . . . . . . . .385 Restore Standard. . . . . . . .. . . . . . . .385 About . . . . . . . . . . . . . . . . . . . . . . 386 File menu . . . . . . . . . . . . . . . . . . . . 386 Open . . . . . . . . ' . . . . . . . . . . . . . . . 386 Session Saving. . . . . . . . . . . . . . .. 387 Get Info . . . . . . . . . . . . . . . . . . . . .388 DOS Shell . . . . . . . . . . . . . . . . . . . .388 Quit . . . . . . . . . . . . . . . . . . . . . . . . 389 View menu . . . . . ... . . . . . . . . . . . . 389 SpeedMenus . . . . . . . . . . . . . . .... 389 Module. . . . . . . . . . . . . . . . . . . . . . 390 Line ...... ' . . . . . . . . . . . . . . . . 391 Search. . . . . . . . . . . . . . . . . . . . . 391 Next. . . . . . . . . . . . . . . . . . . . . . 391 Goto . . . . . . . . . . . . . . . . . . . . . . 391 Add Areas. . . . . . . . . . . . . . . . . .392 Remove Areas. . . . . . . . . . . . . . . .392 Operation . . . . . . . . . . . . . . . . . .392 Callers . . . . . . . . . . . . . . . . . . . . . .393 Module . . . . . . . . . . . . . . . . . . . . 394 File . . . . . . . . . . . . . . . . . . . . . . 394 Edit command. . . . . . . . . . . . . . . .395 Execution Profile. . . . . . . . . . . . . . . .395 Display. . . . . . . . . . . . . . . . . . . .396 Filter . . . . . . . . . . . . . . . . . . . . . 397 Module . . . . . . . . . . . . . . . . . . . . 397 Position. . . . . . . . . . . . . . . . . . . .398 Remove . . . . . . . . . . . . . . . . . . . . 398 Callers . . . . . . . . . . . . . . . . . . . . . .398 Inspect (left pane). . . . . . . . . . . . . .401 Inspect (right pane) . . . . . . . . . . . . .401 Sort (right pane). . . . . . . . . . . . . . .401 Overlays . . . . . . . . . . . . . . . . . . . . . 401 Display . . . . . . . . . . . . . . . . . . . . 402 Inspect . . . . . . . . . . . . . . . . . . . .402 Interrupts . . . . . . . . . . .'. . . . . . . . .402 Collection (top pane). . . . . . . . . . . .403 Subfunctions (top pane) . . . . . . . . . .403 Add (top pane) . . . : . . . . . . . . . . .403 Pick (top pane) . . . . . . . . . . . . . . .403 Remove (top pane) . . . . . . . . . . . . .403 Stack Trace section . . . . . . . . . . . . . . .356 Register section . . . . . . . . . . . . . . . . .357 Message Queue section . . . . . . . . . . . .357 Tasks section. . . . . . . . . . . . . . . . . . .357 Modules section. . . . . . . . . . . . . . . . .358 USER and GDI heap section. . . . . . . . . .358 System Information section . . . . . . . . . .358 Processing WinSpector data. . . . . . . . . . . 359 DFA output . . . . . . . . . . . . . . . . . . .359 UsingDFA with WINSPCTR.LOG . . . . . . 359 Using DFA with WINSPCTR.BIN . . . . . . 360 Other WinSpector tools . . . . . . . . . . . . . 360 Using'EXEMAP.EXE . . . . . . . . . . . . . . 361 Using TMAPSYM.EXE . . . . . . . . . . . . . 361 Using BUILDSYM.EXE. . . . . . . . . . . . .361 Part IV Turbo Prof Her user's guide 363 Chapter 24 Asample profiling session 367 About the sample programs . . . . . . . . . . 368 Profiling a program (PRIMEO) . . . . . . . . . 368 Setting up the profile options . . . . . . . . .369 Collecting data . . . . . . . . . . . . . . . . . . 370 Displaying statistics. . . . . . . . . . . . . . .370 . Printing modules and statistics. . . . . . . . . 372 Time and counts profile listing . . . . . . . .372 Profile statistics report . . . . . . . . . . . . .373 Saving and restoring statistics . . . . . . . . . 374 Analyzing the statistics . . . . . . . . . . . . . 374 Viewing both source code and statistics. . .375 Saving the window configuration. . . . . .376 Measuring an area's efficiency . . . . . . . .376 A modularized primes test (PRIME1). . . . . 377 Modifying the program and reprofiling . . . 378 Loading another program (PRIME2). . . . .378 Reducing calls to a routine (PRIME3) . . . .378 Still more efficiency (PRIME4) . . . . . . . .379 Eliminating CR/LF pairs (PRIMES) . . . . .380 Where to now? . . . . . . . . . . . . . . . . . 380 Chapter 25 The Turbo Prof Her environment 381 Part 1: The environment components. . . . . 381 The menu bar and menus . . . . . . . . . . .381 xiii Delete All (top pane) . . . . . . . . . . . .403 Display (bottom pane) . . . . . . . . . . .404 Files . . . . . . . . . . . . . . . . . . . . . . . .404 Collection (top pane) . . . . . . . . . . . .405 Detail (top pane) . . . . . . . . . . . . . .405 When Full (top pane). . . . . . . . . . . .405 Display (bottom pane) . . . . . . . . . . .405 Areas . . . . . . . . . . . . . . . . . . . . . . .405 Add Areas . . . . . . . . . . . . . . . . . .406 ~ Remove Areas. . . . . . . . . . . . . . . .407 Inspect . . . . . . . . . . . . . . . . . . . .407 Options. . . . . . . . . . . . . . . . . . . .407 Sort . . . . . . . . . . . . . . . . . . . . . .408 Routines . . . . . . . . . . . . . . . . . . . . .408 Local Module (right pane) . . . . . . . . .409 Areas (both panes) . . . . . . . . . . . . .409 Callers (both panes) . . . . . . . . . . . .409 Module (both panes) . . . . . . . . . . . .409 Profile (both panes). . . . . . . . . . . . .409 Disassembly (CPU). . . . . . . . . . . . . . .409 Goto . . . . . . . . . . . . . . . . . . . . . .410 Origin . . . . . . . . . . . . . . . . . . . . .410 Follow . . . . . . . . . . . . . . . . . . . .411 Previous . . . . . . . . . . . . . . . . . . .411 View Source . . . . . . . . . . . . . . . . .411 Mixed . . . . . . . . . . . . . . . . . . . . .411 Text File . . . . . . . . . . . . . . . . . . . . .412 Goto . . . . . . . . . . . . . . . . . . . . . .412 Search . . . . . . . . . . . . . . . . . . . . .412 Next . . . . . . . . . . . . . . . . . . . . . .412 File . . . . . . . . . . . . . . . . . . . . . .413 Edit . . . . . . . . . . . . . . . . . . . . . .413 Coverage. . . . . . . . . . . . . . . . ... . . .413 Add All Modules (left pane) . . . . . . .414 Remove All Modules (left pane) .... .414 Add Module (left pane) . . . . . . . . . .414 Remove Module (left pane) . . . . . . . .414 Delete This Item (left pane) . . . . . . . .414 Display (right pane) . . . . . . . . . . . .414 Position (right pane) . . . . . . . . . . . .415 Module (right pane) . . . . . . . . . . . .415 Run menu . . . . . . . . . . . . . . . . . . . .416 Run . . . . . . . . . . . . . . . . . . . . . . . .416 Program Reset . . . . . . . . . . . . . . . . .416 Arguments. . . . . . . . . . . . . . . . . . . .416 Statistics menu . . . . . . . . . . . . . . . . . .417 Callers . . . . . . . . . . . . . . . . . . . . . .417 Files . . . . . . . . . . . . . . . . . . . . . . . .418 Interrupts . . . . . . . . . . . . . . . . . . . .418 Overlays . . . . . . . . . . .. . . . . . . . . .418 Profiling Options. . . . . . . . . . . . . . . .418 Accumulation. . . . . . . . . . . . . . . . . .420 Disabling accumulation . . . . . . . . . .420 Delete All . . . . . . . . . . . . . . . . . . . .422 Save. . . . . . . . . . . . . . . . . . . . . . . . 422 Saving Files . . . . . . . . . . . . . . . . .422 Restore. . . . . . . . . . . . . . . . . . . . . .422 Print menu. . . . . . . . . . . . . . . . . . . . 423 Statistics . . . . . . . . . . . . . . . . . . . . .423 Module . . . . . . . . . . . . . . . . . . . . . .423 Options . . . . . . . . . . . . . . . . . . . . .424 Options menu. . . . . . . . . . . . . . . . . . 424 Macros . . . . . . . . . . . . . . . . . . . . . . 425 Create . . . . . . . . . . . . . . . . . . . . . 425 Stop Recording . . . . . . . . . . . . . . .425 Remove . . . . . . . . . . . . . . . . . . . . 425 Delete All . . . . . . . . . . . . . . . . . .425 Recording macros. . . . . . . . . . . . . .425 Display Options . . . . ., . . . . . . . . . .426 Display Swapping . . . . . . . . . . . . .426 Screen Lines . . . . . . . . . . . . . . . . .427 Tab Size . . . . . . . . . . . . . . . . . . .427 Width of Names . . . . . . . . . . . . . .427 Path for Source . . . . . . . . . . . . . . . . .427 Save Options . . . . . . . . . . . . . . . . . .427 Restore Options. . . . . . . . . . . . . . . . .428 Window menu . . . . . . . . . . . . . . . . . 429 Zoom . . . . . . . . . . . . . . . . . . . . . . . 429 Next . . . . . . . . . . . . . . . . . . . . . . .429 Next Pane . . . . . . . . . . . . . . . . . . . .429 Size/Move . . . . . . . . . . . . . . . . . : .. 429 Iconize /Restore. . . . . . . . . . . . . . . . .429 Close . . . . . . . . . . . . . . . . . . . . . . . 430 Undo Close . . . . . . . . . . . . . . . . . . .430 User Screen . . . . . . . . . . . . . . . . . . .430 The open window list . . . . . . . . . . . . .430 Help menu. . . . . . . . . . . . . . . . . . . . 430 Index . . . . . . . . . . . . . . . . . . . . . . . 430 Previous Topic . . '. . . . . . . . . . . . . . .431 Help on Help . . . . . . . . . . . . . . . . . . 431 Chapter 26 Profiling strategies 433 Preparing to profile . . . . . . . . . . . . . . . 434 Adjusting your program . . . . . . . . . . . 434 Compiling your program. . . . . . . . . . . 435 Setting profile areas . . . . . . . . . . . . . . 435 What level of detail do you need? . . . . . .436 Adding areas . . . . . . . . . . . . . . . . . .437 What type of data do you need? . . . . . .437 When should data collection start? ; . . . . 438 How do you want time data grouped? .. .438 Which data do you want to view? . . . . . 438 xiv Chapter 28 Profiling your program . . . . . . . . . . . . . 439 Focusing the profile session. . . . . . . . . .439 Testing algorithms . . . . . . . . . . . . . . . 440 Verifying and testing programs . . . . . . .440 Timing execution and monitoring performance. . . . . . . . . . . . . . . . . .440 Studying unfamiliar code ... ' . . . . . . . . 441 Which analysis mode to use. . . . . . . . . .441 Active analysis . . . . . . . . . . . . . . . . . 442 Passive analysis. . . . . . . . . . . . . . . . .442 Passive versus active analysis. . . . . . .443 Coverage analysis . . . . . . . . . . . . . . . 443 Speeding up profiling . . . . . . . . . . . . .443 Improving statistical accuracy. . . . . . . . .443 Insufficient data. . . . . . . . . . . . ..... 444 Resonance . .. . . . . . . . . . . . . . . . . .444 Some tips for profiling overlays. . . . . . . .444 Profiling object-oriented programs. . . . . .445 Interpreting and applying the profile results . . . . . . . . . . . . . . . . . . 445 Analyzing profile data . . . . . . . . . . . . .445 Execution Profile window. . . . . . . . . . .446 Callers window. . . . . . . . . . . . . . . . .446 Overlays window . . . . . . . . . . ..... 446 Interrupts window. . . . . . . . . . . . . . .446 Files window . . . . . . . . . . . . . . . . . . 446 Coverage window . . . . . . . . . . . . . . .446 Filtering collected data. . . . . . . . . . . . .447 Revising your program. . . . . . . . . . . . .448 Modifying data structures. . . . . . . . . . . 448 Storing precomputed results . . . . . . . . .449 Caching frequently accessed data . . . . . .449 Evaluating data as needed . . . . . . .... 449 Optimizing existing code . . . . . . . . . . .449 Wrapping it up . . . . . . . . . . . . . . . . . . 450 Turbo Profiler's command-line options Chapter 29 Customizing Turbo Profiler 465 Rmming TFINST . . . . . . . . . . . . . . . . . 465 Setting the screen colors. . . . . . . . . . . . . 466 Customizing screen colors. . . . . . . . . . .466 Windows. . . . . . . . . . . . . . . . . . . . 466 Dialog boxes and menus. . . . . . . . . . . 466 Screen . . . . . . . . . . . . . . . . . . . . . . 467 The default colors. . . . . . . . . . . . . . . .467 Setting Turbo Profiler display parameters. . . . . . . . . . . . . . . . . . . . 467 Display Swapping. . . . . . . . . . . . . . . .467 Screen Lines . . . . . . . . . . . . . . . . . . .468 Fast Screen Update . . . . . . . . . . . . . . .468 Permit 43/50 Lines . . . . . . . . . . . . . . .468 Full Graphics Saving . . . . . . . . . . . . . .468 Tab Size. . . . . . . . . . . . . . . . . . . . . .468 User Screen Updating . . . . . . . . . . . . .469 Turbo Profiler options. . . . . . . . . . . . . . 469 The Directories dialog box. . . . . . . . . . .469 The User Input and Prompting dialog box. . . . . . . . . . . . . . . . . . . .469 History List Length. . . . . . . . . . . . . . 470 Interrupt Key . . . . . . . . . . . . . . . . . 470 Mouse Enabled . . . . .. . . . . . . . . . . 470 Beep on Error . . . . . . . . . . . . . . . . . 470 Control Key Shortcuts . . . . . . . . . . . . 470 The Miscellaneous Options dialog box . . .470 Printer Output. . . . . . . . . . . . . . . . . 471 NMI Intercept. . . . . . . . . . . . . . . . . 471 Ignore Case of Symbols . . . . . . . . . . . 471 Chapter 27 Inside the profiler 459 The command-line options. . . . . . . . . . . 459 Batch mode (-b) . . . . . . . . . . . . . . . . .460 Configuration file (-c) . . . . . . . . . . . . .461 Display update (-d) . . . . . . . . . . . . . . .461 Help (-h and -?) . . . . . . . . . . . . . . . . .461 Session-state saving (-jn). . . . . . . . . . . .462 Mouse support (-p). . . . . . . . . . . . . . .462 Remote profiling (-r) . . . . . . . . . . . . . .462 Source code and symbols (-s). . . . . . . . .462 Video hardware (-v) . . . . . . . . . . . . . .463 451 Area boundaries . . . . . . . . . . . . . . . . . 452 Time and count collection . . . . . . . . . . .452 Showing routine call overhead . . . . . . . .453 Who pays forloops? . . . . . . . . . . . . . .453 Multiple return statements . . . . . . . . . .455 Disabling often-called functions . . . . . . .455 Logging callers . . . . . . . . . . . . . . . . . . 456 Sampling vs. counting. . . . . . . . . . . . . . 457 Profilermemory use . . . . . . . . . . . . . . . 458 xv International support . . . . . . . . . . . . .471 DOS Shell Swap Size (Kb). . . . . . .'. . . .472 Remote type. . . . . . . . . . . ~ . . . . . . .472 Remote Link Port. . . . . . . . . . . . . . . .472 Link Speed. . . . . . . . . . . . . . . . . . . .472 Network local name . . . . . . . . . . . . . .472 Network remote name. . . . . . . . . . . . .472 Setting the mode for display. . . . '.' . . . .472 Default . . . . . . . . . . . . . . . . . . . .472 Color . . . . . . . . . . . . . . . . . . . . .473 Black and White. . . . . . . . . . . . . . .473 Monochrome . . . . . . . . . . . . .... 473 LCD . . . . . . . . . . . . . . . . . . . . . . 473 When you're through... . . . . . . . . . . . . . 473 Saving changes . . . . . . . . . . . . . . . . .473 Save Configuration File . . . . . . . . . . . .473 Modify TPROF.EXE . . . . . . . . . . . . . .473 Exiting TFINST . . . . . . . . . . . . . . . . .474 Command-line options and TFINST equivalents. . . . . . . . . . . . . . . . . . . . 474 Chapter 31 Turbo Profiler for Windows Chapter 32 Prompts and error messages 497 Turbo Prdfiler prompts . . . . . . . . . . . . . 497 Turbo Profiler error messages . . . . . . . . . 499 Chapter 30 Remote profiling 489 Installing TPROFW . . . . . . . . . . . . . . . 490 Jnstalling TDDEBUG.386 . . . . . . . . . . .490 Configuring TPROFW. . . . . . . . . . . . . . 490 Using TPROFW command-line options. . .491 Using TFINST with TPROFW. . . . . . . . .491 UsingTPROFW. . . . . . . . . . . . . . . . . . 492 Profiling window procedures. . . . . . . . .492 The Window Procedure Messages dialog box . . . . . . . . . . . .' . . . . . . 493 Profiling dynamic-link libraries (DLLs) .. .494 TPROFW error messages. . . . . . . . . . . . 495 Appendix A 477 Hardware and software requirements . . . . 478 Profiling remote DOS applications. . . . . . . 478 Setting up the remote system . . . . . . . . .478 Configuring TFREMOTE . . . . . . . . . . .479 Customizing TFREMOTE. . . . . . . . . . .479 The remote DOS driver . . . . . . . . . . . .480 Starting the remote s~rial driver . . . . . . .480 Starting the remote LAN driver . . . . . . .480 Establishing the remote DOS link . . . . . .481 Serial connection . . . . . . . . . . . . . . . .481 LAN connection . . . . . . . . . . . . . . . .481 Profiling remote Windows applications . . . 482 Setting up the remote system . . . . . . . . .482 Configuring WREMOTE. . . . . . . . . . . .482 Serial configuration . . . . . . . . . . . . . .483 LAN configuration. . . . . . . . . . . . . . .483 WREMOTE command-line options. . . . .484 Starting the remote Windows driver. . . . .484 Establishing the remote Windows link . . .484 LAN connection . . . . . . . . . . . . . . . .485 Loading programs onto the remote system ... ',' . . . . . . . . . . . . . . . . . . 485 Remote profiling sessions. . . . . . . . . . . . 485 Troubleshooting. . . . . . . . . . . ; . . . . . . 486 TFREMOTE messages. . . . . . . ... . . . . . 486 . WREMOTE messages . . . . . . . . . . . . . . 487 xvi Borland C++ error messages and warnings 507 Message categories. . . . . . . . . . . . . . . . 507 Fatal errors . . . . . . . . . . . . . . . . . . . . 507 Errors . . . . . . . . . . . . . . . . .' . . . . . .507 Warnings. . . . . . . . . . . . . . . . . . . . .508 Informational messages . . . . . . . . . . . .508 . Message generators . . . . . . . . . . . . . . . 508 Compiler errors and warnings . . . . . . . .508 Run-time errors and warnings . . . . . . . .509 Linker errors and warnings . . . . . . . . . .509 Librarian errors and warnings . . . . . . . . 510 IDE debugger messages . . . . . . . . . . . .510 ObjectScripting error messages. . . . . . . .510 Help compiler messages . . . . . . . . . . . . 510 Message formats . . . . . . . . . . . . . . . . . 510 Symbols in messages . . . . . . . . . . . . . .511 Alphabetical list of messages. . . . . . . . . . 512 Index 615 Introduction Borland C++ is a powerful, professional programming tool for creating and maintaining DOS, Win16, and Win32 applications. Borland C++ supports both the C and C++ languages with its integrated development environment and command-line tools. How this book is organized This book is divided into the following parts: Part I, "The integrated development environment," introduces you to the integrated development environment (commonly known as the IDE). Part II, "Resource Workshop user's guide," teaches you how to use Resource Workshop to build resources for your Windows applications. Part III, "Borland C++ tools and utilities," describes additional tools you can use to build and debug your applications. Part IV, "Turbo Profiler user's guide," explains how to use Turbo Profiler to analyze the performance of your program as well as to monitor critical computer resources. Appendix A, "Borland C++ error messages and warnings," lists and describes the error messages that can be generated by the Borland C++ programming tools. Typefaces and icons used in this book This book uses the following special fonts: Monospace This type represents text that you type or text as it appears onscreen. Italics These are used to emphasize and introduce words, and to indicate variable names (identifiers), function names, class names, and structure names. Bold This type indicates reserved keywords words, format specifiers, and command-line options. Keycap This type represents a particular key you should press on your keyboard. For example, "Press Del to erase the character." Introduction 1 Note 2 Key1+Key2 This indicates a command that requires you to press Key1 with Key2. For example, Shift+a (although not a command) indicates the uppercase letter"A." ALL CAPS This type represents disk directories, file names, and application names. (However, header file names are presented in lowercase to be consistent with how these files are usually written in source code.) Menu I Choice This represents menu commands. Rather than use the phrase"choose the Save co:tnmand from the File menu," Borland manuals use the convention "choose File I Save." This icon indicates material that you should take special notice of. c++ User's Guide Using the integrated development environment Part I of this manual describes how to use the components of the Borland C++ integrated development environment (IDE). The IDE integrates development of DOS, Win16, and Win32 applications. Using the Project Manager, you can easily build several application types from a single project file. AppExpert and ClassExpert let you take advantage of ObjectWindows 5.0. The integrated debugger and browser let you debug your source code and browse class objects and hierarchies without leaving the IDE. The following chapters cover the tools available through the IDE: • Chapter 1, "Getting started," introduces you to the Borland C++ IDE and takes you through the creation of simple DOS, Windows, and 32-bit Windows programs. • Chapter 2, "Managing projects," describes the Project Manager and shows you how to use the TargetExpert and Source Pools to create the projects for your applications. • Chapter 3, "Specifying project options and compiling," shows you how to use Style Sheets and local overrides to set your project options and how to compile from the IDE. It also contains a complete reference to the options available for both the IDE and the command-line tools. • Chapter 4, "Building applications with AppExpert," describes AppExpert and shows you how to create the source-code foundation for your ObjectWindows applications. • Chapter 5, "Modifying applications with Class Expert," describes how to use ClassExpert to modify the applications you create. Part I, Using the integrated development environment 3 • Chapter 6, uBrowsing classes and objects," shows you how to use the browser to examine your C++ classes. • Chapter 7, UUsing the integrated debugger," describes the integrated debugger and how to use it to step and trace through your program code. • Chapter 8, UUsing the command-line tools," provides an overview of using command-line tools rather than the IDE as you program. 4 C++ User's Guide Getting started Borland C++ is a development package that contains the compilers, tools, and utilities you need for developing Win16, Win32, and DOS applications. While the tools included with Borland C++ can be run from either Windows or the DOS command-line, you'll find that you can accomplish most of your application development using the Integrated Development Environment (IDE). To help you get familiar with the IDE, this chapter offers an overview of the following IDE features: • • • • • • Starting the Borland C++ IDE Using SpeedMenus in the IDE Using the Edit window Working with simple projects Customizing the IDE Running other programs from the IDE Starting the Borland C++ IDE After installing Borland C++, the Program Manager contains a program group titled Borland C++ 5.0. Open this group to reveal the icons for the C++ IDE (labeled Borland C++) and the other programming tools that ship with Borland C++. When you double-click the Borland C++ icon, the IDE opens. Inside the IDE, you'll find all the tools you'll need to create C++ programs. Along with windows for the editor, browser, and debugger, the IDE contains windows for project files and compiler and programming tool messages. Figure 1.1 shows how the IDE might look after compiling a simple Windows project. Chapter 1, Getting started 5 Figure 1.1 The Borland C++ IDE Menu Bar SpeedBar H - - - - - - - - - i t - - Edit window -----fl-- Message window - - - - - - - - f t - - Project window Status Bar The IDE menu system Table 1.1 describes the menus on the IDE menu bar. Table 1.1 File Edit Search View Project Script Tool Debug Options Window Help 6 c++ User's Guide The IDE menus Commands to open, save, and print files. Also includes the IDE exit command. Clipboard commands and commands for undoing and redoing program edits. Commands for searching and replacing strings, browsing symbols, locating functions, and reviewing error messages generated by the programming tools. Commands to open the ClassExpert, Project Manager, Message window, and Browser. Also contains commands to open the various integrated debugger windows. Commands to open, close, and compile projects. Also contains the AppExpert command. Provides commands to run and compile scripts to automate IDE functionality. Commands to launch programming tools from the IDE, including Turbo Debugger. Commands to run your project under control of the integrated debugger. IDE customization and project configuration commands. IDE window management commands. Commands to access the Borland C++ online Help system. The IDE SpeedBar The SpeedBar (located under the main menu) has buttons that give quick access to menu commands which relate to the area of the IDE you're working in. For example, if you're editing code, the SpeedBar contains cut and paste commands, file save commands, and so on. When the Project window has focus, the SpeedBar has buttons that pertain to projects, such as commands for adding project nodes and browsing option settings. The Status Bar at the bottom of the IDE contains "flyby" help hints; when the cursor is over a button, the Status Bar describes the button command. You can configure the flyby hints and other SpeedBar options as described in "Customizing the SpeedBars" on page 14. Using Speed Menus in the IDE Right-clicking (clicking the right mouse button) accesses the Borland C++ SpeedMenus. SpeedMenus contain commands that are context-sensitive to the area of the program you're working in. For example, the SpeedMenu for the Edit window contains commands that are related to the editor. In the Project Manager, the SpeedMenus contain commands to help you with managing your projects. To get a feeling for SpeedMenus, try the following: 1 From the IDE, choose Project I Open, then open the project file MULTITRG.IDE in the \ BCS\ EXAMPLES\IDE \ MULTITRG directory. 2 Double-click the MULTITRG [.CPP] node to open the file in an Edit window. 3 Move the cursor to the string.h header file reference by clicking on the file name in the source code. 4 Right click to open the Edit window SpeedMenu, then choose Open Source to open an Edit window that contains this header file. Note In addition to right-clicking, the IDE speedmenus can be accessed at any time by pressing Alt+F10. Using the Edit window Edit windows contain the Borland C++ editor, which you can use to create and edit your program code. When you're editing a file, the IDE status bar displays the following information about the file you're editing: • The line number and character position of the cursor. For example, if the cursor is on the first line and first character of an Edit window, you'll see 1:1 in the status bar; if the cursor is on line 68 and character 23, you'll see 68:23. • The edit mode: insert or overwrite. Press Insertto toggle whether your text additions overwrite existing characters or insert new ones into the file. Chapter 1, Getting started 7 • The file's save status. The word Modified appears if you've made changes to the file in the active Edit window, and you have not yet saved your edits or changes. Note The Borland C++ editor contains many powerful features to help you enter and modify your program code. For example, you can undo multiple edits by choosing Edit I Undo or pressing Alt+Backspace. You can also open multiple Edit windows; tile the windows as you wish; subdivide the window into different Edit panes; and cut, copy, and paste text between any open files. Although this chapter provides a brief introduction to the editor, complete details on how to use and customize the editor can be found in the online Help that accompanies the IDE. Choose Help I Contents, then' click Integrated Development Environment for a list of topics that relate to the IDE. From here, view the Editor topic, and the Menu - Commands topics Edit Menu and Search Menu. Creating a new file To introduce you to the editor, step through the following instructions to create a DOS program that's used as an example later in this chapter. Create the directory \MYSOURCE using the File Manager or DOS (you'll use this directory to hold the project files you create later in this chapter). 2 From the IDE, choose File I New to open a new Edit window with an empty file. By default, Borland C++ names new files NONAMExx.CPP, where xx is a number that's incremented with each new file opened. . 3 In the Edit window, type the following C++ code to create a DOS program: #includeint main (void) cout « "Welcome to the World of DOS! \n" ; return(O); //print text 4 Choose File I Save As, and save your new file in the \MYSOURCE directory with the file name DOS_TEST.CPP (this file is used later in this chapter). Working with simple projects After you first install Borland C++, you'll want to make sure the program is correctly set up; the details of the compiler and the IDE can wait until later. The best way to test your setup is to compile a few sample programs. In this section, you'll learn how to create and run several simple programs. The first program is a DOS program. After creating the DOS program, you'll be taken through the steps to create a 16-bit Windows program. Then, using the TargetExpert, you'll be shown how to change the 16-bit program into a 32-bit program. 8 c++ User's Guide Creating a DOS program using EasyWin You can become familiar with the Project Manager and the c++ compiler by following these steps to create a simple DOS program: 1 From the IDE, choose Project I New Project, then set the following options in the New Target dialog box: 1 Type the path and name for your new project in the Project Path And Name input box. In this case, type: \mysource\dos_test.ide Note If the directory doesn't exist, the IDE creates the directory for you. 2 In the Target Type list box, click EasyWin [.EXE]. This selection creates a Windows program from a program that uses character-mode input and output. The New Target dialog box should now resemble the one shown in Figure 1.2. Figure 1.2 The New Target dialog box 2 Choose OK to close the New Target dialog box. The Project window opens and displays the target and dependencies of the project you just created. Notice that one of the nodes in the project points to the file DOS_TEST.CPP, the file you created earlier in the chapter (if you haven't already done so, create this file by following the instructions listed in the previous section, uCreating a new file"). 3 Because the)JEFand .RD files are unnecessary for this project, you must delete the .DEF and .RC nodes created by the Project Manager: 1 Select the DOS_TEST [.DEF], then press etr! and select DOS_TEST [.RC]. Chapter 1, Getting started 9 2 From the Project Manager SpeedMenu (press the right mouse button), choose Delete Node, then choose Yes to confirm your request to delete 2 project nodes. 4 Compile and run the program by double-clicking the DOS_TEST [.EXE] project node. If you correctly followed all the steps in this section, the program builds without errors and then runs in a window. If the compiler reports errors or warnings during the compile, retrace the steps in this section to ensure you correctly followed the steps. When the program compiles without errors, the Project Manager creates an executable program called DOS_TEST.EXE and places it in the \MYSOURCE directory. Note You can also create DOS programs that run from the DOS command line, and not in a window as the EasyWin program does. To do so, make the following selections in the New Target dialog box instead of the ones listed in the previous steps: 1 Under Target Type, choose Application [.EXE] (this is the default Target Type). 2 In the Platform combo box, choose DOS (Standard) as the target platform (to reveal the full range of platform options, click the arrow on the right side of the combo box). 3 Choose OK to confirm your settings. Note that when you make these selections, the Project Manager doesn't create the .DEF and .RC nodes, as it does for Windows target programs. Creating a Windows program This section demons~ates how to compile a simple Windows program. First you'll create a 16-bit Windows program, then you'll use the TargetExpert to modify the output to create a 32-bit Windows program. If you followed the steps in the preceding section to create a DOS program, you'll find that most of the steps for creating this Windows program are identical to those listed for the DOS program. When you're finished with this example, the tasks involved with creating and compiling simple programs with the IDE should be familiar: 1 Create a new project. 2 Set the target options using the New Target dialog box. 3 Add code to the appropriate nodes in the project. 4 Compile and run the project. Indeed, most projects will require more involved steps, but the basic steps for creating and compiling projects remains the same. With this in mind, follow these steps to create a simple Windows program: 1 Choose Project I New Project to open the New Target dialog box, then make the following ~ettings: 1 Type the following path and name for your new project in the Project Path And Name input box: \mysource\win_test.ide Note 10 If the directory doesn't exist, the IDE creates the directory for you. c++ User's Guide 2 In the Target Type list box, click Application [.EXE] to set the type of program you plan to create (this is the default setting). 3 In the Platform combo box, set the Target Type to Windows 3.x (16). 2 Click the Advanced button, then uncheck both the .RC and .DEF options in the dialog box that appears. Unchecking these settings tells the Project Manager that this project doesn't use definition and resource files, as most Windows programs do. 3 Choose OK to accept the settings, then choose OK again to close the New Target dialog box. The Project window opens with your new project. 4 In the Project window, double-click the win_test [.cpp] node to open an empty file in the Edit window. S In the Edit window, type the following code to create a Windows program, then save the program by choosing File I Save: #include int PASCAL WinMain(HINSTANCE hCurlnstance, HINSTANCE hPrevlnstance, LPSTR lpCmdLine, int nCmdShow) MessageBox(NULL, "Welcome to the World of Windows!", "A Windows Program", ME_OK I ME_ICONEXCLAMATION ) i return (0) i 6 Choose Project I Build All to compile this program, then choose OK after the compilation is finished. If you followed the steps correctly, you can arrange the windows so the IDE resembles the screen shown in Figure LIon page 6. When you build this project, the compiler produces several warnings, but it still creates an .EXE file in the \MYSOURCE directory. Even though a program that compiles with warnings can still be executed, it's not a good idea to ignore the warnings without first understanding why the compiler complained. The first warnings that appear indicate that the parameters in WinMain are never used in the program. In this small program, it is safe to ignore these warnings. The last warning indicates that the default module-definition settings are being used; this is expected since we didn't create a module-definition (.DEF) file. 7 To run the program from the IDE, choose Debug I Run. When you run this program, a small dialog box with the text "Welcome to the World of Windows!" appears. To terminate the program and return to the IDE, choose OK. Modifying the program target The last exercise in this chapter modifies the previous Windows example so that it creates a 32-bit Windows program that can take advantage of a Win32 operating system, such as Win32s or Windows NT. Before you can complete this exercise, you must be running a 32-bit operating system (such ~s Windows NT) or you must have Win32s installed on your system (you can choose to install Win32s when you install Borland C++). 1 If it is not already open, open the WIN_TEST.IDE project file through the Project I Open menu command. Chapter 1, Getting started 11 2 In the Project window, right-click the target node (WIN_TEST [.EXED to display the SpeedMenu, then choose TargetExpert. \ 3 Change the platform to Win32 in the Platform combo box, then choose OK to close the TargetExpert. 4 Recompile the program by choosing Project I Build All, then choose OK when the compilation finishes. Note It is important to choose Build All (and not Make) whenever you change the target type in your project. This ensures that the new target is rebuilt correctly. 5 ~ Run the program by double-clicking the WIN_TEST [.EXE] node in the Project Manager. Single file programs Usually when you begin to write a new program, you start by creating a new project for that program. Although it's possible to compile a single-source file program without using a project, it's usually easier to maintain the program settings through a project file. However, if you want to set target options for a single-source file program without creating a project, Choose Project I Close Project to make sure you don't have a project file open. 2 Choose File I Open, then open the source file containing your program. 3 Open the TargetExpert by right-clicking in the Edit window and choosing TargetExpert from the SpeedMenu. 4 Adjust the target settings for your smgle-source file program using the TargetExpert dialog box, as described in "Editing target attributes using TargetExpert" on page 27. 5 Choose Options I Project from the menu, and set the project options, as described in Chapter 3, "Specifying project options and compiling." 6 Choose Project I Compile (this command compiles the code in the current Edit window if no project is loaded). Customizing the IDE You can configure the IDE in many ways -to create a customized environment that meets your programming needs. For example, you can have the IDE do tasks automatically (such as saving backups of your files in the Editor windows) or handle special events. The Environment Options dialog box (accessed with the Options I Environment command) lets you configure the different elements and windows of the IDE. Once you've customized the IDE to your liking, choose Options I Save, check the options you want to save, then choose OK; the IDE saves your environment settings to aBle called BCCONFIG.BCW. By default, the file is saved to the BIN directory in your Borland C++ directory tree. This default directory is specified by the DefaultDesktopDir field of your BCWS.INI file, which is located in your Windows directory. 12 C++ Use r 's G u ide The Environment Options dialog box displays a list of customizable topics on the left and each topic's configurable options on the right. Some topics contain SUbtopics, indicated by a + next to the topic. For example, the Editor topic has subtopics called Options, File, and Display. To view a topic's subtopics, click the + sign next to the topic; its subtopics appear under it and the + turns to a- (you can then click the - to collapse the list of subtopics). Topics without subtopics appear with a dot next to their name. Figure 1.3 The Environment Options dialog box This chapter discusses the following Environment Options topics: • • • • • Note Configuring the IDE editor Syntaxhighlighting Customizing the SpeedBars Setting IDE preferences Saving your IDE settings Although this chapter doesn't offer a complete reference to the Environment Options dialog box, a complete reference is available by clicking the Help button in the Environment Options dialog box. Configuring the IDE editor You can configure the editor so that it looks and behaves like other editors such as Brief and Epsilon. The IDE editor uses keyboard mapping files (.KBD files) that set the keyboard shortcuts for the editor and the other windows in the IDE. You can modify this behavior using ObjectScripting. For more information see the online Help. C hap t e r 1, Get tin 9 s tar ted 13 Syntax highlighting Syntax highlighting lets you define a color and font attribute (such as bold) for certain elements of code. For example, you could display comments in blue and strings in red. Syntax highlighting is on by default. Syntax highlighting works on files whose extensions are listed in the Syntax Extensions list (by default, these files are .CPP, .C, .H, .HPP,.RH and .RC). You can add or delete any extension from this list, but be sure to separate extensions with semicolons. The Syntax Highlighting section displays the default color scheme and four predefined color settings. To use a predefined color scheme, 1 Choose Options I Environment I Syntax Highlighting. ,2 Choose one of the four color predefined schemes (Defaults, Classic, Twilight, or Ocean) by choosing the Color SpeedSetting; the sample code changes to the color scheme you select. To customize the syntax highlighting colors, 1 Choose Options I Environment, then select the Syntax Highlighting topic. 2 Select a predefined color scheme to use as a base for your customized colors. 3 Choose the Customize topic listed under the Syntax Highlighting topic. Elements and sample code appear on the right of the Environment Options dialog box. 4 Select an element you want to modify from the list of elements (for example, choose Comment), or click the element in the sample code (this selects the name in the Element list). You might need to scroll the sample code to view more elements. 5 Select a color for the element. The element color in the sample code reflects your selection. Use the left mouse button to select a foreground color for the element (FG appears in the color). Use the right mouse button to select a background color (BG appears in the color). If FB appears in the color, the color is used as both a background and a foreground color. 6 If you want, choose an Attribute (for example, bold). 7 You can check Default FG (foreground) or BG (background) to use the Windows default colors for an element. 8 Repeat steps 2-4 for the elements you want to modify. To turn off syntax highlighting, Choose Options I Environment I Syntax Highlighting, then uncheck Use Syntax Highlighting. Customizing the SpeedBars The IDE has context-sensitive SpeedBars for all its windows, including the Edit, Browser, Debugger, Project Manager, Message, Desktop, and ClassExpert windows. When a window has focus, the corresponding SpeedBar appears. Using the Environment Options dialog box, you can customize each of the SpeedBars so that they include only the buttons you want. 14 C++ User's Guide To add or delete buttons from the SpeedBars, 1 Choose Options I Environment from the IDE's main menu. 2 Choose the SpeedBar topic on the left. The right side of the dialog box displays general options for all SpeedBars. The options here let you specify if you want to hide or view the SpeedBar, where you want the SpeedBar to appear (on the top or bottom of the IDE), and if you want to use the Flyby Help Hints. If you check Use Flyby Help Hints, the IDE displays descriptions of the SpeedButtons on the status line when you pass. the mouse pointer over a button. If you leave this box unchecked, the hints show on the status line only when you click a SpeedButton. 3 Choose the Customize topic listed under the SpeedBar topic to customize the SpeedBar for a particular window. 4 In the Window combo box, choose the specific window (Editor, Browser, Debugger, Project, Message, IDE Desktop, or ClassExpert) whose SpeedBar you want to customize. The Available Buttons list box displays all the available (unused) buttons that you can add to a particular window's SpeedBar. (Each button has a name next to it that describes the button's function.) The Active Buttons list box displays the buttons that are currently contained in the selected window's SpeedBar. To add a button to a SpeedBar, double-click the button icon in the Available Buttons list, or select it and click the right-pointing arrow. The IDE places the button in front of the selected button in the Active Buttons list. To remove a button from a SpeedBar, double-click the button icon in the Active Buttons list, or select it and click the left-pointing arrow. The button moves to the Available Buttons list. .. To reorder the button positions for a SpeedBar, select a button in the Active Buttons list, and use the up and down arrows to move the button within the list (the top button in the list appears on the left side of the SpeedBar; the last button in the list appears on the right side of the SpeedBar) . .. To put separator spaces between buttons on the SpeedBar, select a button from the Active Buttons list, then click the Separator button. The separator is added before the selected button. @ @ You can also make all SpeedBars identical by selecting a SpeedBar in the Window list, then pressing the Copy Layout button. A dialog box appears in which you check all the SpeedBars you want to make identical to the selected SpeedBar. For example, if you first choose the Editor SpeedBar and then click Copy Layout, the dialog box appears with Editor dimmed. If you then check Project and Message, those SpeedBars will be exactly the same as the Editor SpeedBar. You can restore any SpeedBar to its original defaults by selecting the SpeedBar in the Window list, then clicking the Restore Layout button. C hap t e r 1, Get tin 9 s tar ted 15 Setting IDE preferences The Preferences command lets you customize what IDE settings you want automatically saved and how you want some IDE windows to work. To set preferences, 1 Choose Options I Environment I Preferences. 2 Check and uncheck the options you want, then choose OK. For an explanation of each option, see the online Help (press the Help button). Saving your IDE settings The IDE automatically saves information when you exit the IDE, use a transfer tool, build or make a project, run the integrated debugger, or close or open a project. You can control which areas of the IDE get saved from the Preferences topic in the Environment Options dialog box (choose Options I Environment from the main menu). If you want to save your settings manually, you can do so as follows: 1 Choose Options I Save. 2 Check Environment to save the settings from the Editor, Syntax Highlighting, SpeedBar, Browser, and Preferences sections of the Environment Options dialog box. These settings are saved in a file called BCCONFIG.BCW. 3 Check Desktop to save information about open windows and their positions. This information is saved to a file called .DSW. If you don't have a project open, the information is saved to a file called BCWDEF.DSW. 4 Check Project to save changes to your project (.IDE) file, including build options and node attributes. Running other programs from the IDE By default, the IDE lists Turbo Debugger, Resource Workshop, GREP, WinSight, WinSpector, and Key Map Compiler on the Tool menu. To run any of these tools from the IDE, choose Tool I ProgramName, where ProgramName is the name of the program you want to run (for example, Tool I GREP runs the GREP utility). You can run any executable program or utility without leaving the IDE by adding it to the Tool menu. For a complete discussion on adding items to the Tool menu, see n Adding translators, viewers, and tools to the IDE" on page 32. Using online Help in Borland C++ Borland C++ provides complete online documentation through the Help system. Using Help is a convenient way to get information about extensive language features, , compiler options, and any tasks you need to perform while developing applications in Borland C++. 16 C++ Us e r' s G u ide Online Help Organization The Help system is organized into Help files that reflect the structure of the documentation set as follows: Table 1.2 Borland C++ Help files How to Use Help (OPENHELP.HLP) Borland C++ Programmer's Reference (BCPP.HLP) Borland C++ User's Guide (BCW.HLP) Borland Windows Customer Controls Reference (BWCC.HLP) Class Libraries Guide (CLASSLIB.HLP) DOS Reference (BCOOC.HLP) Error Messages and Wamings (BCERRMSG.HLP) ObjectComponents Programmer's Reference (OCF.HLP) Features of Borland C++ Help Programming tips, language details, and library reference IDE tasks, projects, tools BWCC reference Programming and reference material Reference material for DOS Error message descriptions OCF programming and reference ObjectScripting Programmer's Guide (SCRIPT.HLP) ObjectWindows 5.0 Programmer's Reference (OWL.HLP) Script programming and reference Resqurce Script Language Reference (RSL.HLP) Resource Workshop User's Guide (WORKSHOP. HLP) Standard C++ Library Programmer's Reference (STL.HLP) Resource scripting language reference Tools and Utilities (BCTOOLS.HLP) Visual Database Tools Programmer's Reference (BCVDTREF.HLP) Windows System Classes Guide (WINSYS.HLP) WinSight User's Guide (WINSIGill.HLP) WinSpector User's Guide (WINSPECTR.HLP) OWL programming and reference Resource Workshop user's guide and reference Rogue Wave STL user's guide and reference Command-line tools Database reference and developer's guide WinSys classes reference WinSight debugging tool WinSpector post mortem debugging These Help files are all located in the .. \BC5 \ HELP directory. If you want to display one of the specific Help files shown in Table 1.1, you can click on its name whether or not you have opened BC5. Getting Help in Borland C++ In Borland C++, you can get Help in the following ways: • Context-Sensitive Help (F1) • Contents Screens • Index • Keyword Search (F1 or Ctrl+F1 in the Edit Window) Chapter 1, Getting started 17 • SpeedMenus (in the Help window) • Help files Getting context-sensitive Help You can get context-sensitive Help for items in the Borland C++ Integrated Development Environment (IDE). To access context-sensitive Help: 1 Select the element you want help on (menu, menu command, an item in a dialog box. 2 Press F1 or Ctrl+F1. Help buttons are available on many dialog boxes and for most error messages. Click Help to view information about: • The entire dialog box • An error message • The current group of topics in an Options settings dialog box Accessing and using contents screens Each Help Contents offers an entry into a Help system installed with Borland C++. From the Contents, select the category of information that best suits your needs, then click on it. • To display the Master Contents, choose Contents on the Help menu in the Borland C++ IDE. From the Master Contents, you can access all of the Help files. • To access the Help Contents from within a topic in the active Help file, click the Contents tab. • To access the Help Contents of a different Help file installed with Borland C++, rightclick and select the name of the Help file you want to view. To return to a previous topic or Help file, click the Back button. You can expand books that appear on the Contents, or jump directly to a topic. To view a topic, click on it. Using the index In Help, click the Index tab to view a list of index entries. Either type the word you're looking for or scroll through the list. Searching for keywords Keyword Search gives you direct access to Help about a term in your program. To get help on a term: 1 In the Edit window, place the insertion point on the term you want help on. 18 C++ Use r' s G u ide 2 Use one of the following methods: • Press F1 or Ctrl+F1. • Choose Keyword Search on the Help menu. • Choose Go To Help Topic on the Edit Window SpeedMenu. 3 One of these events occurs: • The topic associated with the term you selected is displayed. • If more than one topic is available on the term for which you requested Help, the Topics Found dialog box is displayed listing topics associated with the term. Double-click the topic you want to view. • If no Help is available for the term nearest the insertion point, the index is displayed. You can then select a different searching method to locate a topic associated with that term. The term for which you requested Help appears highlighted in the top box. Click the Display button or double-click the term to view the list of topics associated with the term. To return to a previous topic or Help file, click the Back button. Help SpeedMenus All the Borland c++ Help files have SpeedMenus that you access by right-clicking on the mouse. These menus provide quick access to commands for copying or printing a Help topic, or exiting Windows Help. The SpeedMenu also lists additional Help files containing information related to the current Help file. Right-click and select a Help file from the SpeedMenu. The Contents screen for that Help file is displayed. Using Windows Help More information about using standard Windows Help features is available if you need it. To learn more about the features of Help in Windows 95 and Windows NT, see the following instructions. If you're already in a Help topic, press F1 to display Windows Help. Otherwise, for details about using Help in Windows 95, 1 Choose Start in the lower left comer of the Windows Desktop, then choose Help. Windows Help is displayed. 2 In the Help Contents, open the How To book, then open Use Help. 3 To choose a book in the Help Contents, double-click it or move to it with the arrow keys and press Enter. For details about using Help in Windows NT, choose Help IHow To Use Help in the Program Manager. Chapter 1, Getting started 19 20 'C++ User's Guide Managing projects The Borland C++ IDE contains a Project Manager that gives you a visual representation of the files contained in your project. With the Project Manager, you can see exactly what files you're building, the files you're using in the builds, and the options that you've set for the builds. This chapter covers the following topics, which describe how to use the Project Manager to organize the files in your project: • • • • Project management Using the Project Manager Grouping sets of files with Source Pools Translators, viewers, and tools What is project management?, As your applications grow in size and complexity, you'll discover that your programs become more and more dependent on different intermediate files. In addition, you'll find that some of the modules in your project must be compiled with different compilers or different compiler options. A Windows program, for example, can be composed of resource scripts, import libraries, and source code, with each different file type requiring a different compiler and compiler settings. As the complexity of your projects increase, the need increases for a Way to manage the different components of your projects. By studying the files that make up a project, you can see how a project combines different source files to produce different target files. Target files, for example, can be .DLL or .EXE files. The source files that these targets are dependent upon can consist of files like .C, .CPP, and .H files. Project management is the organization and management of the sources and targets that make up your project. C hap t e r 2, Man a gin 9 Pro j e c t s 21 Using the Project Manager The Project Manager visually organizes all the files in your project using a Project Tree. The Project Tree displays files in a hierarchy diagram. Each level of the hierarchy contains a single target and all the target's dependencies. To show their relationship to the target, dependencies are indented below the target listing. Figure 2.1 shows how the Project window displays a Project Tree. To expand and collapse the hierarchy tree, click nodes containing the + and - symbols. Figure 2.1 The Project window displaying a Project Tree • tEl "repool (.idel------------~ Project node I!!III I- Cl "repool (.lxl] • I-EI "repool [.axe1 Windows 3.1 version Target node EI My Source [SourooPool] ~ Stcpool[.cppJ codetize=35 line$=17 datasize=33 Source node Autodependency [ f11l .. \ .. \ .. \inelude\window".h (AuloDepend) tl'! •. \ .. \ •. \inelude\axept.h [AuloDependj ~ • )( nodes ~ Slcpooi [.Ie] Cl .. \.. \.•\Iib\defaultl.defJ [ K'J cOwl [.obi! Ilfl imporl(.lib) f--------------tl-Run-time tNl. e.tldll (.lib] f-[!J ".epool [.axe) . Win32 version '--EI My Sou.ee (SoureePool] ~D ".epool r.epp) nodes tC! ... C! .. \ .. \ .. \Iib\delault [.del) The Project Manager uses the following types of nodes to distinguish the different types of files in your project: • The project node, located at the top of the Project Tree, represents the entire project. All the files used to build that project appear under the project node (a project node is similar to a symbolic target in a makefile). By default, the project node is not displayed in the Project Tree. To display the project node, choose Options I Environment and select Project View from the list of Topics, then check Show Project Node. • A target node represents a file that is created when its dependent nodes are built (a target is usually an .EXE, .DLL, or .LIB file that you're creating from source code). A project can contain many target nodes. For example, in a single project, you might build an executable file and two separate DLL files, making three targets in all. • Source nodes refer to the files that are used to build a target. Files such as .C, .CPP, and .RC are typical source nodes. • A run-time node refers to files that the Project Manager uses during the linking stage of your project, such as startup code and .LIB files. The Project Manager adds different run-time nodes, depending on the options you specify in TargetExpert. By default, run-time nodes are not displayed by the Project Manager. To view run-time nodes, choose Options I Environment I Project View, then check Show Runtime Nodes. • Autodependency nodes are the files that your program automatically references, such as included header files. By viewing autodependency nodes, you can see the files that source nodes are dependent upon, and you can easily navigate to these files from the Project Manager. By default, autodependency nodes are not displayed in the Project 22 C++ User's Guide Manager. To view autodependency nodes, choose Options IProject IMake, then check Autodependencies: Cache & Display. Note that you must build the project before the Project Manager can display auto dependency information. The Project Manager uses the following color scheme for its nodes: • Blue nodes are those that were added by the programmer. • White nodes indicate project targets. • Yellow nodes are those that were added programmatically by the compiler (when it posts dependencies and Autodependencies), by AppExpert or ClassExpert (when they add .CPP nodes), or by TargetExpert (when it adds nodes based on the target type). The Project Manager uses special glyphs in the left margin to indicate the build attributes of project nodes. To apply build attributes'to a node (and for a reference on the different Project Manager glyphs), choose Edit Local Options from the Project Manager .SpeedMenu, then select the Build Attributes topic. In addition to helping you organize your project files, you can use the Project Manager to access source files and build targets. • To bring a source file into an Edit window, double-click the node in the Project Tree, or highlight the node and either press Enter or choose View IText Edit from the Project ManagerSpeedMenu. • Using the Project Manager to make a project is very effective because you can use the Project Manager to translate only the files that have changed since the last project build; computer resources are not wasted on unnecessary file updates. (The term "translate" refers to using one file type to create another. For example, the C++ compiler is a translator because it generates .OBJ files from .CPP files.) There are several ways to customize the build options of the nodes in your project. Maintaining project options and compiling project targets is described in detail in the following chapter. Project Manager reference The project tree can be traversed with the mouse or the keyboard. Note You can also select a node by typing the node name. Add Node Collapse Hierarchy Collapse node Collapse /EXpand node Copy Node Insert - (hyphen) Minus Spacebar Default action for node Enter Left Click Ctrl+Left Click Drag Double Click Chapter 2, Managing Projects 23 Delete Node Demote a node End node search Expand Hierarchy Expand node Find anode Move down in project Move node down Move node up Move to bottom of hierarchy Move to 'top of hierarchy Move up in project Open SpeedMenu Page down Page up Promote a node Reference Copy Node Scroll left Scroll right Select a node Select Contiguous nodes Select NonContiguous nodes Delete Alt+RightArrow Esc * (asterisk) Plus Incremental search (start typing) DownArrow Alt+DownArrow Left Click Drag Left Click Scroll Bar Alt+UpArrow End Left Click Drag Left Click Drag Scroll Bar Home Scroll Bar UpArrow Alt+FlO Scroll Bar PgDn PgUp Alt+LeftArrow LeftArrow RightArrow Up /DownArrow Shift+UpArrow Right Click Scroll Bar Scroll Bar Alt+Left Click Drag Scroll Bar Scroll Bar Left Click Shift+Left Click Ctrl+Left Click Creating a project When you begin to write a new application, the first step is to create a new project to organize your application's files. The command Project INew Project opens the New Target dialog box. Setting target options with the New Target dialog box When you create a new project, the IDE automatically assigns default file names to the nodes in your project. The following steps show how to change these default settings and how to complete the initial project setup. 1 Type the path and name for the new project into the Project Path And Name input box (the project name must contain eight characters or less). Note that you don't have to type a file extension because the IDE automatically assigns the extension .IDE to all project files. 24 C++ Use r' s G u ide 2 In the Target Name input box, type the name for the first target in your project. This is usually the name of the .EXE or .DLL file that you want to create. Note The remaining fields in the New Target dialog box set the options for the first target in the project. These fields are commonly referred to as the TargetExpert, since these are the fields contained in the TargetExpert dialog box. 3 Choose the type of target you want to build using the Target Type list. For information on the target types, see the online Help for the IDE. Information on using the Help compiler can be found in the online Help file CWH.HLP. 4 Choose a platform for your target using the Platform drop-down list. Information for the individual platform types can be found in online Help. S Select the memory model of the target from the Target Model options: • Tiny, available for only 16-bit DOS applications, sets four segment registers (CS, DS, SS, and ES) to the same starting address, giving you a total of 64K for all your code, data, and stack. • Small uses different code and data segments, giving you near code and near data. .. Medium gives you near data and far code. .. Compact is the inverse of the Medium model, giving you near code and far data. .. Large gives you far code and far data. .. Huge, used with only 16-bit DOS applications, is the same as Large model, but allows more than 64K of static data. .. GUI is used with Win32 CUI applications. .. Console is used with Win32 console applications. Note Windows and DOS programs have different uses for the DS and SS segments. In Windows, they're always the same; however, in DOS these segments are different for Compact, Large, and Huge memory models. The entries in the Target Modelllst adjust according to the Platform type you've selected. 6 Using the Frameworks group, choose the framework to use with your application (the available choices depend on your Platform and Target choices). Frameworks are the class libraries upon which you build your application. Choose any combination of the following libraries for your application: .. Class library isa template-based container class library that uses encapsulation so you can maximize container storage with a minimal amount of reprogramming. When you select this option, TargetExpert links the appropriate BIDSxxx.LIB or BIDSxxx.DLL libraries to your program. .. OWL (Object Windows Library) is an object-oriented class library that encapsulates the behaviors (application-level and window-level) that Windows applications commonly perform. .. OCF consists of Borland ObjectComponents classes for simplifying the creation of OLE applications in C++. ObjectComponents implements a set of high-level interfaces on top of OLE. .. MFC supports Microsoft Foundation Class libraries. Choose 3.0 or 4.0 depending on the version of MFC you are using. Chapter 2, Managing Projects 25 7 Using the Controls options, choose what type of controls your application uses. Borland C++ supports the following types of controls: BWCC (Borland Windows Custom Control Library) is a collection of classes, functions, and bitmap buttons that you can link into your program for an alternative graphical look to standard Windows controls. • VBX allows you to use Visual Basic controls in your applications. This option is available for both 16- and 32-bit Windows applications. • CTL3D lets you use the standard Windows 3-dimensional controls contained in CTL3DV32.DLL. @ 8 TargetExpert displays different library options, depending upon the Target Type and Platform you select. Choose which libraries to add to your project or which standard definitions to use if you are building a static library. .. OLE is an operating system extension that lets applications achieve a high degree of integration. OLE provides a set of standard interfaces so that one OLE program can interact fully with another OLE program. • No exceptions specifies which RTL to link with 16-bit applications. Enable this option if you are building a 16-bit target that you plan to use in a non-C++ environment (such as a .DLL target that will be linked to a Paradox application). • BGI (DOS only) uses the BGI graphics library file for BGI graphics. 9 Compile your program using the following different types of framework libraries: • Dynamic links the dynamic (.DLL) form of the selected libraries. This option allows your application to bind to the standard libraries at run time. The functions in the standard libraries are located in .DLL files rather than directly attached to your application. This greatly reduces the size of an application, but the target is then dependent on the presence of the .DLL libraries at run time. This option forces the large model for 16-bit targets. • Static links the static (.LIB) form of the selected libraries. This option causes the standard library functions to be bound directly to your executable file, creating a larger, standalone executable. If you're building many .DLLs with statically bound RTLs, each .DLL gets its own copy of the routines it uses. Diagnostic links the diagnostic ObjectWindows or Class Libraries. Diagnostic libraries add debug information to the files. A diagnostic version·of these libraries is supplied on the CD version of Borland C++. If you are using the disk version of the product and you select Diagnostic, you must build these libraries. Both OWL and Class Library sources are provided. @ To build a diagnostic version of the libraries, use the following make line: MAKE -DDIAGS Note @ @ 26 See the makefile for other options. Multithreaded links the 32-bit, multithreaded, flat model run-time library. Multithread is available·only if your platform is Win32. Alternate Startup (DOS applications only) links the alternate startup library module COFx.OBJ, which makes SS=DS for all memory models. C++ Use r 's G u ide 10 If needed, click the Advanced button to specify the types of source nodes created with your new target (this procedure is described in the following section). 11 Click OK to accept the settings and close the New Target dialog box. The Project Manager creates the project file, which is denoted with an .IDE extension. When you close the New Target dialog box, the Project Manager draws a graphical representation of your project in the Project window. The Project Manager creates a target node with one or more source nodes below with the project node. After creating the initial target for a project, you can add, delete, or modify the nodes in your project, as described in the following sections. Specifying the source node types The Advanced button in the New Target dialog box opens the Advanced Options dialog box. Use this dialog box to set the types of source nodes that the IDE creates with a new target node. • .CPP Node creates a C+ source node. • .C Node creates a C language source node. • No Source Node creates a target node that doesn't use a source node. Use this option when you do not want to create a source node that uses the same file name as the name of the project. When you create a new target with this option, you must specifically add the source node. If your program is a Windows program, check the following boxes according to the files your target uses: • .RC creates a source node that is associated with a resource script. • .DEF creates a source node that's associated with a Windows definition file. Opening existing projects To open an existing project, choose Project I Open Project, then use the file browser to select an existing .IDE or .PRJ project file (.PRJ files are converted to .IDE files when you save the project). If the project opens, but the Project window is not visible, choose View I Project to access the Project window. Adding source nodes to your project To add a source node to a project: Select any node in the Project Tree under which you want the new node to appear. For example, if you want the new node to appear under the target, select the target node. 2 Press Ins, click the button on the SpeedBar, or right-click the node to open the Project window SpeedMenu, then choose Add Node. 3 Using the file browser, choose the file or files you want associated with the new node. Alternatively, you can type the name of the file you want to add. 4 Choose OK to confirm your settings. C hap t e r 2, Man a gin 9 Pro j e c t s 27 You can use the Windows File Manager to add one or more source hodes. 1 Open the File Manager and arrange the windows so you can still view the Project window in the IDE. 2 In the File Manager, press Gtrl and select the files you want to add as source nodes. 3 Drag the files from the File Manager and drop them on a node in the Project window. The Project Manager automatically adds the source files under the selected node. Deleting source nodes To delete a node in a project, select the node and press Del, or choose Delete Node from the SpeedMenu. To delete many nodes, select the ones you want to delete (press Gtrl or Shift and click the left mouse button to select Il)lultiple nodes), then press Del. The Project Manager asks if you want to delete the nodes before it:proceeds. Adding files without relative path information Because the project tree supports drag and drop, you can copy files right from a desktop file manager. Relative path information is included when files are copied. If you move sources or the IDE, the relative path information will be incorrect. Here is how to add files to your project without the presence of relative path information: • Make sure that Absolute (Options I Project I Make I New Node Path) is turned off (this is the default setting). • Right click on the node under which the added files will become children once they are dropped. • Choose Add Node from the Project Tree SpeedMenu. • Browse and highlight the file(s) you want to add. (Hold down the Gtrlkey to select non-contiguous files.) • After highlighting the desired files, shift focus to the input box and capture to the Clipboard (Gtrl+G). • Browse back to the project file location. • Shift focus to the input box, paste from the Clipboard (Gtrl+ Vor Shift +Insert) and choose OK. Files added to the project by this method do not have relative path information. Editing source node attributes Node attributes describe the node and define the tool that translates it (if applicable). To edit the attributes of a source node: 1 Right-click the source node (or select the node and press Alt+F10), then choose Edit Node Attributes from the SpeedMenu. The Node Attributes dialog box appears. 2 Update the node attributes, then choose OK to confirm your settings. 28 c++ User's Guide Node attributes are defined as follows: • N arne is the file name of the node, without a file extension. • Description is an optional text description of the node. • Style Sheet is the name of the Style Sheet the Project Manager uses when it translates that node. If «None» is specified, the Project Manager uses the option settings in the parent's Style Sheet. • Translator names the translator used on that node. The IDE assigns a default translator for the node type (for example, CppCompile for a .CPP node), which can be overridden using this field. • Node type defines the node extension, which in tum defines the available translators for that node. Adding target nodes to your project To add a target to a project with the New Target dialog box: 1 Choose Project I New Target, or click the button on the SpeedBar. 2 Type the name for the new target, then choose one of the following target types: .. Standard (default) can be an executable, DLL, or other file. • AppExpert is an automatically generated ObjectWindows-based application. • Source Pool is a collection of files that can be referenced in other targets. 3 Choose OK. If the target type is Standard, the TargetExpert dialog box appears so you can further define your target. If the target type is SourcePool, the target is added . to the project and you can add nodes to it immediately. If you choose AppExpert as the target, AppExpert appears. When you add a new target, it is always appended to the end of the Project Tree. To view a sample project with two targets, open the MULTITRG.IDE project in the \BCS\EXAMPLES\IDE\MULTITRG directory. This project file builds a 16-bit and a 32-bit version of the WHELLO program. The project file contains a text file that describes how to use two or more targets in a project. With more than one target in a project, you can choose to build a single target, multiple targets, or the whole project. Deleting target nodes To delete a target node: 1 Right-click the target node you want to delete (or highlight it and press Alt+F10). 2 Choose Delete Node from the SpeedMenu. 3 The Project Manager asks if you're sure you want to delete the target. Choose OK to delete the target and all its dependencies from the project. You can also delete several nodes by pressing Gtrl and clicking the nodes you want to delete, then pres~ Del. C hap t e r 2, Man a gin 9 Pro j e c t s 29 Warning! Use care when deleting target nodes-you cannot undo the deletion. Editing target attributes using TargetExpert Target attributes describe the target. For example, target attributes can describe either a 32-bit Windows DLL or a 16-bit DOS executable. Using TargetExpert, you can modify the attributes for Standard and AppExpert target types. However, you can't change target attributes for Source Pools. To change a target's attributes: 1 In the Project window, right-click the target node (or select it and press Alt+F10), then choose TargetExpert from the SpeedMenu to open the TargetExpert dialog box. Note The TargetExpert fields are a subset of the fields in the New Target dialog box. 2 Update the target attributes, then choose OK to confirm your new settings. Moving nodes within a project You can move nodes within a project in the following ways: • By dragging the node to its new location. • By selecting the node and press Alt and the arrow keys. This moves the selected node up or down through the visible nodes. You can also use Alt and the right and left arrow keys to promote and demote nodes through levels of dependencies. For example, if you have a .CPP file dependent that's on a header file (the .H file appears under and right of the .CPP in the project window), you can move the header file to the same level as the .CPP file by selecting the header file and pressing Alt~. Copying nodes in a project You can copy nodes in your project file either by value or Py reference. When you copy a node by value, the Project Manager places an identical, but separate, copy of the node in the location you specify. The nodes you copy inherit all the attributes from the original node and you have the ability to modify any of the copied node's attributes. When you copy by reference, you simply point to one node from a different location in the project; a reference copy isn't distinct from the original node. If you modify the structure of the original node, the reference copy is also modified. However, a reference copy does not inherit the options of the original node; you're free to attach Style Sheets and override options in the copied node without affecting the original node. To copy a node by vallie: Select the node or nodes you want to copy (press Shift or Ctrl and click to select multiple nodes). You don't need to select the node's dependents because they are copied automatically. 2 Hold down the Ctr! key and drag the selected nodes to where you want to place the complete copies. 30 c++ User's Guide 3 When you release the mouse button, the copied nodes appear. At this point, you can edit either the original or the copied nodes without changing other nodes in the project. To copy a node by reference: Select the node you want to copy by reference. You don't need to select the node's dependents because they are automatically copied by reference. 2 Hold down the Alt key and drag the selected node to where you want to place the reference copy. 3 When you release the mouse button, the reference-copied node appears and is displayed in a lighter font. This helps you remember that the node is copied by reference rather than by value. If you edit the original node (such as adding or deleting dependents), all referenced copies are updated. Warning! You cannot add to, delete, or modify nodes that have been copied by reference; to modify nodes copied by reference, you must edit the master copy. If you delete an original node, all reference copies to that node are also deleted. You cannot undo this deletion. Converting project files into makefiles Using the IDE, you can convert project files (.IDE files) into makefiles, (.MAl< files). To convert a project file to a makefile: 1 Open the project file you want to convert. 2 Choose Project I Generate Makefile. The IDE generates a makefile with the same name as the project file, but with the extension .MAK, and places it in the edit buffer. The IDE displays the new makefile in an Edit window. 3 Choose File I Save to save your new makefile. Customizing the Project window By default, the Project window displays target nodes and source nodes. To'control the display of nodes and options: Choose Options I Environment to open the Environment Options dialog box, then choose Project View. The right side of the dialog box displays the Project View options. 2 Check or uncheck the options you want. A sample node called WHELLO changes as you select or deselect options. This sample shows you how all nodes appear in the Project window. Build translator displays the translator used on the node. o Code size displays the total size of code segments in bytes. This infqgnation appears only after the node has been compiled. . Data size displays the size of the data segment in bytes. This information appears only after the node has been compiled. @ ;& Chapter 2, Managing Projects 31 • Description displays an optional description of the node in the Project Tree. Type the description using the Edit Node Attributes dialog box available from the Pr~ect~anagerSpeed~enu. • Location lists the path to the source file associated with the node. • Name displays the name of the node. • Number of lines displays the number of lines of code in the file associated with the node (note that this appears only after you compile the code). • Node type describes the type of node (for example, .cpp or .c). • Style Sheet names the Style Sheet attached with the node. • Output names the path and file name that's created when the node is translated. For example, a .CPP node creates an .OB} file. e Show runtime nodes displays the nodes the Project ~anager uses when the project is built. For example, it lists startup code and libraries. .. Show project node displays the project node, of which all targets are dependents. 3 Click OK to close the Environment Options dialog box. 4 To save your project customizations, choose Options I Save, then check Project. Note that you can save different option sets with the different projects you work on. Grouping sets of files with Source Pools A Source Pool is a collection of source nodes that can be referenced by multiple target nodes. When a Source Pool is referenced by a target node, the nodes in the Source Pool take on the options and target attributes of the target. Because Source Pools let you create different targets using a common set of source nodes, it's easy to maintain the files that the targets use. For example, with Source Pools, you can create both 16-bit and 32-bit applications using a single set of source nodes. Then, when you add or delete a file from the Source Pool, you don't have to worry about updating all your target nodes; they're updated automatically through the reference to the Source Pool. You can also use Source 1:'ools when you have several header files that you need to include throughout your project. If you place the header files in a Source Pool, you can reference them wherever you need them in your project. Then, you only have to update the original Source Pool when you need to make changes to the group of header files; if you add a new header file to the Source Pool, all the referenced copies are automatically updated. Source Pools are also useful when you want to assign a single Style Sheet to multiple nodes. For example, if three targets in a project need to use the same Style Sheet, you can reference a Source Pool that contains the Style Sheet instead of attaching the same Style Sheet to each individual node. Then, if you need to update the Style Sheet (for example, if you want change from compiling with debug information to compiling without it), you can update all the targets by modifying the single Style Sheet. You can also use Source Pools to apply custom tools to project nodes. For more information, see the example project \BC5\EXA~PLES\IDE\DELIVER. 32 0.+ + Use r' s G u ide Creating a Source Pool When you create a Source Pool, you create a target node with a group of nodes under it. However, the target node of the Source Pool cannot be compiled-to compile the nodes in a Source Pool, you must copy the Source Pool to another target node. Source Pools work to your best advantage when you copy them by reference. 1 In your project, create a new target node by choosing Project I New Target. 2 Type the name of the Source Pool in Target Name. 3 Select SourcePool from the Type list, then press OK to create a Source Pool target node in your project. 4 Select the Source Pool node in the Project Tree, and press Ins to open the Add To Project List dialog box. ' 5 Select the source files you want, then press OK to add them to the Source Pool. 6 Copy the Source Pool by reference by holding down Alt and dragging the Source Pool to the target nodes you want. Note To see a working example of Source Pools, open the sample project called SRCPOOL.IDE in the \BCS\EXAMPLES\IDE\SRCPOOL directory. The project file includes a text file that describes how the Source Pool is used in the example. Translators, viewers, and tools Translators, viewers, and tools are internal and external programs that are available to you through the IDE. ' • Translators are programs that create one file type from another. For example, the C++ compiler is a translator that creates .OBJ files from .CPP files; the linker is a translator that creates .EXE files from .OBJ, .LIB, .DEF, and .RES files. • Viewers are programs that let you examine the contents of a selected node. For example, an editor is a viewer that lets you examine the source code of a .CPP file. Resource Workshop is a viewer for Windows resource files. • Tools are programs that help you create and test your applications. Turbo Debugger and GREP are examples of programming tools. The IDE associates each node in a project with different translators or viewers, depending on the file extension of the node. Although each node can be associated with several different translators or viewers, each node is associated with a single default translator or viewer. This is how the IDE knows to open the Edit window when you double-click a .CPP node (double-clicking a node invokes the default viewer on the node). To see the default node type (determined by file extension) for a specific translator or viewer: 1 Choose Options I Tools to open the Tools dialog box. 2 Select the item you want to inspect from the Tools list. Chapter 2, Managing Projects 33 3 Choose Edit to access the Tools Options dialog box. 4 Choose Advanced to access the Tool Advanced Options dialog box, then inspect the Default For text box. . When you right-click a node, you'll find that some source nodes have a Special command on the SpeedMenu. This command lists the alternative translators that are available for the node type selected. For example, the commands C To Assembler, C++ To Assembler, and Preprocess appear on the Special menu of a .CPP node. The command Implib appears if you selected a .DLL node. Using the Special command, you can invoke any translator that is available for a selected node type. Also, by selecting a source node in the Project Tree and choosing Edit Node Attributes from the SpeedMenu, you can reassign the default translator for the selected node. Adding translators, viewers, and tools to the IDE The Tools dialog box displays the default set of translators, tools, and viewers. The following steps show how to add an item to this list of programs: Choose Options I Tools to access the Tools dialog box. This dialog box displays the default list of translators, tools, and viewers. 2 Choose New to add a new program to the Tools list (to modify a program that's already listed, select the tool, then choose Edit). 3 Set the following options in the Tools Options dialog box: • Name is a description of the item you're adding. This is placed on the Tools list. It Path is the path and executable program name. You can use the Browse button to complete this selection. • Command-line holds any command-line options, transfer macros, and IDE filters you want to pass to the program. For information on transfer macros, refer to online Help. (Try using $prompt if you want to experiment with transfer macros.) IDE filters are .DLL files that let tools interface with the IDE.(for example, the GrepFile tool uses a filter to output text to the Message window). See the FILTER.IDE project in \BCS\EXAMPLES\IDE\FILTER for more information on filters. To see transfer macros and filters in use, choose Options I Tools, then select GrepFiles and choose Edit. • Menu Text appears on SpeedMenus and on the Tools menu. If you want to assign a shortcut key to your menu text, precede the shortcut letter with an ampersandthis letter appears underlined in the menu. For example, &Fi1e assigns F as the shortcut key for File .. If you want an ampersand to appear in your menu text, use two ampersands (&&Up&date appears as &Upgate in the menu). Note III You must supply Menu Text if you want the program item to appear on the SpeedMenu or Tools menu. Help Hint is descriptive text that appears in the status line of the Tools dialog box when you select the program item. 4 Open the Advanced Options dialog box (choose Advanced) to set the options for your new program. Depending on the Tool Type you choose (Simple Transfer, 34 c++ User's Guide Translator, or Viewer), different fields become available. If you create a Translator, the program becomes available for make and build processes. II Place On Tools Menu adds the item to the Tools menu. II Place On SpeedMenu adds a viewer or translator to the associated SpeedMenu. 411 Target Translator, available for translators and viewers. For translators, this field specifies whether the program produces a final target (such as an .EXE file) or an intermediate file (such as an .OBJ or.I file). If you check this box, the translator produces a final target that's saved to the directory you specify in the Final text box (choose Project I Options I Directories). If you don't check Target Translator, the translated file is saved in the directory you specify in the Intermediate text box. III For viewers, Target Translator specifies that the viewer works only on nodes that have been translated (such as .OBJ or .EXE files); the node has to be translated before you can view it. Translate From defines the node types (determined by file extension) that a translator can translate. To specify multiple node types, use a semicolon to separate file extensions. When you enter a file extension in this field, the Project Manager adds the translator to the Special menu of the project nodes that have that file extension. When you choose Special from the Project Manager SpeedMenu, the Project Manager displays all the available translators for that node type. However, it's important that each node type can have only a single, default translator (see the description for Default For). III e e To see how this works, look at the tool CppCompile (choose Options I Tools, double-click CppCompile, then click Advanced). The Tool Advanced Options dialog box shows that the C++ compiler is a translator for .CPP, .C, .CAS, and.H files. If you have a source node with a .C extension, CppCompile appears on the Special menu when you right-click the node and choose Special. Translate To defines the extension of the file that the translator generates. For example, HC31.EXE converts .HPJ files to .HLP, so HC31.EXE holds . hlp in this field. Applies To is similar to the Translate From field, except that it's used for viewers instead of translators. Default For changes the IDE's default translator or viewer for the file types you specify. Type the file extensions (separating each with a semicolon) for the file . types whose default you want to override. 5 Choose OK twice to confirm your settings, then close the Tools dialog box. / Your new tool has now been added to the Tools list of the associated project, and to the Tools menu or SpeedMenu, depending on where you chose to add the item. If you . added the item to the Tools menu, you can check the addition by choosing Tools from the main menu; the new program name appears on the Tools list. Note Although the Project Manager lets you define your own Tools items, these items apply only to the project that you add them to; they aren't added as permanent parts of the IDE. However, translators, viewers, and tools can be passed to new and existing projects. Chapter 2, Managing Projects 35 36 c++ User's Guide Specifying project options and compiling After you create a project file and write the code for the source nodes in your project, you need to set the options for the different project nodes before you can compile the project. This chapter describes how to set options in a project, how to view the options you set, how to compile a projeCt, and how to use the Message window to view and fix compile-time errors. In addition, this chapter contains a complete reference to the compiler and linker options that can be set from the IDE. Setting project options This section explains how to set, view, and manage project options. Project options tell the IDE how to compile and link the nodes in your project to form the targets you need. The settings of the project options can indicate whether or not to generate debugging information, where to look for source code, what types of compiler optimizations you want to use, and so on. The Project Manager lets you set project options in two different ways: • You can attach Style Sheets to your project nodes. • You can override the settings in a Style Sheet using local overrides. Style Sheets group a collection of option settings into a single unit. Once a Style Sheet is created, you can attach it to a node, a group of nodes, or an entire project. Local overrides are settings that take precedence over Style Sheet settings at the node level. C hap t e r 3, S pee i f yin 9 pro j e c top t ion 5 and com p iii n 9 37 Using Style Sheets Often, different project nodes require different option settings. For example, you might want to compile .C files with one set of options and .CPP files with another, or you might want to build one target with debugging information, and another one without it. By applying different Style Sheets to different nodes in your projects, you can easily control how the different nodes get built. In addition, Style Sheets make it easy to view and maintain the settings of your project options. To view the options that can be incorporated into a Style Sheet, open the Project Options dialog box by choosing Options I Project. This dialog box contains a hierarchical list of topics on the left, with the options that relate to each topic listed on the right. To expand and collapse the Topic list, click the + and - icons to the left of the topic listings. To see an example of how Style Sheets are used in a project, open the STYLESHT.lDE project file located in the EXAMPLES \ IDE \ STYLESHT directory of your Borland C++ directory tree. This file uses a different Style Sheet for each of its two versions of WHELLO. The project also contains a text file that explains the use of Style Sheets. Predefined Style Sheets The Project Manager contains several predefined Style Sheets that you can attach to any node in your project. You can also customize a predefined Style Sheet to meet the special needs of your projects. To inspect the predefined Style Sheets, choose Options I Style Sheets. This opens the Style Sheets dialog box, which lists the predefined Style Sheets on the left and a description of the selected Style Sheet on the right. The default project options When you initially create a project, the project inherits the Style Sheet known as the Default Project Options. If you can build all the components in your project with the same options, you can edit this Style Sheet using the Project Options dialog box. However, if different nodes in your project require different option settings, you should override the default option settings by attaching different Style Sheets to the nodes in your project. Warning! Be careful when you use the Options I Project command to modify option settings; if your project contains more than a single target node, the changes you make always modify the project's Default Project Options (regardless of the node you have selected when you choose the command). Because of this, all targets in your project inherit the changes you make when you use the Options I Project command. In addition, if you modify project options when you don't have a project loaded, your modifications update the DefaultProject Options Style Sheet; the projects you later create will inherit these new default settings. If you need to revert to the IDE's factory default settings, delete the file BCWDEF.BCW (located in the \BC5\BINdirectory), then open and close the IDE to create a new file. Managing Style Sheets The buttons at the bottom of the Style Sheets dialog box let you create, compose, copy, edit, rename, and delete user-defined Style Sheets. 38 c++ User's Guide • Create lets you design a new Style Sheet for the currently loaded project. To create a Style Sheet: 1 Choose the Create button, then enter a name for your new Style Sheet into the Create Style Sheet dialog box. Choose OK to add the new Style Sheet to the Available Style Sheets list. 2 Select the new Style Sheet from the Available Style Sheets list, then use the Compose, Copy, or Edit buttons to create your custom Style Sheet. • Compose lets you create a Style Sheet that contains the combined options from one or more Style Sheets. To compose a Style Sheet: 1 Create a new Style Sheet using the Create button. 2 Select the new Style Sheet in the Available Style Sheets list, then click Compose. 3 Select the Style Sheet you want included in your new Style Sheet from the Available Style Sheets list, then move the Style Sheet to the Composite Style Sheets list by double-clicking it or by clicking the ~ button. (You can also remove Style Sheets from the Composite Style Sheet list by selecting a Style Sheet there and clicking ~.) 4 Continue modifying the composed Style Sheet, then choose OK when you're finished. Note You cannot edit the option settings in a composed Style Sheet. However, you can edit the option settings in the Style Sheets contained in the composed Style Sheet, which affects the settings in the composed Style Sheet. • Copy lets you create a new Style Sheet from an existing one. When you choose Copy, you're prompted for the new Style Sheet's name. Enter the new name, then choose OK to make an exact copy of the selected Style Sheet. Copying is a fast way to create a Style Sheet that closely resembles another-you only have to change the options you want. • Edit lets you modify the option settings of an existing Style Sheet, including any predefined Style Sheet. • Rename lets you rename a selected Style Sheet. • Delete lets you remove an unwanted Style Sheet. (This action cannot be reversed.) Attaching Style Sheets to a node To attach a Style Sheet to a project node: 1 Right-click the node in the Project Tree (or select it and press AIt+F10). 2 Choose Edit Node Attributes from the SpeedMenu. The Node Attributes dialog box appears. 3 Select a Style Sheet from the drop-down box, then choose OK. When you attach a Style Sheet to a node, all the child nodes of that node inherit the settings of the selected Style Sheet. To change the settings of a child node, attach a different Style Sheet, or override an option setting using a local override. C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 39 Note Although you can attach only a single Style Sheet to a project node, one Style Sheet can be composed of several different Style Sheets. Sharing Style Sheets between projects When you create a custom Style Sheet, that Style Sheet remains with the project for which it was created; it doesn't get added to the list of predefined Style Sheets. However, if you want a new project to use one of your custom Style Sheets or userdefined tools, you can do so by letting a project inherit the settings of another project.. Before a project can inherit the settings of another project, you must modify the BCW.INI file that resides in your Windows directory. If the file doesn't contain an inherit setting, then you must add tl1.e settings to the file as follows: [Project] iTo have new projects inherit settings from the Default Project Settings (default) : inherit=O iTo have new projects inherit settings from currently open project: inherit=l iTo have new projects inherit factory default settings: inherit=2 To pass Style Sheets or user-defined tools from one project to a new project: Modify BCW.INI so that inherit=l. 2 Open the project that contains the Style Sheet or tools you want to share. 3 Choose Project I New Project. When the new project is created, it inherits the Style Sheets and user-defined tools of the project that was open when you choose Project I New Project. Project Description Language files . You can also use Project Description Language (.PDL) files to share Style Sheets and tools between projects. When you save a project, you can instruct the IDE to create a .PDL file that has the same file name as the project's .IDE file. Likewise, when you open a project, you can instruct the IDE to read the project's .PDL file. Because a .PDL file contains information about the Style Sheets and tools used in a project, you can edit a project's .PDL file so that it uses the Style Sheets and tools of your choosing. However, care must be taken whenever you edit a .PDL file-it's easy to corrupt the file to the point where the Project Manager can't read it. If you plan to use .PDL files to share Style Sheets and tools, you must first ensure that the IDE creates and reads the files. To do so, open the BCW.INI file (found in your Windows directory) and add the following settings to the [Project] section of the .INI file: [Project]saveastext=l readastext=l 40 c++ User's Guide The saveastext setting tells the IDE to save a .PDL file whenever a project is saved. The readastext setting tells the IDE to update an .IDE file if its associated .PDL file is newer than the .IDE file. To share Style Sheets or user-defined tools between projects: 1 Modify your BCW.INI file as just described. 2 Open the project that you need to transfer Style Sheets or tools to, then close the project (choose Project I Close Project). This creates a .PDL file for the project. 3 Open the project that contains the Style Sheets or tools you want to share, then close the project to save the current settings in the .PDL file. 4 Using a text editor, open the .PDL file containing the Style Sheet or tools you want to share (the .PDL file name matches the file name of the .IDE file). 5 Search for the Style Sheet's name. For example, if you created a Style Sheet cailed MYSTYLE, you'll see a section in the .PDL file that starts { StyleSheet = "MYSTYLE". 6 Copy all the text from the beginning brace to the ending brace. If needed, you can copy more than a single Style Sheet. Note To share a user-defined tool, copy the section that reads Subsystem= . 7 Open the .PDL file that is to receive the Style Sheet. S Find the section for Style Sheets, then paste the copied text to the end of the existing Style Sheet list. 9 Save the .PDL file that received the copied Style Sheet. 10 Open the project that received the copied Style Sheet to update the project's Style Sheets and tools from the .PDL file. After transferring Style Sheets, it's a good idea to reset the saveastext and the readastext flags in the BCW.IN! file to o. This tells the IDE to not save to or update from .PDL files. Setting local overrides Option settings can be overridden at the node level using local overrides. Local overrides are useful when anode's option settings must differ from its associated Style Sheet by one or two settings. Note Although local overrides make it easy to set options for individual nodes, they have the disadvantage of being difficult to track. While the Options Hierarchy dialog box displays the Style Sheet and local override settings for a selected node, you must examine each individual node to see which ones have been overridden. Because of this, it's recommended that you use separate Style Sheets for nodes that require different option settings, and use local overrides only in special cases. To override an option setting: 1 Choose the node whose settings you want to override. 2 Right-click the node (or press Alt+F10) and choose Edit Local Options from the SpeedMenu. The Options dialog box (which is similar to the Project Options dialog box) appears and displays the settings for that node . . C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 41 3 Select the option you want to override. The IDE automatically checks the Local Override box whenever you modify a Style Sheet setting. 4 Choose OK to confirm your new settings. Warning! The Local Override check box is enabled only when an option within a topic is selected; otherwise, the check box is grayed. When you select an option (using Tab, or by clicking and dragging the mouse off the option), the Local Override check box shows the status of the selected option. Because of this, you must individually select each option in a topic to see which ones have been overridden locally. If you choose an option (by clicking it, or by selecting it and pressing Enter), you change its setting, which always causes the Local Override check box to be checked. To undo an override: 1 Right-click the node whose setting you want to modify, then choose Edit Local Options from the SpeedMenu. 2 In the Options dialog box,' select the topic that contains the overridden setting. When you select a topic page that has a locally overridden option, the Project Manager enables the Undo Page button. 3 Select the option (using Tab, or by clicking and dragging the mouse off the option) whose local override you want to undo; the Local Override check box will be checked. 4 Click the-Local Override check box to undo the override; the option will revert to its default Style Sheet setting. To revert the entire topic to the settings contained in the associated Style Sheet, choose the Undo Page button. S Choose OK to confirm your modifications. Viewing project options Because each node can have its own Style Sheet and you can override the options in the Style Sheet, you need a quick way to view the option settings for each node. To view option settings for the nodes in your project: 1 Right-click any node in the Project window and choose View Options Hierarchy, or click the button on the SpeedBar. The Options Hierarchy dialog box appears, listing the nodes in the project on the left and the options that each node uses on the right. You can expand and collapse the list of nodes in the dialog box just like you can in the Project window, however, Autodependency nodes don't appear. An option that's surrounded by double-asterisks (**) in the Options listing indicates that the option is overridden (by either a Style Sheet or local override) by a dependent node located farther down in the Options listing. (The asterisks display only when you select the node where the option is overridden.) 2 When you select a node in the Project Options At list, its settings appear to the right in the Options list. 42 c++ User's Guide The Options list displays components of the project in square brackets. At the top of the list, you'll see the name of the project followed by its Default Project Options. Below this is the name of the target associated with the node you've selected. If the node has a Style Sheet associated with it, it's displayed beneath the node (also in brackets), along with the settings of the Style Sheet. If you've overridden any settings, these are displayed beneath the [Node overrides] listing. The Options list displays the settings for all the,ancestors of the node selected in the Project Tree. 3 If you want to edit an option, double-click the option in the Option list, or select it and click Edit.Whenever you edit options in this manner, the modifications become local overrides. 4 When you finish viewing your project's option settings, choose Close. Compiling projects There are two basic ways to compile projects: build and make. Build compiles and links all the nodes in a project, regardless of file dates. Make compares the time stamp of the target with the time stamps of all the files used to build the target. Make then compiles and links only those nodes necessary to bring the target up to date. To compile a project, open the project using the Project IOpen command, then choose one Compile, Make All, or Build All from the Project menu (note that the SpeedBar has three similar looking buttons that correspond to these Project Menu commands). • Compile (Alt+F9) builds the code in the currently active Edit window. If a Project window is selected, all the selected nodes in the project are translated; child nodes aren't translated unless they're selected. • Make All (F9) translates all the out-of-date nodes in a project. If a project is not open, the file contained in the active Edit window buffer is built. When you choose Make All, the Project Manager moves down the Project Tree until it finds a node with no dependents. The Project Manager then compares that node's date and time against the date and time of the node's parent. The Project Manager translates the node only if the child node is newer than the parent node. The Project Manager then moves up the Project Tree and checks the next node's date and time. In this way, the Project Manager recurses through the Project Tree, translating only those nodes that have been updated since the last compile. • Build All translates all nodes in a project-even if they are up-to-date. Build All always starts at the project node and builds each successive target down the project. Choose Cancel to stop a build. When you choose Build All, the Project Manager starts at the first target and works down the Project Tree until it comes to a node with no dependents. The Project Manager compiles that node first (and other nodes on the same level), then works back up the Project Tree, compiling and linking all the nodes needed to create the target. This process is then repeated down the Project Tree, until all the targets have been updated; For example, if you have a project with an .EXE target that is dependent on two separate .OBI files, the Project Manager creates the first .OBI file by compiling all its dependents. It then creates the next .OBI file. Once a target node's dependents are Chapter 3, Specifying project options and compiling 43 created, it can compile or link the target node. In this case, the Project Manager will link the two .OBJ files (and any run-time nodes) to create the final .EXE. Compiling part of a project There are several ways to compile specific parts of a project. You can • • • • Translate an individual node Build a node and its dependents Make a node and its dependents Select several nodes and compile To translate an individual node: 1 Select the node you want to translate. 2 Choose Project ICompile from the main-menu or choose the default translation command from the SpeedMenu. For example, if you've selected a .CPP file, the node SpeedMenu contains the command C++ Compile, which compiles only the selected node. To build a node and its dependents: 1 Select the node you want to build. 2 Right-click the node (or press Alt+F10) and choose Build Node from the SpeedMenu. All the dependent nodes are built regardless of whether they're out-of-date. To make a node and its dependents: 1 Select the node you want to build. 2 Right-click the node (or press Alt+F10) and choose Make Node from the SpeedMenu. This command compiles only the dependent nodes whose source files are newer than their associated target files. To compile several selected nodes: 1 Select the project nodes you want to compile by pressing etrl and clicking the desired project nodes. (The nodes must be of the same file type, such as .CPP). 2 Choose Make Node or Build Node from the Project Manager SpeedMenu to compile the selected nodes. Fixing compile-time errors Compile-time errors, or syntax errors, occur when your code violates a syntax rule of the language you're programming in; the C++ compiler cannot compile your program unless it contains valid language statements. If the compiler encounters a syntax error while compiling your code, the Message window opens and displays the type of error or warning it encountered. By choosing Options IEnvironment IPreferences, you can specify if old messages should be preserved or deleted between calls to different 44 e++ User's Guide programming tools (such as a compiler, GREP, or the resource compiler). Check Save Old Messages if you want the Message window to retain its current listing of messages when you run a tool. To clear the Message window, choose Remove All Messages from the Message window SpeedMenu. Viewing errors To view the code that caused a compiler error or warning, select the message in the Message window; the IDE updates the Edit window so that it displays the location in your code where the error or warning occurred (this is called Automatic Error Tracking). If the file containing the error isn't loaded in an Edit window, press Spacebar to load the file (you can also load the file by pressing Alt+F10, then choosing View Source from the SpeedMenu). When you view errors in this manner, the Message window remains selected so you can navigate from message to message.To open or view the Message window, click the button on the SpeedMenu, or choose View I Message. Fixing errors To edit the code associated with an error or warning, do one of the following: • Double-click the messagein the Message window. • Select the message in the Message window and press Enter. • Press Alt+F10 and choose Edit Source from the SpeedMenu. The Edit window gains focus with the insertion point placed on the line and column in your source code where the compiler detected the error. From here, edit your code to fix the error. After fixing the error, press Alt+F7to move to the next error message in the list or press Alt+FB to go back to the previous message. Project options reference You set compiler, linker, librarian, and make options from two different places in the IDE: the Project Options multiple-page dialog box and TargetExpert. The remainder of this chapter describes the options available in the Project Options dialog box. They are described in alphabetical order. i6-bit compiler options The 16-bit Compiler options affect the compilation of all 16-bit source modules. It is usually best to keep· the default setting for most options in this section. Calling Conventions Calling Convention options tell the compiler which calling sequences to generate for function calls. The C, Pascal, and Register calling conventions differ in the way each handles stack cleanup, order of parameters, case, and prefix of global identifiers. Chapter 3, Specifying project options and compiling 45 You can use the __cdecl, __pascal, or __fastcall keywords to override the default 'calling convention on specific functions. Note These options should be used by experts only. C Command-line equivalent: -pc, -pThis option tells the compiler to generate a C calling sequence for function calls (generate underbars, case sensitive, push parameters right to left). This is the same as declaring all subroutines and functions with the __cdecl keyword. Functions declared using the C calling convention can take a variable parameter list (the number of parameters does not need to be fixed). Pascal Command-line equivalent:-p This option tells the compiler to generate a Pascal calling sequence for function calls (do not generate underbars, all uppercase, calling function cleans stack, pushes parameters left to right). This is the same as declaring all subroutines and functions with the __pascal keyword. The resulting function calls are usually smaller and faster than those made with the C (-pc) calling convention. Functions must pass the correct number and type of arguments. Register Command-line equivalent: -pr This option forces the compiler to generate all subroutines and all functions using the Register parameter-passing convention, which is equivalent to declaring all subroutines and functions with the __fastcall keyword. With this option enabled, functions or routines expect parameters to be passed in registers. Default = C (-pc) Entry/Exit code These options specify which type of prolog and epilog code the compiler generates for each module's functions. Note Although these options are listed in the 16-bit compiler section, they also apply to 32-bit programs. Windows all functions exportable Command-line equivalent: -tW This option creates a Windows object function prolog/ epilog for all __far functions, then sets up those functions to be called from another module. This option assumes that all functions can be called by the Windows kernel or by other modules and generates 46 c++ User's Guide the necessary overhead mformation for every __far function (whether the function needs it or not). To export the function address from the .EXE to a .DLL, the code includes a call to MakeProcInstanceO, passing the resulting pointer to the .DLL that requested the address of the function. For the function to be exportable, the function must be declared as _export or the function name must be included in the .DEF file of the executable. This option creates the most general Windows executable, but not necessarily the most efficient. Note The -W command-line option is supported for backward compatibility, and is equivalent to -tWo Default = ON Windows explicit functions exported Command-line equivalent: -tWE This option creates a Windows object module in which only __far functions dedared as _export functions are exportable. Use this option if you have functions that will not be called by the Windows kernel. Windows Explicit Functions Exported operates the same as Windows All Functions Exportable except that only those functions marked with the _export keyword (and methods of classes marked as _export) are given the extra prolog/ epilog. This option is far more efficient than Windows All Functions Exportable, since only those functions called from outside the module get the prolog overhead. This option requires that you determine in advance which functions or classes need to be exported. MakeProcInstanceO is still used, but no .DEF file manipulation is needed (if you use this option along with _export, you don't need to define exports in your .DEF files). Note The -WE command-line option is supported for backward compatibility, and is equivalent to -tWE. Default = OFF Windows smart callbacks, all functions exportable Command-line equivalent: -tWS This option creates an object module with smart callbacks for all __far functions exported. Use this option only if the compiler can assume that D5 == 55 for all functions in the module (which is true for the vast majority of Windows programs and the default for Borland tools). Tllis option creates a Windows .EXE function prolog/ epilog for all __far functions and sets them up to be called from another module. MakeProcInstanceO does not need to be called and you do not need to edit the .DEF file. Note The -WS command-line option is supported for backward compatibility, and is equivalent to -tWS. " Default = OFF C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 47 Windows smart callbacks,explicit functions exportable Command-line equivalent: -tWSE This option is the same as Windows Smart Callbacks except that only those functions marked with the _export keyword (and methods of classes marked as _export) are given the extra prolog/ epilog. This is efficient since only those functions called from outside the module get the prolog overhead. This option requires determining in advance which functions / classes need to be exported. Note The -WSE command-line option is supported for backward compatibility, and is equivalent to -tWSE. Oefault = OFF Windows DLL, all functions exportable Command-line equivalent: -tWD This option creates a Windows .OLL function prolog/ epilog for all __far functions, then sets up those functions to be called from another module. To actually export function addresses from the .OLL, the functions must be marked with the _export keyword or the function names need to be included in the .OEF file of the executable. Note The -WD command-line option is supported for backward compatibility, and is equivalent to -tWD. Oefault = OFF Windows DLL, explicit functions exported Command-line equivalent: -tWDE This option is the same as Windows OLL, All Functions Exportable except that only __far functions marked with the _export keyword (and methods of classes marked as _export) are given the extra prolog/ epilog. This is far more efficient than the Windows OLL, All Functions Exportable option since only those functions called from outside the module get the prolog overhead. This option requires determining which functions or classes need to be exported in advance. No .DEF file manipulation is needed. Note The -WDE command-line option is supported for backward compatibility, and is equivalent to -tWDE. Oefault = OFF Memory model The Memory Model section lets you specify the organization of segments for code and data in your 16-bit programs. (32-bit programs always use the flat memory model.) Large is the most common memory model used for Windows programs. All .OBJ and .LIB files in your program should be compiled in the same memory model. 48 c++ User's Guide Assume SS equals DS The Assume SS Equals DS options specify how the compiler considers the stack segment (SS) and the data segment (DS). Always (DOS only) Command-line equivalent: -Fs The compiler always assumes that SS is equal to DS in all memory models. This option causes the compiler to use the alternate COFx.OBJ startup module (which places the stack in the data segment) instead ofCOx.OBJ. You can use this option when porting code originally written for an implementation that makes the stack part of the data segment. Default = Default for Memory Model Default for memory model The memory model you use determines whether the stack segment (SS) is equal to the data segment (DS). Usually, the compiler assumes that SS is equal to DS in the small and medium memory models (except for DLLs). Never Command-line equivalent: -Fs- The compiler assumes that the SS is never equal to DS. This is always the case in the compact and large memory models and when building a Windows DLL. Automatic far data Command-line equivalent: -Ff When the Automatic Far Data option is enabled, the compiler automatically places data objects larger than or equal to the threshold size into far data segments. The threshold size defaults to 32,767. This option is useful for code that doesn't use the huge memory model, but declares enough large global variables that their total size is close to or exceeds 64K. This option has no effect for programs that use tiny, small, and medium memory models. . When thIs option is disabled, the size value is ignored This option and the Far Data Threshold input box work together. The Far Data Threshold specifies the minimum size above which data objects will be automatically made far. If you use this option with the Generate COMDEFs option (-Fe), the COMDEFs become far in the compact, large, and huge models. Default = OFF The command-line option -Fm enables all the other -F options (-Fe, -Ff, and -Fs). You can use -Fm as a handy shortcut when porting code from other compilers. To do this in the IDE, check the Automatic Far Data and Always options on this Project Options page, and the Generate COMDEFs option on the Compiler I Floating Point page. C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 49 Far data threshold Command-line equivalent: -Ff=size, where size = threshold size Use Far Data Threshold to specify the size portion needed to complete the Automatic Far Data option. Default = 32767 (if Automatic Far Data is disabled, this option value is ignored) Far virtual tables Command-line equivalent: -Vf When you tum this option on, the compiler creates virtual tables in the code segment instead of the data segment, unless you override this option using the Far Virtual Tables Segment (-zV) or Far Virtual Tables Class (-zW) options. Virtual table pointers are made into full 32-bit pointers (which is done automatically if you are using the huge memory model). You can use Far Virtual Tables to remove the virtual tables from the data segment (which might be getting full). You might also use this option to share objects (of classes with virtual functions) between modules that use different data segments (for example, a DLL and an executable that uses that DLL). You must compile all modules that might share objects entirely with or entirely without this option. Note that you can get the same effect by using the huge or _export modifiers on a class-by-class basis. This option changes the mangled names of C++ objects. Default = OFF Fast huge painters Cokmand-line equivalent: -h This option offers an alternative method of calculating huge pointer expressions. This option behaves differently for DOS and Windows programs. For Windows programs, huge pointers are normalized by the value of the variable _ALTINCR, which is initialized by Windows at the startup time of the application. For DOS programs, this option offers a faster method of "normalizing" than the standard method. (Normalizing is resolving a memory address so that the offset is always less than 16.) When you use this option, huge pOinters are normalized only when a segment wraparound occurs in the offset part, which causes problems with huge arrays if an array element crosses a segment boundary. Usually, Borland C++ normalizes a huge pointer whenever adding or subtracting from it. This ensures, for example, that if you have an array of structs that's larger than 64K, indexing into the array and selecting a struct field always works with structs of any size. Borland C++ accomplishes this by always normalizing the results of huge pointer operations-the address offset contains a number that is no higher than 15 and a segment wraparound never occurs with huge pointers. The disadvantage of this approach is that it tends to be quite expensive in terms of execution speed. 50 c++ User's Guide Default = OFF Model The Model options specify the memory model you want to use. The memory model you choose determines the default method of memory addressing. Compact Command-line equivalent: -me Use the compact model if your code is small but you need to address a lot of data. The Compact model is the opposite of the medium model: far pointers are used for data but not for code; code is limited to 64K; pointers can point almost anywhere. All functions are near by default and all data pointers are far by default. Huge Command-line equivalent: -mh, DOS only Use the huge model for very large applications only. Far pointers are used for both code and data. Borland C++ normally limits the size of all static data to 64K; the huge memory model sets aside that limit, allowing data to occupy more than 64K. Default = Large in IDE; Small in BCC.EXE Large Command-line equivalent: -ml Use the large model for very large applications only. Far pointers are used for both code and data. Data is limited to 1MB. Far pointers can point almost anywhere. All functions and data pointers are far by default. Medium Command-line equivalent: -mm Use the medium model for large programs that do not keep much data in memory. Far pointers are used.for code but not for data. Data and stack together are limited to 64K, but code can occupy up to 1MB. . The -mm! command-line option compiles using the medium model and assumes DS != SS. To achieve this in the IDE, you need to check both the Medium and Never options. Note The net effect of the -ms! and -mm! options is actually very small. If you take the address of a stack variable (parameter or auto), the default (DS == SS) is to make the resulting pointer a near (DS relative) pointer. This way, you can assign the address to a defaultsized pointer in those models without problems. When DS != SS, the pointer type created when you take the address of a stack variable is an _ss pointer. This means that the pointer can be freely assigned or passed to a far pointer or to an _ss pointer. But for the memory models affected, assigning the address to a near or default-sized pointer produces a "Suspicious pointer conversion" warning. Such warnings are usually errors. C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 51 Small Command-line equivalent: -ms Use the small model for average size applications. The code and data segments are different and don't overlap, so you have 64K of code and 64K of data and stack. Near pointers are always used. The -ms! command-line option compiles using the small model and assumes DS != SS. To achieve this in the IDE, you need to check both the Small and Never options. Tiny Command-line equivalent: -mt ,DOS only This is the smallest of the memory models. Use this model when memory is at an absolute premium. All four segment registers (CS, DS, SS, ES) are set to the same address. You have a total of 64K for all of your code, data, and stack. Near pointers are always used. Tiny model programs can be converted to .COM format by linking with the It option. Put constant strings in code segments Command-line equivalent: -de This option moves all string literals from the data segment to the code segment of the generated object file, making the data type eonst. Note Use this option only with compact or large memory models. In addition, this option does not work with overlays. Using this option saves data segment space. In large programs, especially those with a large number of literal strings, this option shifts the burden from the data segment to the code segment. Default = OFF Processor The Processor options let you specify the minimum CPU type compatible with your program. These options introduce instructions specific to the CPU type you select to increase performance. 16-bit instruction set The Instruction Set options specify for which CPU instruction set the compiler should generate code. 80186 Command-line equivalent: -1 Choose the 80186 option if you want the compiler to generate extended 16-bit code for the 80186 instruction set. Also supports the 80286 running in Real mode. 52 C++ Use r s Gu ide f 80286 Command-line equivalent: -2 Choose the 80286 option if you want the compiler to generate 16-bit code for the 80286 protected-mode-compatible instruction set. 80386 Command-line equivalent: -3 Choose the 80386 option if you want the compiler to generate 16-bit code for the 80386 protected-mode-compatible instruction set. 8086 Command-line equivalent: -1Choose the 8086 option if you want the compiler to generate 16-bit code for the 8086compatible instruction set. (To generate 8086 code, you must not turn on the options -2, -3, -4, or -5.) i486 Command-line equivalent: -4 Choose the i486 option if you want the compiler to generate 80386/i486 instructions running in enhanced-mode Windows. Default = 8086 (-1-) Data alignment The Data Alignment options let you choose how the compiler aligns data in stored memory. Word, double-word, and quad-word alignment force integer-size and larger items to be aligned on memory addresses that are a multiple of the type chosen. Extra bytes are inserted in structures to ensure that members align correctly. Byte alignment Command-line equivalent: -a1 or -aWhen Byte Alignment is turned on, the compiler does not force alignment of variables or data fields to any specific memory boundaries; the compiler aligns data at either even or odd addresses, depending on which is the next available address. While byte-wise alignment produces more compact programs, the programs tend to run a bit slower. The other data alignment options increase the speed that 80x86 processors fetch and store data. Double word (4-byte) Command-line equivalent: -a4, 32-bit only Double Word alignment aligns non-character data at 32-bit word (4-byte) boundaries. Chapter 3, Specifying project options and compiling 53 Quad word (a-byte) Command-line equivalent: -as, 32-bit only Quad Word alignment aligns non-character data at 64-bit word (8-byte) boundaries. Default = Byte Alignment (-a-) Word alignment (2-byte) Command-line equivalent: -a2 When Word Alignment is on, the compiler aligns non-character data at even addresses. Automatic and global variables are aligned properly. char and unsigned char variables and fields can be placed at any address; all others are placed at an even-numbered address. Segment names code Segment Names Code options let you specify a new code segment name and reassign the group and class. Code Use Code to change the name of the code segment as well as the code group and class. In all options, use an asterisk (*) for name to select the default segment names. Note Do not change the settings in this dialog box unless you are an expert. Code class Command-line equivalent = -zAname Changes the name of the code segment class to name. By default, the code segment is assigned to class CODE. Default = * (default segment name) for all options Code group Command-line equivalent = -zPname Causes any output files to be generated with a code group for the code segment named name. Code segment Command-line equivalent = -zCname Sets the name of the code segment to name. By default, the code segment is named _CODE for near code and modulename_TEXT for far code, except for the medium and large models where the name is filename_CODE (filename is the source file name). 54 c++ User's Guide Segment names data Use Segment Names Data to change the default segment, group, and class names for initialized and uninitialized data. Note Do not change the settings in this dialog box unless you have a good understanding of segmentation on the 80x86 processor. Under normal circumstances, you do not need to specify segment names. Initialized Data Use Initialized Data to change the default segment, group, and class names for initialized data. In all options, use an asterisk (*) for name to select the default segment names. Note Do not change the settings in this dialog box unless you have a good understanding of segmentation on the 80x86 processor. Under normal circumstances, you do not need to specify segment names. Initialized data class Command-line equivalent = -zTname Sets the name of the initialized data segment to name. By default, the initialized data segment class is named DATA. Default = * (default segment name) for all options Initialized data group Command-line equivalent = -zSname Sets the name of the initialized data segment group to name. By default, the data group is named DGROUP. Initialized data segment Command-line equivalent = -zRname Sets the name of the initialized data segment to name. By default, the initialized data segment is named _DATA for near data and modulename_DATA for far data. Uninitialized data Use Uninitialized Data to change the default segment, group, and class names for code uninitialized data. In all options, use an asterisk (*) for name to select the default segment names. Note Do not change the settings in this dialog box unless you have a good understanding of segmentation on the 80x86 processor. Under normal circumstances, you do not need to specify segment names. Chapter 3, Specifying project options and compiling 55 Un initialized data (BSS class) Command-line equivalent = -zBname Sets the name of the uninitialized data segment class to name. By default, the uninitialized data segments are assigned to class BSS. Default = * (default segment name) for all options Uninitialized data (BSS group) Command-line equivalent = -zGname Sets the name of the uninitialized data segment group to name. By default, the data group is named DGROUP. Uninitialized data (BSS segment) Command-line equivalent = -zDname Sets the name of the uninitialized data segment. By default, the uninitialized data segment is named _BSS for near uninitialized data and modulename_BSS for far uninitialized data. Segment names far data 16-bit Compiler ISegment Names Far Data options set the far data segment name, group, class name, and the far virtual tables segment name and class. Far data Use Far Data to change the default segment, group, and class names for far data. In all options, use an asterisk (*) for name to select the default segment names. Note Do not change the settings in this dialog box unless you have a good understanding of segmentation on the 80x86 processor. Under normal circumstances, you do not need to specify segment names. Far data class Command-line equivalent = -zFname Sets the name of the class for __far objects to name. By default, the name is FAR_DATA. Default = * (default segment name) for all options Far data group Command-line equivalent = -zHname Causes __far objects to be placed into the group name. By default, far objects are not placed into a group. Far data segment Command-line equivalent = -zEname 56 c++ User's Guide Sets the name of the segment where __far objects are placed to name. By default, the segment name is the name of the far object followed by _DATA. Far virtual tables Use Far Virtual Tables to change the default segment and class names virtual tables. In all options, use an asterisk (*) for name to select the default segment names. Note Do not change the settings in this dialog box unless you have a good understanding of segmentation on the 80x86 processor. Under normal circumstances, you do not need to specify segment names. Virtual table class Command-line equivalent = -zWname Sets the name of the far virtual table class segment to name. By default, far virtual table classes are generated in the CODE segment. Default = * (default segment name) for all options Virtual table segment Command-line equivalent = -zVname Sets the name of the __far virtual table segment to name. By default, far virtual tables are generated in the CODE segment. 32·bit compiler options The 32-bit Compiler page contains two radio buttons that allow you to select which 32-bit compiler you want to use when compiling 32-bit applications. Use Borland optimizing compiler The Borland optimizing compiler is a faster compiler than the Intel compiler and it produces smaller executable files. Use Intel optimizing compiler The Intel optimizing compiler produces faster executable files than does the Borland compiler at the expense of slower cpmpilation times and slightly larger executable file sizes. 32·bit compiler options 32-bit Compiler options listed on the Processor and Calling Convention pages affect the compilation of all 32-bit Windows applications for Windows NT and Windows 95. C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 57 Because 32-bit programs use a flat memory model (they are not segmented), there are fewer options to configure than for 16-bit programs. Calling conventions Calling Convention options tell the compiler which calling sequences to generate for function calls. The C, Pascal, and Register calling conventions differ in the way each handles stack cleanup, order of parameters, case, and prefix of global identifiers. You can use the __cded, __pascal, __fastcall, or __stdcall keywords to override the default calling convention on specific functions. Note These options should be used by experts only. C Command-line equivalent: -pc, -pThis option tells the compiler to generate a C calling sequence for function calls (generate underbars, case sensitive, push parameters right to left). This is the same as declaring all subroutines and functions with the __cded keyword. Functions declared using the C calling convention can take a variable parameter list (the number of parameters does not need to be fixed). You can use the __pascal, __fastcall, or __stdcall keywords to specifically declare a function or subroutine using another calling convention. Pascal Command-line equivalent: -p This option tells the compiler to generate a Pascal calling sequence for function calls (do not generate underbars, all uppercase, calling function cleans stack, pushes parameters left to right). This is the same as declaring all subroutines and functions with the __pascal keyword. The resulting function calls are usually smaller and faster than those made with the C (-pc) calling convention. Functions must pass the correct number and type of arguments. You can use the __cded, __fastcall, or __stdcall keywords to specifically declare a function or subroutine using another calling convention. Register Command-line equivalent: -pr This option forces the compiler to generate all subroutines and all functions using the Register parameter-passing convention, which is equivalent to declaring all subroutines and functions with the __fastcall keyword. With this option enabled, functions or routines expect parameters to be passed in registers. You can use the__pascal, __cded, or __stdcall keywords to specifically declare a function or subroutine using another calling convention. Standard Call (32-bit compiler only) Command-line equivalent: -ps 58 c++ User's Guide This option tells the compiler to generate a Stdcall calling sequence for function calls (does not generate underscores, preserve case, called function pops the stack, and pushes parameters right to left). This is the same as declaring all subroutines and functions with the __stdcall keyword. Functions must pass the correct number and type of arguments. You can use the __cdecl, __pascal, __fastcall keywords to specifically declare a function or subroutine using another calling convention. Default = C (-pc) Processor 32-bit Compiler Processor options specify which CPU instruction set to use and how to handle floating-point code for 32-bit programs. 32·bit instruction set The Instruction Set options specify for which CPU instruction set the compiler should generate code. 80386 Command-line equivalent: -3 Choose the 80386 option if you want the compiler to generate 80386 protected-modecompatible instructions running on Windows 95 or Windows NT. i486 Command-line equivalent: -4 Choose the i486 option if you want the compiler to generate i486 protected-modecompatible instructions running on Windows 95 or Windows NT. Pentium Command-line equivalent: -5 Choose the Pentium option if you want the compiler to generate Pentium instructions on Windows 95 or Windows NT. While this option increases the speed at which the application runs on Pentium machines, expect the program to be a bit larger than when compiled with the 80386 or i486 options. In addition, Pentium-compiled code will sustain a performance hit on non-Pentium systems. Pentium Pro Command-line equivalent: -6 Choose the Pentium Pro option if you want the compiler to generate Pentium Pro instructions running on Windows 95 or Windows NT. C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 59 Note This option is valid only if you are using the 32-bit Intel compiler (choose 32-bit Compiler I Intel Optimizing Compiler in the Project Options dialog box or use the BCC32i.EXE command-line compiler). Default = 80386 (-3) Build Attributes options Build attributes affect whether or not a node is built during compilation. The icons associated with each of these options are displayed next to the nodes in the Project hierarchy diagram. Note This set of options is not available for an AppExpert project. Always build Check Always Build and the node is always built, even if it has not changed. Build when out of date Check Build When Out of Date and the node is built only if it has changed. Can't build Check Can't Build to be notified when a node cannot be built. Exclude from parent Check Exclude from Parent and the system indicates when a node should be excluded from parent (such as with source pools). Never build Check Never Build and the node is not built. c++ options C++ Options affect compilation of all C and C++ programs. For most options in this section, you usually want to keep the default settings. 60 c++ User's Guide c++ compatibility Use the C++ Compatibility options to handle C++ compatibility issues, such as handling 'char' types, specifying options about hidden pointers, passing class arguments, adding hidden members and code to a derived class, passing the 'this' pointer to 'Pascal' member functions, changing the layout of classes, or insuring compatibility when class instances are shared with non-C++ code or code compiled with previous versions of Borland C++. 'deep' virtual bases Command-line equivalent: -Vv When a derived class overrides a virtual function which it inherits from a virtual base class, and a constructor or destructor for the derived class calls that virtual function using a pointer to the virtual base class, the compiler can sometimes add hidden members to the derived class. These "hidden members" add code to the constructors and destructors. This option directs the compiler not to add the hidden members and code so that the class instance layout is the same as with previous version of Borland C++; the compiler does not change the layout of any classes to relax the restrictions on pointers. Default = OFF Calling convention mangling compatibility Command-line equivalent: -VC When this option is enabled, the compiler disables the distinction of function names where the only possible difference is incompatible code generation options. For example, with this option enabled, the linker will not detect if a call is made to a _ _fastcall member function with the cdecl calling convention. This option is provided for backward compatibility only; it lets you link old library files that you cannot recompile. Default = OFF Disable constructor displacements Command-line equivalent: -Vc When the Disable Constructor Displacements option is enabled, the compiler does not add hidden members and code to a derived class (the default). This option insures compatibility with previous versions of the compiler. Default = OFF Do not treat 'char' as distinct type Command-line equivalent: -K2, 16-bit Allow only signed and unsigned char types. The Borland C++ compiler allows for signed char, unsigned char, and char data types. This option treats char as signed. Chapter 3, Specifying project options and compiling 61 This option is provided for compatibility with previous versions of Borland C++ (3.1 and earlier) and supports only 16-bit programs. Default = OFF Don't restrict scope of 'for' loop expression variables Command-line equivalent: -Vd This option lets you specify the scope of variables declared in for loop expressions. The output of the following code segment changes, depending on the setting of this option. int main (void) for(int i=O; i<10; iff) cout « "Inside for loop, i = " « Ilend of for-loop block cout « "Outside for loop, i = " « i « i «endl; endl; Ilerror without -Vd Ilend of block containing for loop If this option is disabled (the default), the variable i goes out of scope when processing reaches the end of the for loop. Because of this, you'll get an Undefined Symbol compilation error if you compile this code with this option disabled. If this option is enabled (-Vd), the variable i goes out of scope when processing reaches the end of the block containing the for loop. In this case, the code output would be: Inside for loop, i =0 Outside for loop, i = 10 Default = OFF Pass class values via reference totemporary Command-line equivalent: -Va When this option is enabled, the compiler passes class arguments using the "reference to temporary" approach. When an argument of type class with constructors is passed by value to a function, this option instructs the compiler to create a temporary variable at the calling site, initialize this temporary variable with the argument value, and pass a reference from this temporary to the function. This option insures compatibility with previous versions of the compiler. Default = OFF Push 'this" first for Pascal member functions Command-line equivalent: -Vp 62 C++ Use r 's G u ide When this option is enabled, the compiler passes the this pointer to Pascal member functions as the first parameter on the stack. By default, the compiler passes the this parameter as the last parameter on the stack, which permits smaller and faster member function calls. Default = OFF Treat 'far' classes as 'huge' Command-line equivalent -Vb When this option is enabled, the compiler treats all classes declared __far as if they were declared as __huge. For example, the following code normally fails to compile. Checking this option allows the following code fragment to compile: struct _huge A virtual void f(); II A vtable is required to see the error. }; struct _far B public A }; II Error: Attempting to derive a far class from the huge base 'A'. Default = OFF Virtual base pOinters When a class inherits virtually from a base class, the compiler stores a hidden pointer in the class object to access the virtual base class subobject. The Virtual Base Pointers options specify options about the hidden pointer. Always near Command-line equivalent: -VbWhen the Always Near option is on, the hidden pointer will always be a near pointer. (When a class inherits virtually from a base class, the compiler stores a hidden pointer in the class object to access the virtual base class subobject.) This option allows for the smallest and most efficient code. Same size as 'this' pointer Command-line equivalent: -Vb When the Same Size as 'this' Pointer option is on, the compiler matches the size of the hidden pointer to the size of the this pointer in the instance class. This allows for compatibility with previous versions of the compiler. Default = Always Near (-Vb-) Chapter 3, Specifying project options and compiling 63 Vtable pointer follows data members Command-line equivalent -Vt When this option is enabled, the compiler places the virtual table pointer after any nonstatic data members of the specified class. This option insures compatibility when class instances are shared with non-C++ code . and when sharing classes with code compiled with previous versions of Borland C++. Default = OFF Exception handling I RTII Use the Exceptions Handling options to enable or disable exception handling and to tell the compiler how to handle the generation of run-time type information. If you use exception handling constructs in your code and compile with exceptions disabled, you'll get an error. Enable exceptions Command-line equivalent: -x When this option is enabled, C++ exception handling is enabled. If this option is disabled (-x-) and you attempt to use exception handling routines in your code, the compiler generates error messages during compilation. Disabling this option makes it easier for you to remove exception handling information from programs; this might be useful if you are porting your code to other platforms or compilers. Note Disabling this option turns off only the compilation of exception handling code; your application can still include exception code if you link .OB] and library files that were built with exceptions enabled (such as the Borland standard libraries). Default=ON Enable run-time type information Command-line equivalent: -RT This option causes the compiler to generate code that allows run-time type identification. In general, if you set Enable Destructor Cleanup (-xd), you will need to set this option as well. Default=ON Enable compatible exceptions Command-line equivalent: -xc, 16-bit only 64 c++ User's Guide This option allows .EXEs and .DLLs built with Borland C++ to be compatible with executables built with other products. When Enable Compatible Exceptions is disabled, some exception handling information is included in the .EXE, which could cause compatibility issues. Note Libraries that can be linked into .DLLs need to be built with this option enabled. Default = OFF Enable destructor cleanup Command-line equivalent: -xd When this option is enabled and an exception is thrown, destructors are called for all automatically declared objects between the scope of the catch and throw statements. In general, when you enable this option, you should also set Enable Runtime Type Information (-RT) as well. Note Destructors are not automatically called for dynamic objects allocated with new, and dynamic objects are not automatically freed. Default = ON Enable exception location information Command-line equivalent: -xp When this option is enabled, run-time identification of exceptions is available because the compiler provides the file name and source-code line number where the exception occurred. This enables the program to query file and line number from where a C++ exception was thrown. Default = OFF Enable fast exception pro logs Command-line equivalent: -xf When this option is enabled, inline code is expanded for every exception handling function. This option improves performance at the cost of larger executable file sizes. Note If you select both Fast Exception Prologs and Enable Compatible Exceptions (-xc), fast prologs will be generated but Enable Compatible Exceptions will be disabled (the two options are not compatible). Default = OFF General Zero-length empty base classes Command-line equivalent: -Ve Usually the size of a class is at least one byte, even if the class does not define any data members. When this option is enabled, the compiler ignores this unused byte for the memory layout and the total size of any derived classes. Chapter 3, Specifying project options and compiling 65 Default = OFF Member pOinters Use c++ Member Pointers options to direct member pointers and affect how the compiler treats explicit casts. Honor precision of member pOinters Command-line equivalent: -Vmp When this option is enabled, the compiler uses the declared precision for member pointer types. Use this option when a pointer to a derived class is explicitly cast as a pointer-to-member of a simpler base class (when the pointer is actually pointing to a derived class member). Default = OFF Member pointer representation The c++ Member Pointers options specify what member pointers can point to. Smallest for class Command-line equivalent: -Vmd When this option is enabled, member pointers use the smallest possible representation that allows member pointers to point to all members of their particular class. If the class is not fully defined at the point where the member pointer type is declared, the most general representation is chosen by the compiler and a warning is issued. Default = OFF Support all cases Command-line equivalent: -Vmv When this option is enabled, the compiler places no restrictions on where member pointers can point. Member pointers use the most general (but not always the most efficient) representation. Default = ON Support multiple inheritance Command-line equivalent: -Vmm When this option is enabled, member pointers can point to members of multiple inheritance classes (with the exception of virtual base classes). Default = OFF Support single inheritance Command-line equivalent: -Vms 66 c++ User's Guide When this option is enabled, member pointers can point only to members of base classes that use single inheritance. Default = OFF Templates Use the options under C++ Options I Templates to tell the compiler how to generate template instances in C++. Templates instance generation The Template Instance Generation options specify how the compiler generates template instances in C++. External Command-line equivalent: -Jgx When the External option is on, the compiler generates external references to all template instances. When you use this option, all template instances in your code must be publicly defined in another module with the external option (-Jgd) so that external references are properly resolved. Default = OFF Global Command-line equivalent: -Jgd When the Global option is on, the compiler generates public (global) definitions for all template instances. The Global option does not merge duplicates. If the same template instance is generated more than once, the linker reports public symbol re-definition errors. Default = OFF Smart Command-line equivalent: -Jg When the Smart option is enabled, the compiler generates public (global) definitions for all template instances. If more than one module generates the same template instance, the linker automatically merges duplicates to produce a single copy of the instance. To generate the instances, the compiler must have available the function body (in the case of a template function) or the bodies of member functions and definitions for static data members (in the case of a template class), typically in a header file. This is a convenient way of generating template instances. Default = ON C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 67 Virtual Tables C++ Options IVirtual Tables options control C++ virtual tables and the expansion of inline functions when debugging. Virtual tables linkage The c++ Virtual Tables options control C++ virtual tables and the expansion of inline functions when debugging. External Command-line equivalent: -VO You use the External option to generate external references to virtual tables. If you don't want to use the Smart or Local options, use the External and Public options to produce and reference global virtual tables. Note When you use this option, one or more of the modules comprising the program must be compiled with the Public option to supply the definitions for the virtual tables. Default = OFF Local Command-line equivalent: -Vs You use the Local option to generate local virtual tables (and out..;of-line inline functions) so that each module gets its own private copy of each virtual table or inline function it uses. The Local option uses only standard .OBI and .ASM constructs, but produces larger executables. Default = OFF Public Command-line equivalent: -V1 Public produces public definitions for virtual tables. When using the External option (-VO), at least one of the modules in the program must be compiled with the Public option to supply the definitions for the virtual tables. All other modules should be compiled with the External option to refer to that Public copy of the virtual tables. Default = OFF Smart Command-line equivalent: -V This option generates common C++ virtual tables and out-of-line inline functions across the modules in your application. As a result, only one instance of a given virtual table or out-of-line inline function is included in the program. The Smart option generates the smallest and most efficient executables, but produces .OBI and .ASM files compatible only with TLINK and TASM. . 68 c++ User's Guide Default=ON Compiler options Compiler options are common to all C and C++ programs. They directly affect how the compiler generates code. Defines Command-line equivalent: -Dname and -Dname=string The macro definition capability of Borland C++ lets you define and undefine macros (also called manifest or symbolic constants) in the IDE or on the command line. The macros you define override those defined in your source files. Defining macros from the IDE Preprocessor definitions (such as those used in #if statements and macro definitions) can be entered on the Compiler Defines page. The following rules apply when using the Defines input box: Separate multiple definitions with semicolons (;), and assign values with an equal sign (=). For example: SwitchliSwitch2iSwitch3=OFF • Leading and trailing spaces are stripped, but embedded spaces are left intact. • If you want to include a semicolon in a macro, precede the semicolon witha backslash (\). Defining macros on the command line On the command line, the -Dname option defines the identifier name to the null string. -Dname=string defines name to string. In this assignment, string cannot contain spaces or tabs. You can also define multiple #define options on the command line using either of the following methods: Include multiple definitions after a single -D option by separating each define with a semicolon (;) and assigning values with an equal sign (=). For example: BCC.EXE -Dxxxiyyy=lizzz=NO MYFILE.C Include multiple -D options, separating each with a space. For example: BCC.EXE -Dxxx -Dyyy=l -Dzzz=NO MYFILE.C Code generation Compiler Code Generation options affect how code is generated. C hap t e r 3, S pee i t. yin 9 pro j e c top t ion san d com p iii n 9 69 Allocate enums as ints Command-line equivalent: -b When the Allocate Enums As !nts option is on, the compiler always allocates a whole word (a two-byte int for 16-bits or a four-byte int for 32-bits) for enumeration types (variables of type enum). When this option is off (-b-), the compiler allocates the smallest integer that can hold the enum~ration values: the compiler allocates an unsigned or signed char if the values of the enumeration are within the range of 0 to 255 (minimum) or -128 to 127 (maximum), or an unsigned or signed short if the values of the enumeration are within the following ranges: oto 65,535 (minimum) or -32,768 to 32,767 (maximum) (16-bit) The compiler allocates a a two-byte int (16-bit) or a four-byte int (32-bit) to represent the enumeration values if any value is out of range. Default=ON Duplicate strings merged Command-line equivalent: -d When you check the Duplicate Strings Merged option, the compiler merges two literal strings when one matches another. This produces smaller programs (at the expense of a slightly longer compile time), but can introduce errors if you modify one string. Default = OFF (-d-) fastthis Command-line equivalent: -po, 16-bit only This option causes the compiler to use the __fastthis calling convention when passing the this pointer to member functions. The this pointer is passed in a register (or a register pair in 16-bit large data models). Likewise, calls to member functions load the register (or register pair) with this. Note that you can use __fastthis to compile specific functions in this manner. When this is a 'near' (16-bit) pointer, it is supplied in the SI register; for 'far' this pointers, DS:S1 is used. If necessary, the compiler saves and restores DS. All references in the member function to member data are done via the SI register. The names of member functions compiled with __fastthis are mangled differently from non-fastthis member functions, to prevent mixing the two. It is easiest to compile all classes with __fastthis, but you can compile some classes with __fastthis and some without, as in the following example: II no -po on the command-line class X; #pragrna option -po class Y IIY will use fastthis 70 C++ Use r 's G u ide }; class X IIX will not use fastthis, Iisince its class declaration Ilappeared before fastthis was turned on }; #pragma option -po- Note If you use a makefile to build a version of the class library that has __fastthis enabled, you must define _CLASSLIB_ALLOW_po and use the -po option. The _CLASSLIB_ALLOW_po macro can be defined in BORLANDC\INCLUDE\ SERVICES\borlandc.h. If you use a makefile to build a __fastthis version of the runtime library, you must define _RTL_ALLOW_po and use the -po option. If you rebuild the libraries and use -po without defining the appropriate macro, the linker emits undefined symbol errors. Default = OFF Register variables These options suppress or enable the use of register variables. Automatic Command-line equivalent: -r Choose Automatic to tell the compiler to automatically assign register variables if possible, even when you do not specify a register variable by using the register type specifier. Generally, you can keep this option set to Automatic unless you are interfacing with preexisting assembly code that does not support register variables. Default = Automatic (-r) None Command-line equivalent: -rChoose None to tell the compiler not to use register variables even if you have used the register keyword. Register keyword Command-line equivalent: -rd Choose Register Keyword to tell the compiler to use register variables only if you use the register keyword and a register is available. Use this option or the Automatic option (-r) to optimize the use of registers. Note You can use -rd in #pragma options. Chapter 3, Specifying project options and compiling 71 Unsigned characters Command-line equivalent: -K When the Unsigned Characters option is on, the compiler treats all char declarations as if they were unsigned char type, which provides compatibility with other compilers. Default = OFF (char declarations default to signed; -K-) Floating point The Floating Point options specify how the compiler handles floating-point numbers in your code. Correct Pentium FDIV flaw Command-line equivalent: -fp Some early Pentium chips do not perform specific floating-point division calculations with full precision. Although your chances of encountering this problem are slim, this switch inserts code that emulates floating-point division so that you are assured of the correct result. This option decreases your program's FDIV instruction performance. Note Use of this option only corrects FDIV instructions in modules that you compile. The runtime library also contains FDIV instructions which are not modified by the use of this switch. To correct the run-time libraries, you must recompile them using this switch. The following functions use FDIV instructions in assembly language which are not corrected if you use this option acos acos asin asini atan atan2 atan21 cos tanl cosh coshi cosi exp expl fmod [pow powlO powlOl owl sin sinh sinhl sin! tahn tanh In addition, this switch does not correct functions that convert a floating-point number to or from a string (such as printf or scan£). Default = OFF 72 c++ User's Guide Fast floating point Command-line equivalent: -ff When Fast Floating Point is on, floating-point operations are optimized without regard to explicit or implicit type conversions. Calculations can be faster than under ANSI operating mode. When this option is unchecked (-ff-), the compiler follows strict ANSI rules regarding floating-point conversions. Default = OFF No floating point Command-line equivalent: -fChoose No Floating Point if you are not using floating point. No floating-point libraries are linked when this option is enabled (-f-). If you enable this option and use floatingpoint calculations in your program, you will get link errors. When unchecked (-f), the compiler emulates 80x87 calls at runtime. Default = OFF (-f) Compiler output Set control of object file contents on the Compiler Output page. Autodependency information Command-line equivalent: -XWhen the Autodependency option is checked (-X-), the compiler generates auto dependency information for all project files with a .C or .CPP extension. The Project Manager can use autodependency information to speed up compilation times. The Project Manager opens the .OBJ file and looks for information about files included in the source code. This information is always placed in the .OBJ file when the source module is compiled. After that, the time and date of every file that was used to build the .OBJ file is checked against the time and date information in the .OBJ file. The source file is recompiled if the dates are different. This is called an autodependency . check. If the project file contains valid dependency information, the Project Manager does the autodependency check using that information. This is much faster than reading each .OBJ file. When this option is unchecked (-X), the compiler does not generate the autodependency information. Modules compiled with autodependency information can use Make's autodependency feature. Default = ON (-X-) Chapter 3, Specifying project options and compiling 73 Generate COMDEFs Command-line equivalent: -Fc, 16-bit only Generate COMDEFs generates communal variables (COMDEFs) for global C variables that are not initialized and not declared as static or extern. Use this option when header files included in several source files contain global variables. For example, a definition such as int SomeArray[256]; could appear in a header file that is then included in many modules. When this option is on, the compiler generates SomeArray as a communal variable rather than a public definition (a COMDEF record rather than a PUBDEF record). You can use this option when porting code that uses a similar feature with another implementation. The linker generates only one instance of the variable, so it will not be a duplicate definition linker error. As long as a given variable does not need to be initialized to a nonzero value, you do not need to include a definition for it in any of the source files. Default = OFF Generate underscores Command-line equivalent: -u When the Generate Underscores option is on, the compiler automatically adds an underscore character C) in front of every global identifier (functions and global variables) before saving them in the object module. Pascal identifiers (those modified by the _ _pascal keyword) are converted to uppercase and are not prefixed with an underscore. Underscores for C and C++ are optional, but you should tum this option on to avoid errors if you are linking with the standard Borland C++ libraries. Default = ON Source Compiler I Source options set source code interpretation. Identifier length Command-line equivalent: -in, where n = significant characters Use the Identifier Length input box to specify the number of significant characters (those which will be recognized by the compiler) in an identifier. Except in C++, which recognizes identifiers of unlimited length, all identifiers are treated as distinct only if their significant characters are distinct. This includes variables, preprocessor macro names, and structure member names. Valid numbers for n are 0, and 8 to 250, where 0 means use the maximum identifier length of 250. 74 c++ User's Guide By default, Borland C++ uses 250 characters per identifier. Other systems (including some UNIX compilers) ignore characters beyond the first eight. If you are porting to other environments, you might want to compile your code with a smaller number of significant characters, which helps you locate name conflicts in long identifiers that have been truncated. Default = 250 Language compliance The Language Compliance options tell the compiler how to recognize keywords in your programs. ANSI Command-line equivalent: -A The ANSI option compiles C and C++ ANSI-compatible code, allowing for maximum portability. Non-ANSI keywords are ignored as keywords. Borland extensions Command-line equivalents: -A-, -AT The Borland Extensions option tells the compiler~to recognize Borland's extensions to the C language keywords, including near, far, huge, asm, cded, pascal, interrupt, _export, _ds, _cs, _ss, _es, and the register pseudovariables LAX, _BX, and so on). For a complete list of keywords, see the keyword index. Kernighan and Ritchie Command-line equivalent: -AK The Kernighan and Ritchie option tells the compiler to recognize only the K&R extension keywords and treat any of Borland's C++ extension keywords as normal identifiers. If you get declaration syntax errors from your source code, check that this option is set to Borland Extensions. Default = Borland Extensions (-A-) UNIX V Command-line equivalent: -AU The UNIX V option tells the compiler to recognize only UNIX V keywords and treat any of Borland's C++ extension keywords as normal identifiers. MFC compatibility Command-line equivalents: -VF Tum this option on to compile code that is compatible with the Microsoft Foundation Classes (MFC). Among other things, the compiler makes the following adjustments to be compatible with MFC: Chapter 3, Specifying project options and compiling 75 • Accepts spurious semicolons in a class scope. • Allows anonymous structs. • Uses the old-style scoping resolution in for loops. • Allows methods to be declared with a calling convention, but leaves off the calling convention in the definition. • Tries the operator new if it cannot resolve a call to the operator new[ ]. • Lets you omit the operator & on member functions. • Allows a const class that is passed by value to be treated as a trivial conversion, not as a user conversion. • Allows you to use a cast to a member pointer as a selector for overload resolution, even if the qualifying type of the member pointer is not derived from the class in which the member function is declared. • Accepts declarations with duplicate storage in a class, as in extern "e" typedef • Accepts and ignores #pragma comment(linker, "... ") directives. Default = OFF Nested comments Command-line equivalent: -c When the Nested Comments option is on, you can nest comments in your C and C++ source files. Nested comments are not allowed in standard C implementations, and they are not portable. Default = OFF Debugging Compiler Debugging options affect the generation of debug information during compilation. When linking larger .OBJ files, you may need to tum these options off to increase the available system resources. Browser reference information in OBJs Command-line equivalent: -R When the Browser Reference Info In OBJs option is on, the compiler generates additional browser-specific information such as location and reference information. This information is then included in your .OBJ files. In addition to this option, you need debugging information (-v) to use the Browser. When this option is off, you can link and create larger object files. While this option does not affect execution speed, it does affect compilation time and program size. 76 C++ Use r '5 GU ide Default = ON Debug information in OBJs Command-line equivalent: -v When the Debug Info In OBJs option is on, debugging information is included in your .OBJ files. The compiler passes this option to the linker so it can include the debugging information in the .EXE file. For debugging, this option treats C++ inline functions as normal functions. You need debugging information to use either the integrated debugger or the standalone Turbo Debugger. When this option is off (-v-), you can link and create larger object files. While this option does not affect execution speed, it does affect compilation and link time. Note When Line Numbers is on, make sure you turn off Jump Optimization in the 16-bit specific optimizations and Pentium scheduling in the 32-bit Compiler options. When these options are enabled, the source code will not exactly match the generated machine instructions, which can make stepping through code confusing. Default=ON Line numbers Command-line equivalent: -y When the Line Numbers option is on, the compiler automatically includes line numbers in the object and object map files. Line, numbers are used by both the integrated debugger and Turbo Debugger. Although the Debug Info in OBJs option (-v) automatically generates line number information, you can turn that option off (-v-) and turn on Line Numbers (-y) to reduce the size of the debug information generated. With this setup, you can still step and trace, but you will not be able to watch or inspect data items. Including line numbers increases the size of the object and map files but does not ,affect the speed of the executable program. Note When Line Numbers is on, make sure you tum off Jump Optimization in the 16-bit specific optimizations and Pentium scheduling in the 32-bit Compiler options. When these options are enabled, the source code will not exactly match the generated machine instructions, which can make stepping through code confusing. Default = OFF Out-of-line inline functions Command-line equivalent: -vi When the Out-of-Line Inline Functions option IS on, the compiler expands C++ inline functions inline. Chapter 3, Specifying project options and compiling 77 To control the expansion of inline functions, the Debug Information In OBJs option (-v) acts slightly differently for C++ code: when inline function expansion is disabled, inline functions are generated and called like any other functiort. Because debugging withinline expansion can be difficult, the command-line compilers provide the following options: • • • • -v turns debugging on and inline expansion off -v- turns debugging offand inline expansion on -vi turns inline expansion off (no inline substitution will occur) -vi- turns inline expansion on For example, if you want to tum both debugging and inline expansion on, use the -v and -vi- options. Default = OFF Standard stack frame Command-line equivalent: -k When the Standard Stack Frame option is on, the compiler generates a standard stack frame (standard function entry and exit code). This is helpful when debugging, since it simplifies the process of tracing through the stack of called subroutines. When this option is off, any function that does not use local variables and has no parameters is compiled with abbreviated entry and return code. This makes the code smaller and faster. The Standard Stack Frame option should always be on when you compile a source file for debugging. Default=ON Test Stack Overflow Command-line equivalent: -N, 16-bit only When the this option is on, the compiler generates stack overflow logic at the entry of each function. Even though this is costly in terms of both program size and speed, it can be a real help when trying to track down difficult stack overflow bugs. If an overflow is detected, the run-time error message Stack overflow! is generated, and the program exits with an exit code of l. Note Stack overflow testing is always enabled in the 32.,.bit compilers (this adds a minimal overhead to 32-bit programs). Default = OFF Precompiled headers Using precompiled header files can dramatically increase compilation speed by storing an image of the symbol table on disk in a file, then later reloading that file from disk 78 C++ Use r 's G u id e instead of parsing all the header files again. Directly loading the symbol table from disk is much faster than parsing the text of header files, especially if several source files include the same header file. Cache precompiled header Command-line equivalent: -He Whenyouenable this option, the compiler caches the precompiled headers it generates. This is useful when you are precompiling more than one header file. Note To use this option, you must also enable the Generate and Use (-H) precompiled header option. Default = OFF Precompiled header name Command-line equivalent: -H=filename This option lets you specify the name of your precompiled header file. The compilers set . the name of the precompiled header to filename. When this option is enabled, the compilers generate and use the precompiled header file that you specify. Precompiled headers Using precompiled headers can dramatically increase compilation speeds, though they require a considerable amount of disk space. Do not generate or use Command-line equivalent: -HWhen the Do Not Generate Or Use option is on, the compilers do not generate or use precompiled headers. Default = Do not generate or use (-H-) Generate and use Command-line equivalent: -H When this option is enabled, the IDE generates and uses precompiled headers. The default file name is .CSM for IDE projects and BCDEF.CSM (16-bit) or BC32DEF.CSM (32-bit) for the command-line compilers. Use but do not generate Command-line equivalent: -Hu When the Use But Do Not Generate option ison, the compilers use preexisting precompiled header files; new precompiled header files are not generated. Chapter 3 , Specifying pro j e c to p t ion s and compiling 79 · Stop precompiling after header file Command-line equivalent: -H"xxx"; for example -H"owllowlpch.h" This option terminates compiling the precompiled header after the compiler compiles the file specified as xxx. You can use this option to reduce the amount of disk space used by precompiled headers .. When you use this option, the file you specify must be included' from a source file for the compiler to generate a .CSM file. Note You cannot specify a header file that is included from another header file. For example, you cannot list a header included by windows.h because this would cause the precompiled header file to be closed before the compilation of windows.h was competed. Directories options The Directories options tell the Borland C++ compiler where to find or where to put header files, library files, source code, output files, and other program elements. Source directories The Source Directories options let you specify the directories that contain your standard include files, library and .OB} files, and program source files. Include Command-line equivalent: -Ipath, where path = directory path Use the Include list box to specify the drive and/ or directories that contain program include files. Standard include files are those given in angle brackets in an #include statement (for example, #include and you set the Include option (-I) to specify the path c:\bc\include, the file owl.h must reside in C: \BC \ INCLUDE \ OWL, and not in C: \BC\INCLUDE or C: \ OWL. • If you put an #include statement in your source code, Borland C++ searches for "somefile" only in the directories specified with the Include (-I) option. • If you put an #include "somefile" statement in your code, Borland C++ first searches for "somefile" in the current directory; if it does not find the file there, it then searches in the directories specified with the Include (-I) option. Library file search algorithms • The library file search algorithms are similar to those for include files: C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 81 • Implicit libraries: Borland C++ searches for implicit libraries only in the specified library directories; this is similar to the search algorithm for #include . Implicit library files are the ones Borland C++ automatically links in and the start-up object file (COx.OBJ). To see these files in the Project Manager, tum on run-time nodes (choose Options I Environment I Project View, then check Show Runtime Nodes). • Explicit libraries: Where Borland C++ searches for explicit (user-specified) libraries depends in part on how you list the library file name. Explicit library files are ones you list on the command line or in a project file; these are file names with a .LIB extension. • If you list an explicit library file name with no drive or directory (like this: mylib.lib), Borland C++ first searches for that library in the current directory. If the first search is unsuccessful, Borland C++ looks in the directories specified with the Library (-L) option. This is similar to the search algorithm for #include "somefile". • If you, list a user-specified library with drive and/ or directory information (like this: c:\mystuf£\mylibl.lib), Borland C++ searches only in the location you explicitly listed as part of the library path name and not in any specified library . directories. Output Directories The Output Directories options sp~cify the directories where your .OB], .EXE, .DLL, and .MAP files are placed. The Borland C++ IDE looks for those directories when performing a make or run and to check dates and times of .OB]s, .EXEs, and .DLLs. If the entry is blank, the files are stored in the current directory. Click the down-arrow icon or press Alt+Down arrow to display the history list of previously entered directory names. Intermediate Use the Intermediate list box to specify where Borland C++ places object (.OBJ) and map (.MAP) files when it builds your project. This is also the directory where a tool (such as Resource Workshop) places any temporary files that it might create. Final Command-line equivalent: -npath, where path = directory path The Final list box specifies the location where the IDE places the generated target files (for example, .EXE and .DLL files). Guidelines for entering directory names Use the following guidelines when entering directories in the Directories options pages. • You must separate multiple directory path names (if allowed) with a semicolon (;). • You can use up to a maximum of 127 characters (including white space). • White space before and after the semicolon is allowed but not required. 82 C++ Use r 's G u ide • Relative and absolute path names are allowed, including path names relative to the logged position in drives other than the current one. For example: C:\;C: .. \BORLAND\BC;D:\myprog\source Librarian options Librarian options affect the behavior of the built-in librarian. The built-in librarian combines the .OBJ files in your project into .LIB files. Options in this section control that process. In addition, you can cause the librarian to generate a list (.LST) file containing the .OBJs in a generated .LIB and the functions those .OBJs contain. TLIB.EXE is the command-line librarian. Case-sensitive library Command-line equivalent = Ie When the Case-Sensitive Library option is on, the librarian treats case as significant in all symbols in the library. For example, if Case-Sensitive Library is checked, "CASE", "Case", and "case" are all treated as different symbols. Create extended dictionary Command-line equivalent = IE When the Create Extended Dictionary option is on, the librarian includes, in compact form, additional information that helps the linker process library files faster. Generate list file When the Generate List File option is on, the librarian automatically produces a list file (.LST) that lists the contents of your library when it is created. Library page size Command-line equivalent =IPsize, where size is number of pages The Library Page Size input box is where you set the number of bytes in each library "page" (dictionary entry). The page size determines the maximum size of the library. Page size must be a power of 2 between 16 and 32,768 inclusive. The default page size of 16 allows a library of about 1 MBinsize. To create a larger library, change the page size to the next higher value (32). Chapter 3, Specifying project options a.nd compiling 83 Purge comment records Command-line equivalent =10 When the Purge Comment Records option is on, the librarian removes all comment records from modules added to the library. Linker options Linker options affect how an application is linked. Linker options let you control how intermediate files (.OBI, .LIB, and .RES) are combined into executables (.EXE) and dynamic-link libraries (.DLL). For most options in this section, you will usually want to keep the default settings. 16·bit linker 16-bit Linker options tell the linker how to link 16-bit programs. Discard nonresident name table Command-line equivalent = IGn, 16-bit only When the Discard Nonresident Name Table option is enabled, the linker does not emit the nonresident name table. The resultant image will contain only the module description in the nonresident names table. See Transfer resident names to nonresident names table for usage details. Default = OFF Enable 32·bit processing Command. Jine equivalent =13, 16-bit only The Enable 32-bit processing option lets you link 32-bit DOS object modules produced by TASM or a compatible assembler. This option increases the memory requirements for TLINK and slows down linking. Default = OFF Inhibit optimizing far call to near Command-line equivalent =If, 16-bit only When the linker patches two code segments together, and far calls are made from one to the other, the linker will optimize the code by converting the far calls to near calls. When Inhibit Optimizing Far Call To Near is enabled, this optimization does not occur. You might want to enable this option when you experience run-time crashes that appear to be related to corrupt virtual tables. Because virtual tables reside in the code segment, their contents can sometimes be interpreted by the linker as one of these far calls. 84 c++ User's Guide Default = OFF Initialize segments Command-line equivalent =Ii, 16-bit only When the Initialize Segments option is on, the linker initializes uninitialized trailing segments to be output into the executable file even if the segments do not contain data records. This is normally not needed and will increase the size of your .EXE files!" Default = OFF Linker goodies • Discard nonresident name table • Transfer resident names to nonresident names table Segment alignment Command-line equivalent =IA:dd, 16-bit only Use the Segment Alignment input box to change the current byte value on which to align segments. The operating system seeks pages for loading based on this alignment value. You can enter numbers in the range of 2 to 65,535. Note The alignment factor is automatically rounded up to the nearest power of two. For example, if you enter 650, it is rounded up to 1,024 (this is different from the 32-bit Segment Alignment option). For efficiency, you should use the smallest value that still allows for correct segment offsets in the segment table. Default = 512 . Transfer resident names to nonresident names table Command-line equivalent =IGr, 16-bit only This option causes the linker to copy all names in the resident names table which have not been specified as RESIDENTNAME in the .DEF file to the nonresident names table .. The resultant image contains only the module name and the symbol names of the exported symbols that were specified as RESIDENTNAME in the .DEF fil~. When you use this option, you must also specify the WEP entry point as a RESIDENTNAME in the EXPORTS section of the .DEF file (Windows obtains the WEP entry point for this symbol by looking it up in the resident names table). Note When building .DLLs that contain many exports, it's possible to exceed the 64K header file limitation. Because the .DLL contains the resident names table in its header, moving the exports out of the header using the IGr option usually remedies this problem. The IGr option causes the linker to transfer the names in the resident names table to the nonresident names table. Names in the nonresident names table are then assigned ordinal numbers, which your .EXE file uses when referencing the entry points in the .DLL. Chapter 3, Specifying project options and compiling 85 There are two ways to create input files for the linker: • Run IMPLIB on the .DLL to create an import library for linking purposes. • Run IMPDEF in the .DLL to create a .DEF file for linking purposes. Once the import library or .DEF file has been created, there is no need to keep the names in either the resident or the nonresident names tables. Relinking the .DLL and specifying both the Transfer Resident Names to Nonresident Names Table (/Gr) and Discard Nonresident Name Table (/Gn) options causes the linker to build a '.DLL with an "empty" names table. Not only does this post-processing avoid the problem of exceeding the header limitation, but it also creates a .DLL that loads faster (because it's smaller) and runs faster (because references to entry points are by ordinal number instead of by name). To summarize this process, you must Enable the IGr switch to transfer the names in the resident names table to the nonresident names table. This also assigns ordinal numbers to the names. However; before doing so, make sure you have included a .DEF file with the following export definition in the EXPORTS section: EXPORTS WEP @1 RESIDENTNAME 2 Build the .DLL. 3 Run IMPLIB or IMPDEF on the new .DLL file. 4 Enable the IGn switch (along with the already enabled IGr switch). 5 Relink the .DLL. To see an example of this process, refer to the makefile that builds the ObjectWindows example programs. Default = OFF 16·bit optimizations The 16-bit Optimizations control how the linker optimizes 16-bit .EXE programs. In most cases the final executable file size is reduced, which results in a faster load time. Whenever you use one or more of these options, the linker reorders the .EXE segments as follows: • • • • Note PRELOAD segments PRELOAD resources LOAD ON CALL segments LOAD ON CALL resources These options work only with 16-bit Windows and DPMI programs. Chain fixups Command-line equivalent =10c, 16-bit only 86 c++ User's Guide Chain fixups removes duplicate and/ or unnecessary fixup data from the .EXE file. This is done by emitting only one fixup record for each unique internal fixup and "remembering" the duplicate fixups by creating a linked list of the internal fixup locations within the .EXE data segment. When the loader loads the .EXE, it applies the fixup specified in the fixup record to each of the locations specified in the linked list. Specifying this optimization also causes trailing zeros in data segments to be eliminated. This usually results in a significantly smaller .EXE file, which loads faster. Default = OFF Iterate data Command-line equivalent =fOi, 16-bit only This option scans data segments for patterns of data (for example, a block with 128 bytes filled with "0"). Instead of emitting the data, TLINK emits a "description" of the block of data which matches the pattern (for example, a 5-byte descriptor specifying a 128 bytes of 0). Specifying this optimization also causes trailing zeros in data segments to be eliminated. This usually results in a significantly smaller .EXE file, which loads faster. Default = OFF Minimize resource alignment Command-line equivalent = fOr, 16-bit only This optimization switch is the same as the Minimize segment alignment switch (fDa), except that it applies to resource alignment values instead of segment alignment values. Default = OFF Minimize segment alignment Command-line equivalent = fDa, 16-bit only This optimization switch determines the minimum segment alignment value by examining the size of the .EXE file. An .EXE that has a size of 1 byte to 64K bytes results in an alignment value of 1; if the .EXE file size is 64K+ 1 bytes to 128K bytes, the alignment value is 2; and so on. While this optimization results in a smaller .EXE file, the .EXE might load slower because the newly calculated alignment value may cause the segments to cross physical disk sector boundaries more often. Unless you have also specified the Segment Alignment (fA) linker option, the linker initially generates an .EXE using the default alignment value of 512. Note that this option overrides whatever alignment value the linker might have used to initially generate the .EXE file. Default = OFF 32·bit linker 32-bit Linker options tell the linker how to link 32-bit programs. C hap t e r 3, S pee i f yin 9 pro j e c top t ion 5 and com p iii n 9 87 , Allow import by ordinal Command-line equivalent =10, 32-bit only This option lets you import by ordinal value instead of by the import name. When you specify this option, the linker emits only the ordinal numbers (and not the import names) to the resident or nonresident name table for those imports that have an ordinal number specified. If you do not specify this option, the linker ignores all ordinal numbers contained in import libraries or the .DEF file, and emits the import names to the resident and nonresident tables. Note This option is different than the 16-bit 10 (overlays) option. Committed stack size (in hexadecimal) Command-line equivalent = ISc:xxxx, 32-bit only Specifies the size of the committed stack in hexadecimal. The minimum allowable value for this field is 4K (Ox1000) and any value specified must be equal to or less than the Reserved Stack Size setting (IS). Note Specifying the committed stack size here overrides any STACKSIZE setting in a module definition file. The command-line version of this option (/Sc:xxxx) accepts hexadecimal numbers as the stack reserve value. Default = 8K (0x2000) Committed stack size (in hexadecimal) Command-line equivalent = IHc:xxxx, 32-bit only Specifies the size of the committed heap in hexadecimal. The minimum allowable value for this field is 0 and any value specified must be equal to or less than the Reserved Heap Size setting (/H). Note Specifying the committed heap size here overrides any HEAPSIZE setting in a module definition file. The command-line version of this option (/Hc:xxxx) accepts hexadecimal numbers as the stack reserve value. Default = 4K (Ox1000) File alignment (in hexadecimal) Command-line equivalent = IAf:xxxx, 32-bit only The File Alignment option specifies page alignment for code and data within the executable file. The linker uses the file alignment value when it writes the various, objects and sections (such as code and data) to the file. For example, if you use the default value of Ox200, the linker stores the section of the image on 512-byte boundaries within the executable file. When using this option, you must specify a file alignment value that is a power of 2, with the smallest value being 16. 88 c++ User's Guide Note The old style of this option (IA:dd) is still supported for backward compatibility. With this option, the decimal number dd is multiplied by the power of 2 to calculate the file alignment value. The command-line version of this option (/Af:xxxx) accepts either decimal or hexadecimal numbers as the file alignment value. Default = 512 (0x200) Image base address (in hexadecimal) Command-line eqUivalent = IB:xxxx, 32-bit only The Image Base Address option specifies an image base address for an application, and is used in conjunction with the Image is Based option. If this setting is turned on, internal fixups are removed from the image and the requested load address of the first object in the application is set to the hexadecimal number specified. All successive objects are aligned on 64K linear address boundaries. This option makes applications smaller on disk and improves both load-time and run-time performance (the operating system no longer has to apply internal fixups). The command-line version of this option (/B:xxxx) accepts either decimal or hexadecimal numbers as the image base address. Note It is not recommended that you enable this option when producing a DLL. In addition, do not use the default setting of Ox400000 if you intend to run your application on Wiri32s systems. Default = Ox400000 (recommended for true Win32 system applications) Image is based The Image is Based option affects whether an application has an image base address. If this setting is turned on, internal fixups are removed from the image and the requested load address of the first object in the application is set to the number specified in the Image Base Address input box. Using this option can greatly reduce the size of your final application module; however, it is not recommended for use when producing a DLL. Default = OFF Maximum linker errors Command-line equivalent =IEnn Specifies maximum errors the linker reports before terminating. lEO (default) reports an infinite number of errors (that is, as many as possible). Object alignment (in hexadecimal) Command-line equivCilent = IAo:xxxx, 32-bit only The linker uses the object alignment value to determine the virtual addresses of the various objects and sections (such as code and data) in your application. For example, if C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p il i n 9 89 you specify an object alignment value of 8192, the linker aligns the virtual addresses of the sections in the image on 8192-byte (0x2000) boundaries. When using this option, you must specify an object alignment value that is a power of 2, with the smallest value being 4096 (the default). The command-line version of this option (/Ao:xxxx) accepts either decimal or hexadecimal numbers as the object alignment value. Default = 4096 (Ox1000) Reserved heap size (in hexadecimal) Command-line equivalent = IH:xxxx, 32-bit only Specifies the size of the reserved heap in hexadecimal. The minimum allowable value for this field is O. Note Specifying the reserved heap size here overrides any HEAPSIZE setting in a module definition file. The command-line version of this option (/H:xxxx) accepts hexadecimal numbers as the stack reserve value. Default = 1Mb (Ox1000000) Reserved stack size (in hexadecimal) Command-line equivalent = IS:xxxx, 32-bit only Specifies the size of the reserved stack in hexadecimal. The minimum allowable value for this field is 4K (Ox1000). Note Specifying the reserved stack size here overrides any STACKSIZE setting in a module definition file. The command-line version of this option (/S:xxxx) accepts hexadecimal numbers as the stack reserve value. Default = 1Mb (Ox1000000) Verbose Command-line equivalent = Ir, 32-bit only This option causes the linker to emit messages that indicate what part of the link cycle is currently being executed by the linker. With this option turned on, the linker emits some or all of the following messages: • • • • • 90 Starting pass 1 Generating map file Starting pass 2 Reading resource files Linking resources c++ User's Guide General Use the Linker I General options to include or exclude debugging information from your .EXE or .DLL. Debug information must be included in your program if you want to use the debugger (you can tum it off for production versions). Case-sensitive exports and imports Command-line equivalent =Ie, 16-bit only When the Case-Sensitive Exports option is on, the linker is case sensitive when it processes the names in the IMPORTS and EXPORTS sections of the module definition file. Use this option when you are trying to export non-callback functions from DLLs, as in exported C++ member functions or dynamic versions of ObjectWindows Library and BIDS. Do not use this option for normal Windows callback functions (declared FAR PASCAL). Default = OFF Case-sensitive link Command-line equivalent = Ie When the Case-Sensitive Link option is enabled, the linker differentiates between upper and lower-case characters in public and external symbols. Normally, this option should be checked, since C and C++ are both case-sensitive languages. Default = ON Code pack size Command-line equivalent = IP=n, 16-bit only Use Code Pack Size to change the default code-packing size to any value between 1 and 65,536. (On the command line, set n to a value between 1 and 65,536.) You would probably want the limit to be a multiple of 4K under 386 enhanced mode because of the paging granularity of the system. Although the optimum segment size in 386 enhanced mode is 4K, the default code segment packing size is 8K because typical code segments are from 4K to 8K in size, and the default of 8K might pack more efficiently. Code segment packing typically increases performance because each maintained segment requires system overhead. On the command-line, IP- tums code segment packing off, which can be useful if you've turned it on in the configuration file, but want to turn it off for a particular link. Default = 8192 bytes (8K) Default libraries Command-line equivalent = In C hap t e r 3, S pee i f yin 9 pro j e c top t ion 5 and com p iii n 9 91 When you are linking with modules created by a compiler other than the Borland C++ compiler, the other compiler might have placed a list of default libraries in the object file. When the Default Libraries option is unchecked (of£), the linker tries to find any undefined routines in these libraries and in the default libraries supplied by the C++ IDE. When this option is checked (on), the linker searches only the default libraries supplied by the C++ IDE and ignores any defaults in .OBJ files. You might want to check this option when linking modules written in another language. Default = ON Include debug information Command-line equivalent = Iv When the Include Debug Information option is on, the linker includes information in the output file needed to debug your application with the Borland C++ Integrated Debugger or Turbo Debugger. On the command line, this option causes the linker to include debugging information in the executable file for all object modules that contain debugging information. You can use the Iv+ and Iv- options to selectively enable or disable debugging information on a module-by-module basis (but not on the same command-line where you use Iv). For example, the following command includes debugging information for modules mod2 and mod3, but not for modI and mod4: TLINK modl /v+ mod2 mod3 /v- mod4 Default = ON in IDE; OFF on the command line Pack code segments Command-line equivalent = IP Pack Code Segments has different meanings for I6-bit and 32-bit applications. In addition, Code Segment Packing applies only to Windows applications and DLLs. For I6-bit links, Code Segment Packing causes the linker to minimize the number of code segments by packing as many code segments as possible into one physical segment up to (and never greater than) the code-segment packing limit, which is set to 8,192 (8K) by default. TLINK starts a new segment if needed. Because there is a certain amount of system overhead for every segment maintained, code segment packing typically increases performance by reducing the number of segments. For 32-bit links, Code Packing Segments means the linker packs all code into one "segment." On the command line, IP- turns this option off. Default=ON Subsystem version (major.minor) Command-line equivalent = N d.d 92 c++ User's Guide This option lets you specify the Windows version ID on which you expect your application will be run. The linker sets the Subsystem version field in the .EXE header to number you specify in the input box. You can also set the Windows version ID in the SUBSYSTEM portion of the module definition file (.DEF file). However, any version setting you specify in the IDE or on the command line overrides the setting in the .DEF file. Command-line usage When you use the N d.d command-line option, the linker sets the Windows version ID to the number specified by d.d. For example, if you specify N4.0, the linker sets the Subsystem version field in the .EXE header to 4.0. Default = 4.0 Map file Linker 1Map File options tell what type of map file to produce. You can configure your map file output using the Map File options, which gives you information on segment ordering, segment sizes, and public symbols. Include source line numbers Command-line equivalent: 11, 16-bit only When the Include Source Line Numbers option is on, the linker includes source line numbers in the object map files. For this option to work, linked .OBJ files must be compiled with debug information using-v. When Include Source Line Numbers is on, make sure you turn Jump Optimizations off in the Optimization 116 bit Specific options page, otherwise the compiler might group together common code from multiple lines of source text during jump optimization, or it might reorder lines (which makes line-number tracking difficult). Default = OFF Map file You use the Map File options to choose the type of map file to be produced at link time. For settings other than Off, the map file is placed in the output directory defined in the Directories 1Output page. Off Command-line equivalent = Ix The Off option tells the linker not to create a map file. Default =OFF C hap t e r 3, S pee i f yin 9 pro j e c top t ion 5 and com pili n 9 93 Publics Command-line equivalent =1m This option causes the linker to produce a map file that contains an overview of the application segments and two listings of the public symbols. The segments listing has a line for each segment, showing the segment starting address, segment length, segment name, and the segment class. The public symbols are broken down into tw.o lists, the first showing the symbols in sorted alphabetically, and the second showing the symbols in increasing address order. Symbols with absolute addresses are tagged Abs. A list of public symbols is useful when debugging: many debuggers use public symbols, which lets you refer to symbolic addresses while debugging. Segments Command-line equivalent =Is The Segments option adds a "Detailed map of segments" to the map file created with the Publics option (1m). The detailed list of segments contains the segment class, the segment name, the segment group, the segment module, and the segment ACBP information. If the same segment appears in more than one module, each module appears as a separate line. The ACBP field encodes the A (alignment), C (combination), and B (big) attributes into a set of four bit fields, as defined by Intel. TLINK uses only three of the fields: A, C, and B. The ACBP value in the iTLap is printed in hexadecilnal. The follow Ing field values must be ORed together to arrive at the ACBP value printed. A (alignment) C(combination) B(big) 00 20 40 60 80 An absolute segment A byte-aligned segment C (combination)OOCannot be combined A paragraph-aligned segment AO A page-aligned segmentr An unnamed absolute portion of storage 00 08 00 02 Cannot be combined A public combining segment Segment less than 64K Segment exactly 64K With the Segments options enabled, public symbols with no references are flagged idle. An idle symbol is a publicly defined symbol in a module that was not referenced by an EXTDEF record or by any other module included in the link. For example, this fragment from the public symbol section of a map file indicates that symbols Symboll and Symbol3 are not referenced by the image being linked: 0002:00000874 0002:00000CE4 0002:000000E7 94 c++ User's Guide Idle Idle Symboll Symbol 2 Symbo13 Print mangled names in map file Command-line equivalent =1M Prints the mangled C++ identifiers in the map file, not the full name. This can help you identify how names are mangled (mangled names are needed as input by some utilities). Default = OFF Warnings Warnings options enable or disable the display of Linker warnings. "No stack" warning Command-line equivalent =Ik 16-bit, Iwstk 32-bit This option lets you control whether or not the linker emits the "No stack" warning. The warning is generated if no stack segment is defined in any of the object files or in any of the libraries included in the link. Except for .DLLs, this indicates an error. If a Borland C++ program produces this error, make sure you are using the correct COx startup object file. Use the TLINK32 command-line option Iw-stk to tum this warning off. Default = OFF 32·bit warnings • • • • • • • • No entry point Duplicate symbol No deffile Import does not match previous definition Extern not qualified with _import Using based linking in DLL Self-relative fixup overflowed .EXE module built with a .DLL extension Warn duplicate symbol in .L1B Command-line equivalent = Id 16-bit, Iwdpl32-bit When the Warn Duplicate Symbols option is on, the linker warns you if a symbol appears in more than one object or library files. If the symbol must be included in the program, the linker uses the symbol definition from the first file it encounters with the symbol definition. Use the TLINK32 command-line option Iw-dpl to tum this warning off. Default = OFF Chapter 3, Specifying project options and compiling 95 Make options Make options control the conditions under which the building of a project stops and how the project manager uses autodependency information. Autodependencies When the Make IAutodependencies option is selected, the Project Manager automatically checks dependencies for every target that has a corresponding source file in the project list. Cache When Cache is selected, autodependency information is stored in memory to make dependency checking faster. This option speeds up compilation, but autodependency information will not display in the project tree. Cache and display When Cache and Display is selected, the Project Manager stores the autodependency information in the project file. Once the autodependency information is generated (after a compile) the information is displayed in the project tree. This makes dependency checking faster, but makes project files larger. None When None is selected, no autodependency checking is performed. Use When Use is selected, autodependency checking is performed by reading the autodependency information out of the .OBJ files. Break make on The Make IBreak Make On options specify the error condition that stops the making of a project. Errors This option stops a make when the compiler encounters errors. Fatal errors This option tells the Project Manager to generate a list of errors and warnings for all files and all targets in the project. The Project Manager will go on to link if no errors occur. Default =Errors 96 c++ User's Guide Warnings Command-line equivalent == -w! This option stops a make if the compiler encounters warnings. When this compiler option is enabled, the compiler terminates the compile and returns a non-zero error code if a warning is encountered; an .OBJ file is not created. New node path Tum on the Absolute option if you want new nodes to have an absolute, instead of a relative, path. Messages options Messages options let you control the messages generated by the compiler. Compiler messages are indicators of potential trouble spots in your program. These messages can warn you of many kinds of problems that may be waiting to happen, such as variables and parameters that are declared but never used, type mismatches, and many others. Setting a message option causes the compiler to generate the associated message or warning the specific condition arises. Note that some of the messages are on by default. ANSI Violations Compiler Messages I ANSI Violations options enable or disable individual warning messages about statements that violate the ANSI standard for the C language. The options are: • Void functions may not return a value Command-line equivalent: -wvoi, Default = ON • Both return and return of a value used Command-line equivalent: -wret, Default = ON • Suspicious pointer conversion Command-line equivalent: -wsus, Default = ON • Undefined structure 'ident' Command-line equivalent: -wstu, Default = ON • Redefinition of 'ident' is not identical Command-line equivalent: -wdup, Default = ON • Hexadecimal value more than three digits Command-line equivalent: -wbig, Default = ON • Bit, fields must be signed or unsigned int Command-line equivalent: -wbbf, Default = OFF • 'ident' declared as both external and static Command-line equivalent: -wext, Default = ON • Declare 'ident' prior to use in prototype Command-line equivalent: -wdpu, Default = ON • Division by zero " Command-line equivalent: -wzdi, Default = ON Chapter 3, Specifying project options and compiling 97 • Initializing 'ident' with 'ident' Command-line equivalent: -wbei, Default = ON • Initialization is only partially bracketed Command-line equivalent: -wpin, Default = OFF • Non-ANSI keyword used Command-line equivalent: -wnak, Default = OFF Display warnings Use the Display Warnings options to choose which warnings are displayed. All Command-line equivalent: -w Display all warning and error messages. Default = OFF None Suppresses the display of warning messages. Errors are still displayed. Default = OFF Selected Command-line equivalent: -waaa Choose which warnings are displayed. Using pragma warn in your source code overrides messages options set either at the command line or in the IDE. To disable a message from the command line, use the command-line option -w-aaa, where aaa is the 3-letter message identifier used by the command-line option. Default = ON General Compiler Messages I General options enable or disable a few general warning messages. The options are • Unknown assembler instruction Command-line equivalent: -wasm, Default =OFF • Ill-formed pragma Command-line equivalent: -will, Default = ON • Array variable 'ident' is near Command-line equivalent: -wias, Default = ON • Superfluous & with function Command-line equivalent: -wamp, Default = OFF • 'ident' is obsolete Command-line equivalent: -wobs, Default = OFF 98 C++ Use r 's G u ide • Cannot create precompiled header Command-line equivalent: -wpeh, Default::;: OFF • User-defined warnings Command-line equivalent: -wmsg, Default ::;: ON User-defined warnings Command-line equivalent: -wmsg The User-defined warnings option allows user-defined messages to appear in the IDE's Message window. User-defined messages are introduced with the #pragma message compiler syntax. Note In addition to messages that you introduce with the #pragma message compiler syntax, user-defined warnings allows warnings introduced by third-party libraries to be displayed. Remember, if you need help on a third-party warning, please contact the vendor of the header file that issued the warning. Default::;: ON Inefficient C++ coding Compiler Messages I Inefficient C++ Coding options enable or disable individual warning messages about inefficient C++ coding. The options are: • Functions containing 'ident' not expanded inline Command-line equivalent: -winI, Default ::;: ON • Temporary used to initialize 'ident' Command-line equivalent: -wlin, Default ::;: ON • Temporary used for parameter 'ident' Command-line equivalent: -wIve, Default ::;: ON Inefficient coding Compiler Messages I Inefficient Coding options are used to enable or disable individual warning messages about inefficient coding. The options are: • 'ident' assigned a value which is never used Command-line equivalent: -waus, Default::;: ON • Parameter 'ident' is never used Command-line equivalent: -wpar, Default ::;: ON • 'ident' declared but never used Command-line equivalent: -wuse, Default::;: OFF • Structure passed by value Command-line equivalent: -wstv, Default ::;: OFF • Umeachable code Command-line equivalent: -wreh, Default::;: ON • Code has no effect . Command-line equivalent: -weff, Default::;: ON Chapter 3, Specifying project options and compiling 99 Note The warnings Unreachable Code and Code Has No Effect can be indicators of serious coding problems. If the compiler generates these warnings, be sure to examine the lines of code which cause the errors to be generated. Obsolete C++ Compiler Messages IObsolete C++ options choose which specific obsolete items or incorrect syntax C++ warnings to display. The options are: • Base initialization without class name is obsolete Command-line equivalent: -wobi, Default = ON • This style of function definition is obsolete Command-line equivalent: -wofp, Default = ON • Overloaded prefix operator used as a postfix operator Command-line equivalent: -wpre, Default = OFF Portability Compiler Messages IPortability options enable or disable individual warning messages about statements that might not operate correctly in all computer environments. The options are: • Non-portable pointer conversion Command-line equivalent: -wrpt, Default = ON • Non-portable pointer comparison Command-line equivalent: -wept, Default = ON • Constant out of range in comparison Command-line equivalent: -wmg, Default = ON • Constant is long Command-lirte equivalent: -wcln, Default = OFF • Conversion may lose significant digits Command-line equivalent: -wsig, Default = OFF • Mixing pointers to signed and unsigned char Command-line equivalent: -wuep, Default = OFF Potential C++ Errors Compiler Messages IPotential C++ Errors options enable or disable individual warning messages about statements that violate C++ language implementation. The options are: • Constant member 'ident' is not initialized Command-1..iJ.i.e equivalent: -wnci, Default =ON • Assigning 'type' to 'enumeration' Command-line equivalent: -weas, Default =OFF • 'function' hides virtual function 'function2' Command-line equivalent: -whid, Default = ON 100 C++ Use r 's G u ide • Non-const function 'ident' called for const object Command-line equivalent: -wnd, Default = ON • Base class 'ident' inaccessible because also in 'ident' Command-line equivalent: -wibc, Default = OFF • Array size for' delete' ignored Command-line equivalent: -wdsz, Default = OFF • Use qualified name to access nested type 'ident' Command-line equivalent: -wnst, Default = OFF • Handler for ' ' Hidden by Previous Handler for ' ' Command-line equivalent: -whch, Default == ON • Conversion to 'type' will fail for virtual base members Command-line equivalent: -wmpc, Default = ON • Maximum precision used for member pointer type Command-line equivalent: -wmpd, Default = ON • Use '> >' for nested templ~tes instead of I»~' Command-line equivalent: -wntd, Default = ON • Non-volatile function called for volatile object Command-line equivalent: -wnd, Default = ON Potential errors Compiler Messages IPotential Errors options enable or disable individual warning messages about potential coding errors. The options are: • Possibly incorrect assignment Command-line equivalent: -wpia, Default = ON • Possible use of 'ident' before definition Command-line equivalent: -wdef, Default = ON • No declaration for function 'ident' Command-line equivalent: -wnod, Default = OFF • Call to function with no prototype Command-line equivalent:-wpro, Default = ON • Function should return a value Command-line equivalent: -wrvl, Default = ON • Ambiguous operators need parentheses Command-line equivalent: -wamb, Default = OFF • . Condition is always (true/false) Command-line equivalent: -wccc, Default = OFF Stop after ... errors Command-line equivalent: -jn Errors: Stop After causes compilation to stop after the specified number of errors has been detected. You can enter any number from 0 to 255. Entering 0 causes compilation to continue until the end of the file. Default = 25 C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d co mpi lin 9 101 Stop after ... warnings Command-line equivalent: -gn Warnings: Stop After causes compilation to stop after the specified number of warnings has been detected. You can enter any number from a to 255. Entering a causes compilation to continue until either the end of the file or the error limit set in Errors: Stop After has been reached, whichever comes first. Default = 100 Optimization options Optimization options are the software equivalent of performance tuning. There are two general types of compiler optimizations: • Those that make your code smaller • Those that make your code faster Although you can compile with optimizations at any point in your product development cycle, be aware when debugging that some assembly instructions might be optimized away" by certain compiler optimizations. 1/ General settings The main Optimizations page in the Project Options dialog box contains four radio buttons that let you select the overall type of optimizations you want to use. Because of the complexities of setting compiler optimizations, it is recommended that you use either the Optimize for Size or the Optimize for Speed radio buttons. The general optimization settings are: • • • • Disable all optimizations Use selected optimizations Optimize for size Optimize for speed 16 and 32·bit The 16- and 32-bit compiler options specify optimization settings for all compilations. Common subexpression The Common Subexpressions options tell the compiler how to find and eliminate duplicate expressions in your code. No optimization When the No Optimization option is on, the compiler does not eliminate common subexpressions. This is the default behavior of the command-line. compilers. 102 C++ Use r 's G u ide Optimize Globally Command-line equivalent: -Og When you set this option, the compiler eliminates common subexpressions within an entire function. This option globally eliminates duplicate expressions within the target scope and stores the calculated value of those expressions once (instead of recalculating the expression). Although this optimization could theoretically reduce code size, it optimizes for speed and rarely results in size reductions. Use this option if you prefer to reuse expressions rather than create explicit stack locations for them. Optimize locally Command-line equivalent: -Oc When the Optimize Locally option is on, the compiler eliminates common subexpressions within groups of statements unbroken by jumps (basic blocks). Induction variables Command-line equivalent: -Ov When this option is enabled, the compiler creates induction variables and it performs strength reduction, which optimizes for loops speed. Use this option when you're compiling for speed and your code contains loops. The optimizer uses induction to create new variables (induction variables) from expressions used in loops. The optimizer assures that the operations performed on these new variables are computationally less expensive (reduced in strength) than those used by the original variables. Optimizations are common if you use array indexing inside loops, because a multiplication operation is required to calculate the position in the array that is indicated by the index. For example, the optimizer creates an induction variable out of the operation v[i] in the following code because the v[i] operation requires multiplication. This optimization .also eliminates the need to preserve the value of i: int v[10] i void f(int X, int Y, int z) int ii for (i = Oi i < 10i i++) v[i] = X * Y * Zi With Induction variables enabled, the code changes: int V[10]i voidf(int x, int Y, int z) { int i , *Pi for (p = Vi P < &V[10]i P++) *p = X * Y * Zi Chapter 3, Specifying project options and compiling 103 Inline intrinsic functions , Command-line equivalent: -Oi When the Inline Intrinsic Functions option is on, the compiler generates the code for common memory functions like strcpyO within your function's scope. This eliminates the need for a function call. The resulting code executes faster, but it is larger. The following functions are inlined with this option: alloea rnemcpy stpcpy strcpy strncpy fabs memset streat strlen strnset memchr rot! strchr strneat strrehr mememp rotr strcmp strnemp You can control the inlining of these functions with the pragma intrinsic. For example, #pragma intrinsic strepy causes the compiler to generate inline code for all subsequent calls to strepy in your function, and #pragma intrinsic -strcpy prevents the compiler from inlining strepy. Using these pragmas in a file overrides any compiler option settings. When inlining any intrinsic function, you must include a prototype for that function before you use it; the compiler creates a macro that renames the inlined function to a function that the compiler recognizes internally. In the previous example, the compiler would create a macro #define strepy __strepy__. The compiler recognizes calls to functions with two leading and two trailing underscores and tries to match the prototype of that function against its own internally stored prototype. If you don't supply a prototype, or if the prototype you supply doesn't match the compiler'S prototype, the compiler rejects the attempt to inline that function and generates an error. 16·bit The Optimizations I16-bit options pertain to 16-bit applications only. Assume no pOinter aliasing Command-line equivalent: -Oa When the Assume No Pointer Aliasing option is on, the compiler assumes that pointer expressions are not aliased in common subexpression evaluation. Assume No Pointer Aliasing affects the way the optimizer performs common subexpression elimination and copy propagation by letting the optimizer maintain copy propagation information across function calls and by letting the optimizer maintain common sub expression information across some stores. Without this option the optimizer must discard information about copies and subexpressions. Pointer aliasing might create bugs that are hard to spot, so it is only applied when you enable this option. Assume No Pointer Aliasing controls how the optimizer treats expressions that contain pointers. When compiling with global or local common subexpressions and Assume No 104 c++ User's Guide Pointer Aliasing is enabled, the optimizer recognizes *p * x as a common subexpression in function func1. int g, Yi int funcl(int *p) { int X=5i Y = *p * Xi , g = 3i return (*p * X) i void func2(void) g=2i funcl(&g)i II This is incorrect--the assignment g II invalidates the expression *p * X =3 Copy propagation Command-line equivalent: -Op When this option is enabled, copies of constants, variables, and expressions are propagated whenever possible. Copy propagation is primarily speed optimization, but it never increases the size of your code. Like loop-invariant code motion, copy propagation relies on the analysis performed during common subexpression elimination. Copy propagation means that the optimizer remembers the values assigned to expressions and uses those values instead of loading the value of the assigned expressions. With this, copies of constants, expressions, and variables can be propagated. Dead code elimination Command-line equivalent: -Ob When the Dead Code Elimination option is on, the compiler reveals variables that might not be needed. Because the optimizer must determine where variables are no longer used (live range analysis), you might also want to set Global Register Allocation (-Oe) when you use this option. Global register allocation Command-line equivalent: -Oe When this option is enabled, global register allocation and variable live range analysis are enabled. This option should always be used when optimizing code because it increases the speed and decreases the size of your application. Invariant code motion Command-line equivalent: -Om Chapter 3, Specifying project options and compiling 105 When this option is enabled, invariant code is moved out of loops and your code is optimized for speed. The optimizer uses information about all the expressions in the function (gathered during common subexpression elimination) to find expressions whose values do not change inside a loop. To prevent the calculation from beifig done many times inside the loop, the optimizer moves the code outside the loop so that it is calculated only once. The optimizer then . reuses the calculated value inside the loop. You should use loop-invariant code motion whenever you are compiling for speed and have used global common subexpressions, because moving code out of loops can result in enormous speed gains. For example, in the following code, x * y * z is evaluated in every iteration of the loop: int v[10]; void f(int x, int y, int z) int i; for (i = 0; i < 10; itt) v[i] = x * y * z; The optimizer rewrites the code: int v[10]; void f(int x, int y, int z) int i,t1; t1 = x * y * z; for (i = 0; i < 10; itt) v[i] = t1; Jump optimization Command-line equivalent: -0 When Jump Optimization option is on, the compiler reduces the code size by eliminating redundant jumps and reorganizing loops and switch statements. When this option is enabled, the sequences of tracing and stepping in the debugger can be confusing because of the reordering and elimination of instructions. If you are debugging at the assembly level, you might want to disable this option. Default=ON Loop optimization Command-line equivalent: -01 When this option is enabled, loops are compacted into REP /STOSx instructions. Loop optimization takes advantage of the string move instructions on the 80x86 processors by replacing the code for a loop with a string move instruction, making the code faster. 106 c++ User's Guide Depending on the complexity of the operands, the compacted loop code can also be smaller than the corresponding non-compacted loop. Suppress redundant loads Command-line equivalent: -z When this option is enabled, the compiler suppresses the reloading of registers by remembering the contents of registers and reusing them as often as possible. Exercise caution when using this option; the compiler cannot detect if a value has been modified indirectly by a pointer. Windows prolog/epilog Command-line equivalent: -OW Use the Windows Prolog/Epilog option to suppress the inc bp / dec bp of an exported Windows far function prolog and epilog code. If Debug Information in .OBJ Files (-v) is enabled, this option is disabled because some debugging tools (such as WinSpector and Turbo Debugger) need the inc bp / dec bp instructions to display stack-frame information. 32·bit Use the Optimizations I32-bit options to specify options specific to the Pentium processor and the Intel optimizing compiler. The options are: Cache hit optimizations (Intel compiler only) Command-line equivalent: -OM Specifies a set of memory accessing optimizations that improves cache hits and reduces the number of memory accesses. These optimizations include: • • • • • • Loop interchange Loop distribution Strip mining and preloading Loop blocking Alternate loops Loop unrolling Optimize across function boundaries (Intel compiler only) Command-line equivalent: -01 Specifies a set of interprocedural optimizations. These optimizations eliminate call overhead and can create opportunities for further optimizations. They are applied across procedure boundaries but are restricted to routines within the same file, including routines in files combined by the #include preprocessor directive. These optimizations include: C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 107 • • • • • Note Monitoring module-level static variables Inline function expansion Cloning Passing arguments in registers Constant argument propagation Currently, these optimizations are disabled if your source code contains embedded assembly code. Pentium instruction scheduling Command-line equivalent: -os When enabled, this switch rearranges instructions to minimize delays that can be caused by Address Generation Interlocks (AGI) that occur on the i486 and Pentium processors. This option also optimizes the code so that it takes advantage of the Pentium parallel pipelines. Best results for Pentium systems are obtained when you use this switch in conjunction with the 32-bit Compiler I Pentium option in the Project Options dialog box (-5). Note that scheduled code is more difficult to debug at the source level because instructions from a particular source line may be mixed with instructions from other source lines. Stepping through the source code is still possible, although the execution point might make unexpected jumps between source lines as you step. Also, setting a breakpoint on a source line may result in several breakpoints being set in the code. This is especially important to note when inspecting variables, since a variable may be undefined even though the execution point is positioned after the variable assignment. Stepping through the following function when this switch is enabled demonstrates the stepping behavior: int v[lO]; void f(int i, int j) int a,b; a = v[i+j]; b = v[i-j] ; v[i] = a + b; v[j] =a - b; Execution starts by computing the index i-j in the assignment to b (note that a is still undefined although the execution point is positioned after the assignment to a). The index i+j is computed, v[i-j] is assigned to b, and v[i+j] is assigned to a. If a breakpoint is set on the assignment to b, execution will stop twice: once when computing the index and again when performing the assignment. Default = OFF (-O-S) 108 c++ User's Guide General optimization settings Disable all optimizations Command-line equivalent: -Od Disables all optimization settings, including ones which you may have specifically set and those which would normally be performed as part of the speed/size tradeoff. Because this disables code compaction (tail merging) and cross-jump optimizations, using this option can keep the debugger from jumping around or returning from a function without warning, which makes stepping through code easier to follow. Note You can override this setting using the predefined Style Sheets in the Project Manager. Optimize for size Command-line equivalents: -01 This radio button sets an aggregate of optimization options that tells the compiler to optimize your code for size. For example, the compiler scans the generated code for duplicate sequences. When such sequences warrant, the optimizer replaces one sequence of code with a jump to the other and eliminates the first piece of code. This occurs most often with switch statements. The compiler optimizes for size by choosing the smallest code sequence possible. This option (-01) sets the following optimizations: • • • • • • • Note Jump optimizations (-0) Dead code elimination (-Ob) Duplicate expressions (-Oc) Register allocation and live range analysis (-Oe) Loop optimizations (-01) Instruction scheduling (-OS) Register load suppression (-Z) The compiler options -Ot and -G are supported for ba!2kward compatibility only, and are equivalent to the -01 compiler option. Optimize for speed Command-line equivalent: -02 This radio button sets an aggregate of optimization options that tells the compiler to optimize your code for speed. This switch (-02) sets the following optimizations: • • • • • • • • • Dead code elimination (-Ob) Register allocation and live range analysis (-Oe) Duplicate expression within functions (-Og) Intrinsic functions (-Oi) Loop optimizations (-01) Code motion (-Om) Copy propagation (-Op) Instruction scheduling (-OS) Induction variables (-Ov) Chapter 3, Specifying project options and compiling 109 • Register load suppression (__Z) If you are creating Windows applications, you'll probably want to optimize for speed. Note The compiler options -Os and -G- are supported for backward compatibility only, and are equivalent to the -02 compiler option. The -Ox option is also supported for backward compatibility and for compatibility with Microsoft make files. Use selected optimizations Does not set any optimization by default, but lets you set the specific optimization options you need through the settings contained in the Optimization subtopics. The subtopic pages are: • 16 and 32-bit • 16-bit specific • 32-bit specific Note Configuring your own optimization settings should be reserved for expert users only. Resources options The Resources options let you set several options for how resources are compiled and bound to your application by the integrated resource compiler and resource linker. 16·bit Resources The 16-bit Resource options let you choose options for resources targeted for 16-bit applications. Target Windows version Use the Target Windows Version options to choose the Windows version with which you are working. These options specify which version of Windows your resources are marked with when you create 16-bit resources. You cannot mixJ6-bit and 32-bit files in a resource project. To add resources from existing 32-bit .RES or .EXE files to a 16-bit resource project, save the files as .RC files and add the .RC files to your project; .RC files are not version specific. Windows 3.1 Command-line equivalent: (Rlink.EXE) -V31 Creates 16-bit resources for a Windows 3.1 application. Windows 95 Command-line equivalent: (Rlink.EXE) -V40 Creates 16-bit resources for a Windows 95 application. 110 C++ Use r' s G u ide Pack fastload area The Pack Fastload Area option optimizes the executable file by packing all PRELOAD segments and resources in a contiguous area in the.EXE file. When Pack Fastload Area is enabled, the resource linker writes all data segments, all nondiscardable code segments, and the entry-point code segment to a contiguous area in the executable file. This makes your executable files load faster at runtime. If you uncheck Pack Fastload Area, no such optimizations will be done. Default = OFF Librarian Librarian options affect the behavior of the built-in librarian. The built-in librarian combines the .OBJ files in your project into .LIB files. Options in this section control that process. In addition, you can cause the librarian to generate a list (.LST) file containing the .OBJs in a generated .LIB and the functions those .OBJs contain. TLIB.EXE is the command-line librarian. Case-sensitive library Command-line equivalent = Ie When the Case-Sensitive Library option is on, the librarian treats case as significant in all symbols in the library. For example, if Case-Sensitive Library is checked, "CASE", "Case", and "case" are all treated as different symbols. Create extended dictionary Command-line equivalent = IE When the Create Extended Dictionary option is on, the librarian includes, in compact form, additional information that helps the linker process library files faster. Generate list file When the Generate List File option is on, the librarian automatically produces a list file (.LST) that lists the contents of your library when it is created. Library page size Command-line equivalent = IPsize, where size is number of pages The Library Page Size input box is where you set the number of bytes in each library "page" (dictionary entry). The page size determines the maximum size of the library. Page size must be a power of 2 between 16 and 32,768 inclusive. The default page size of 16 allows a library of about 1 Mbinsize. To create a larger library, change the page size to the next higher value (32). Chapter 3, Specifying project options and compiling 111 Purge comment records Command-line equivalent = /0 When the Purge Comment Records option is on, the librarian removes all comment records from modules added to the library. 32·bit Resources The 32-bit resource options let you choose options for resources targeted for 32-bit applications. Language Use the Language list boxes to select the base and sub-languages to be used for the resources in the your project. Multiple resources with the same ID may be bound to a single .EXE or .DLL if they each . have different major and/ or minor languages specified. The language currently specified by Windows will determine which resource identified by the ID will actually be loaded. The language you choose must match the language that Windows NT systems are set to. If not, your resources might not be correctly displayed (this is especially true for menu resources). Major Use the Major list box to select the base (or primary) language to be used for the resources. Minor Use the Minor list box to select the sub-language (or dialect) to be used for the resources. For example, you might define your resource to have English as the base language and U.S. as the sub-language. Note These options set the default languages for the Resource compiler. You can override these default settings by embedding language statements in your .RC file. Default = Neutral Target Windows version Use the Target Windows Version options to choose the Windows version with which you are working. These options specify which version of Windows your resources are marked with when you create 32-bit resources. You cannot mix 16-bit and 32-bit files in a resource project. To add resources from existing 16-bit .RES or .EXE files to a 32-bit resource project, save the files as .RC files and add ·the .RC files to your project; .RC files are not version specific. 112 C++ Use r 's G u ide Win32sIWindows NT 3.1 This options links your resources so that your 32-bit applications can be run on Win32s, Windows NT 3.1, and Windows NT 3.5 systems (this is not compatible with Windows NT 3.51 systems). Windows 95IWindows NT 3.51 This options links your resources so that your 32-bit applications can be run on Windows 95 and Windows NT 3.51 systems. Command-line only options The options are available only from the command line. Object search paths Command-line equivalent = Ij This option lets you specify the directories the linker will search if there is no explicit path given for an .OBJ module in the compile/link statement. This option works with both TLINK and TLINK32. The Specify Object Search Path uses the following command-line syntax: /j [; ] [ ... ] The linker uses the specified object search path(s) if there is no explicit path given for the .OBJ file and the linker cannot find the object file in the current directory. For example, the command TLINK32 /jc:\myobjs;.\objs splash . \ common \ logo , "utils logolib directs the linker to first search the current directory for SPLASH. OBI. If it is not found in the current directory, the linker then searches for the file in the C: \MYOBJS directory, and then in the. \OBJS directory. However, notice that the linker does not use the object search paths to find the file LOGO.OBJ because an explicit path was given for this file. 16 and 32-bit command-line switches The following command-line switches are supported by the command-line compilers BCC.EXE, BCC32.EXE, and BCC32i.EXE. c++ compile Command-line equivalent = -P The -P command-line option causes the compiler to compile all source files as C++ files, regardless of their extension. Use -P- to compile all.CPP files as C++ source files and all other files as C source files. The command-line option -Pext causes the compiler to compile all source files as C++ files and it changes the default extension to whatever you specify with ext. This option is provided because some programmers use different extensions as their default extension for C++ code. C hap t e r 3, S pee if yin 9 pro j e c top t ion san d com p iii n 9 113 The option -P-ext compiles files based on their extension (.CPP compiles to C++, all other extensions compile to C) and sets the default extension (other than .CPP). Compile .OBJ to filename Command-line equivalent = -ofilename Use this option to compile the specified source file to filename.OBJ. Compile to .ASM, then assemble Command-line equivalent = -B This command-line option causes the compiler to first generate an'.ASM file from your C++ (or C) source code (same as the -5 command-line option). The compiler then calls TASM (or the assembler specified with the -E option) to create an .OBJ file from the .ASM file. The .ASM file is then deleted. To use this 32-bit compiler option, you must install a 32-bit assembler, such as TASM32.EXE, and then specify this assembler with the -E option. In the IDE, right-click the source node in the Project Manager, then choose Special I C++ to Assembler. Compile to .OBJ, no link Command-line equivalent = -c Compiles and assembles the names .C, .CPP, and .ASM files, but does not execute a link on the resulting .OBJ files. In the IDE, choose Project I Compile. Compile to assembler Command-line equivalent =-5 This option causes the compiler to generate an .ASM file from your C++ (or C) source code. The generated .ASM file includes the original C or C++ source lines as comments in the file. Create a map file Command-line equivalent = -M Use this command-line option tells the linker to create a map file. Pass option to linker Command-line equivalent = -Ix Use this command-line option to pass option(s) x to the linker from a compile command. Use the command-line option -l-x to disable a specific linker option. Specify assembler Command-line equivalent = -Efilename Assemble instructions using filename as the assembler. The 16-bit compiler uses TASM as the default assembler. In the IDE, you can configure a different assembler using the Tool menu. 114 c++ User's Guide Specify assembler option Command-line equivalent = -Tx Use this command-line option to pass the option(s) x to the assembler you specify with the -E option. To disable all previously enabled assembler options, use the -Tcommand-line option. Specify executable file name Command-line equivalent = -efilename Link file using filename as the name of the executable file. If you do not specify an executable name with this option, the linker creates an executable file based on the name of the first source file or object file listed in the command. Undefine symbol Command-line equivalent = -Uname This command-line option undefine the previous definition of the identifier name. 16-bit command-line switches The following switches are supported by the 16-bit command-line compiler (BCC.EXE) and linker (TLINK.EXE). Compile to DOS .COM Command-line equivalent = -tDc The compiler creates a DOS tiny-model .COM file. DOS .COM, applications cannot exceed 64K in size, have segment-relative fixups, or define a stack segment. In addition, .COM files must have a starting address of 0:100H. If you change the file extension (to .BIN, for example), the starting address can be either 0:0 or 0:100H. The linker can't generate debugging information for .COM files, so you'll need to debug it as an .EXE file, then recompile and link the application as a .COM file. Compile to DOS .EXE Command-line equivalent =-tD The compiler creates a DOS .EXE file (same as -tDe). Compile to DPMI .EXE Command-line equivalent = -wx The compiler creates a DOS Protected Mode Interface (DPMI) .EXE file. Enable backward compatibility options Command-line equivalent = -Vo C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com pi lin 9 115 This compiler option enables the following 16-bit backward compatibility options: -Va, -Vb, -Ve, -Vp, -Vt, -Vv. Use this option as a handy shortcut when linking libraries built with older versions of Borland C++. Expanded memory swapping Command-line equivalent = lye This 16-bit linker option controls how TLINK uses expanded memory for I/O buffering. If the linker needs more memory for active data structures (while reading object files or writing the executable file), it either clears buffers or swaps them to expanded memory. When reading files, the linker clears the input buffer so that its space can be used for other data structures. When creating an executable, it writes the buffer to its correct place in the executable file. In both cases, you can substantially increase the link speed by swapping to expanded memory. By default, swapping to expanded memory is enabled and swapping to extended memory is disabled. If swapping is enabled and no appropriate memory exists in which to swap, then swapping doesn't occur. Default = ON Extended memory swapping Command-line equivalent =Iyx This TLINK option controls the linker's use of extended memory for I/O buffering. By default, the linker can use up to 8Mb of extended memory. You can control the linker's use of extended memory with one of the following forms of this switch: • Iyx or Iyx+ uses all available extended memory, up to 8Mb • Iyxn uses only up to n Kb of extended memory Default = OFF Generate 8087 instructions Command-line equivalent = -f87 Use this 16-bit compiler option to create DOS 8087 floating point code. Generate overlay code Command-line equivalent = - y The compiler generates the DOS code needed to create overlay files. Link DOS .COM Command-line equivalent = fIde TLINK generates a real-mode DOS .COM file. (The command-line option It is supported for backward compatibility only; it has the same functionality as fIde.) Link DOS .EXE Command-line equivalent = fIde 116 c++ User's Guide TLINK generates a real-mode OOS .EXE file. Link OPMI .EXE Command-line equivalent = (fxe TLINK generates a DOS Protected Mode Interface (DPMI) .EXE file. Link Windows .OLL Command-line equivalent = (fwd TLINK generates a Windows .DLL file. Link Windows .EXE Command-line equivalent = (fwe TLINK generates a Windows .EXE file. Overlay the compiled files Command-line equivalent = -Yo The compiler overlays the compiled overlay files which you've specified with the -Y option. Overlay the compiled files Command-line equivalent =10 This DOS -only option causes TLINK to overlay all the modules or libraries that follow the option on the command line. Use 10- on the command line to turn of overlays. If you list a class name after this option, TLINK overlays all the segments in that class (this also works for multiple classes). If you don't list any name after this option, TLINK overlays all segments of classes ending with CODE. This option uses the default overlay interrupt number 3FH. To specify a different interrupt number, use loxx, whrere xx is a two-digit hexademimal number. Specify option to RLiNK Command-line equivalent =IRx TLINK passes the option x to RLINK.EXE (x can be either e, k, m, p, or v). 32-bit command-line switches The following switches are supported by the 32-bit command-line compilers (BCC32.EXE and BCC32i.EXE) and linker (TLINK32.EXE). Note The followmg 32-bit command-line options are not needed if you include a module definition file in your compile and link commands which specifies the type of 32-bit application you intend to build. Chapter 3, Specifying project options and compiling 117 Link 32·bit .DLL file Command-line equivalent =ffpd TLINK32 generates a 32-bit protected-mode Windows .DLL file. Link 32·bit .EXE file Command-line equivalent = ffpe TLINK32 generates a 32-bit protected-mode Windows .EXE file. Link for 32·bit console application Command-line equivalent =lap . TLINK32 generates a protected-mode executable file that runs in console mode. Link using 32·bit Windows API Command-line equivalent =laa TLINK32 generates a protected-mode executible that runs using the 32-bit Windows API. Command-line options quick reference This section presents two quick reference tables for command-line options. The first table lists command-line options available from the Options I Project menus and dialog boxes, and they're organized function. The second table lists options that are available only from the command line. Table 3.1 Command-line options by function 16-bit Compiler I Calling Convention -p -pc -po -pr Use Pascal calling convention. Use C calling convention. (Default: -pc, -p-.) Use fastthis calling convention for passing this parameter in registers. Use fastcall calling convention for passing parameters in registers. 16-bit Compiler I EntrylExit Code -tW -tWD -tWDE -tWE -tWS -tWSE -W -WD -WDE 118 C++ Use r 's Gu ide Make the target a Windows .EXE with all functions exportable. (Default) Make the target a Windows DLL with all functions exportable. Make the target a Windows .DLL with explicit functions exportable. Make the target a Windows .EXE with explicit functions exportable. Make the target a Windows .EXE that uses smart callbacks (16-bit compiler only). Make the target a Windows .EXE that uses smart callbacks, with explicit functions exportable (16-bit compiler only). Make the target a Windows .EXE with all functions exportable. (Default) (Note there is no space between the -Wand the !.) Make the target a Windows DLL with all functions exportable. Make the target a Windows DLL with explicit functions exportable. Table 3.1 -WE -WS -WSE Command-line options by function Make the target a Windows .EXE with explicit functions exportable. Make the target a Windows .EXE that uses smart callbacks (16-bit compiler only). Make the target a Windows .EXE that uses smart callbacks, with explicit functions exportable (16-bit compiler only). 16-bit Compiler I Memory Model -de Move string literals from data segment to code segment (16-bit compiler only). -F -Ff Uses fast huge pointers. Create far variables automatically. -Ff=size Create far variables automatically; set the threshold to "size" (16-bit compiler only). -Fs Assume DS=SS in all memory models (16-bit compiler only). -me -mh Compile using compact memory model (16-bit compiler only). -ml Compile using huge memory model. Compile using large memory model (16-bit compiler only). -mm Compile using medium memory model (16-bit compiler only). -mm! Compile using medium memory model; assume DS!=SS (16-bit compiler only). (Note: there is no space between the -mm and the !.) Compile using small memory model (16-bit compiler only). (Default) -ms -ms! Compile using small memory model; assume DS! = SS (16-bit compiler only). (Note: there is no space between the -ms and the !.) -Vf Far C++ virtual tables (16-bit compiler only). 16-bit Compiler I Processor -1-1 -2 Generate 8086 compatible instructions. Generate the 80186/286 compatible instructions (16-bit only). Generate 80286 protected-mode compatible instructions (16-bit compiler only). (Default for 16- bit) -3 Generate 80386 protected-mode compatible instructions. (Default for 32-bit) -4 -a -an Generate 80386/80486 protected-mode compatible instructions. Align byte. (Default: -a- use byte-aligning.) Align to "n". l=byte, 2=word (l6-bit = 2 bytes), 4=Double word (32-bit compiler only, 4 bytes) 16-bit Compiler I Segment Names Code -zAname Code class set to "name". -zCname Code segment class set to "name". -zPname Code group set to "name". 16-bit Compiler I Segment Names Data -zBname BSS class set to "name". -zDname BSS segment set to "name". -zGname BSS group set to "name". -zRname Data segment set to "name". -zSname Data group set to "name". Data class set to "name". -zTname 16-bit Compiler I Segment Names Far Data Chapter 3, Specifying project options and compiling 119 Table 3.1 Command-line options by function -zEname -zFname -zHname -zVname -zWname Far segment set to "name". Far class set to "name". Far group set to "name". Far virtual segment set to "name" (16-bit compiler only). Far virtual class set to "name" (l6-bit compiler only). 32-bit Compiler I Calling Convention -p -pc -pr -ps Use Pascal calling convention. Use C calling convention. (Default: -pc, -p-.) Use fastcall calling convention for passing parameters in registers. Use stdcall calling convention (32-bit compiler only). 32-bit Compiler I Processor -3 -4 -5 Generate 80386 protected-mode compatible instructions. (Default for 32-bit) Generate 80386/80486 protected-mode compatible instructions. Generate Pentium protected-mode compatible instructions. C++ Options I C++ Compatibility -K2 -Va -Vb -Vc -Vp -Vt Allow only two character types (signed and unsigned). Char is treated as signed. Compatibility with Borland C++ 3.1 and earlier. Pass class arguments by reference to a temporary variable (16-bit compiler only). Make virtual base class pointer same size as 'this' pointer of the class (l6-bit compiler only). (Default) Do not add the hidden members and code to classes with pointers to virtual base class members (16-bit compiler only). Pass the 'this' parameter to 'pascal' member functions as the first. Place the virtual table pointer after nonstatic data members (16-bit compiler only). C++ Options I Exception Handling -RT -x -xc -xd -xf -xp Enable runtime type information, (Default) Enable exception handling. (Default) Enable compatible exception handling. Enable destructor cleanup. (Default) Enable fast exception prologs. Enable exception location information. C++ Options I Member Pointer -Vmd -Vmm -Vmp -Vms -Vmv Use the smallest representation for member pointers. Member pointers support multiple inheritance. Honor the declared precision}or all member pointer types. Member pointers support single inheritance. Member pointers have no restrictions (most general representation). (Default) C++ Options I Templates -Jg -Jgd -Jgx 120 C++ Use r 's G u ide Generate definitions for all template instances and merge duplicates. (Default) Generate public definitions for all template instances; duplicates result in redefinition errors. Generate external references for all template instances. Table 3.1 Command-line options by function c++ Options I Virtual Tables -v -vo -VI -Vs Use smart c++ virtual tables. (Default) External C++ virtual tables. Public C++ virtual tables. Local C++ virtual tab~es. Compiler I Code Generation -b -d -K -po -r -rd -y -Yo Make enums always integer-sized. (Default: -b- make enums byte-sized when possible.) Merge duplicate strings. (Default) Default character type unsigned. (Default: -K- default character type signed.) Use fastthis calling convention for passing this parameter in registers (l6-bit compiler only). Use register variables. (Default) Allow only declared register variables to be kept in registers. Generate overlay-compatible code. Overlay compiled files. Compiler I Compiler Output -Fc -u -x Generate COMDEFs (16-bit compiler only). Generate underscores. (Default) Disable compiler autodependency output. (Default: -X- use compiler autodependency output.) Compiler I Debugging -k -v -vi -y Tum on standard stack frame. (Default) Check for stack overflow. Include browser information in generated .OBJ files. Tum on source debugging. Control expansion of inline functions. Line numbers on. Compiler I Defines -Dname -Dname=string -Uname Define "name" to the null "string". Define"name" to "string". Undefine any previous definitions of "name". Compiler I Floating Point -f off Emulate floating point. (Default) Fast floating point. (Default) Compiler I Precompiled Headers -H -Hfilename Generate and use precompiled headers. (Default) Sets the name of the file for precompiled headers. Set the name of the file for precompiled headers. Use but do not generate precompiled headers. -H=filename -Hu Compiler I Source -A -AK Use only ANSI keywords. Use only Kernigham and Ritchie keywords. C hap t e r 3, Spee i f yin 9 pro j e c top t ion 5 and com pi lin 9 121 Table 3.1 Command-line options by function -AT -AU -c Use Borland C++ keywords (also -A-). Use only UNIX V keywords. Turn nested comments on. (Default: -C- turn nested comments off.) -in Make significant identifier length to be "n". (Default) Configuration Files @filename Read compiler options from the response file "filename" Messages -gn -jn -w -wxxx Warnings: stop after "n" messages. (Default: 255.) Errors: stop after lin" messages. (Default) Display warnings on. Enable "xxx" warning message. (Default) Messages I ANSI Violations -wbbf Bit fields must be signed or unsigned int. -wbig Hexadecimal value contains more than three digits. (Default) -wdpu Declare type 'type' prior to use in prototype (Default) -wdup Redefinition of 'macro' is not identical. (Default) -wext 'identifier' is declared as both external and static (Default) -wnak Non-ANSI Keyword Used: ' ' (Note: Use of this option is a requirement for ANSI conformance.) -wpin Initialization is only partially bracketed. -wret Both return and return of a value used. (Default) -wstu Undefined structure 'structure' -wsus Suspicious pointer conversion. (Default) -wvoi Void functions may not return a value. (Default) -wzdi Division by zero (Default) Messages I General -Ff=l Array variable 'identifier' is near. (Default) -wamp Superfluous & with function. -wasm Unknown assembler instruction. -will ill-formed pragma. (Default) -wpch Cannot create precompiled header: header. (Default) Messages I Inefficient C++ Coding -winI Functions containing reserved words are not expanded inline. (Default) -wlin Temporary used to initialize 'identifier'. (Default) -wIve Temporary used for parameter 'parameter' in call to 'function' (Default) Messages. I Inefficient Coding -waus 'identifier' is assigned a value that is never used. (Default) -weff Code has no effect. (Default) -wpar Parameter 'parameter' is never used. (Default) 122 C++ Use r '5 G U ide Table 3;1 Command-line options by function -wrch -wstv -wuse Umeachable code. (Default) Structure passed by value. 'identifier' declared but never used. Messages I Obsolete c++ -wobi -wofp -wovl -wpre Base initialization without a class name is now obsolete. (Default) Style of function definition is now obsolete. (Default) Overload is now unnecessary and obsolete. (Default) Overloaded prefix operator 'operator' used as a postfix operator. Messages I Portability -wc1n -wept -wmg -wrpt -wsig -wuep Constant is long. Nonportable pointer comparison. (Default) Constant out of range in comparison. (Default) Nonportable pointer conversion. (Default) Conversion may lose significant digits. Mixing pointers to different' char' types. Messages I Potential c++ Errors -wbei -wdsz -wheh -whid -wibe -wmpe -wmpd -wncf -wnci -wnst -wntd -wnvf Initializing 'identifier' with 'identifier'. (Default) Array size for 'delete' ignored. (Default) Handler for' ' hidden by Previous Handler for' '. 'functionl' hides virtual function 'function2'. (Default) Base class 'basel' is inaccessible because also in 'base2'. (Default) Conversion to type fails for members of virtual base class base. (Default) Maximum precision used for member pointer type type. (Default) Non-const function 'function' called for const object. (Default) The constant member 'identifier' is not initialized. (Default) Use qualified name to access nested type 'type'. (Default) Use '> >' for nested templates instead of I»~'. (Default) Non-volatile function function called for volatile object. (Default) Messages I Potential Errors -wamb -wece -wdef -wnod -wpia -wpro -wrvl Ambiguous operators need parentheses. Condition is always true OR Condition is always false. (Default) Possible use of 'identifier' before definition. No declaration for function 'function'. Possibly incorrect assignment. (Default) Call to function with no prototype. (Default) Function should return a value. (Default) Optimizations -Od Disable all optimizations. Optimizations I Size -0 Optimize jumps. C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 123 Table 3.1 Command-line options by function -Ob Eliminate dead code. -Oe -01 Allocate global registers and analyze variable live ranges. Compact loops. -ow -z Suppress the inc bp / dec bp on windows far functions (16-bit compiler only). Enable register load suppression optimization. Optimizations I Specific -01 Generate smallest possible code (same as using -0, -Db, -Oe, -Og, -Oi, -01, -Om, -Op, -Ot, -Ov, -k-, -Oe, and -Z) -02 Generate fastest possible code. -Oa Optimize assuming pointer expressions are not aliased on common subexpression evaluation. -Oe Eliminate duplicate expressions within basic blocks. -Og Eliminate duplicate expressions within functions. -Ox Generate fastest code; Microsoft compatible. Optimizations I Speed -Oi -Om Expand common intrinsic functions. Move invariant code out of loops. -Op -Ov Propagate copies. Enable loop induction variable and strength reduction. Response Files +filename Use alternate configuration file "filename" Command-line options The following table lists all options that are available only from the command-line. Table 3.2 Command-line options only -B Compiles assembly and calls TASM or TASM32. IfTASM isn't in your path, checking this option generates an error. Also, old versions of TASM might have problems with 32-bit code. -e Compiles and assembles the named .c, .CPP, and .ASM files, but does not execute a link command. -efilename Derives the executable program's name from filename by adding the file extension .EXE (the program name is then filename.EXE). filename must immediately follow the -e, with no intervening whitespace.Without this option, the linker derives the .EXE file's name from the name of the first source or object file in the file name list. -Efilename -Fm -h 124 C++ Use r' s G u ide Use "filename" as the name of the assembler to use. By default, TASM is used. Enables all the other -F options (-Fe, -Ff, and -Fs). You can use it as a handy shortcut when porting code from other compilers. This option offers an alternative method of calculating huge pointer expressions; this method is much faster than the standard method, but must be used with caution. When you use this option, huge pointers are normalized only when a segment wraparound occurs in the offset part. This causes problems with huge arrays if any array elements cross a segment boundary. Table 3.2 Command-line options only -B Compiles assembly and calls TASM or TASM32. If TASM isn't in your path, checking this option generates an error. Also, old versions of TASM might have problems with 32-bit code. -He Cache precompiled headers. Use with -H, -Hxxx, -Hu, or -Hfilename. This option is useful when compiling more than one precompiled header. (32-bit compiler only) -Ix Pass option "x" to the linker (TLINK for BCC and TLINK32 for BCC32). More than one option can appear after the -1 (which is a lowercase L). -ofilename Compile source file to "filename".oBJ. -p Perform a C++ compile regardless of source file extension. (Default) -Pext Perform a C++ compile regardless of source file extension and set the default extension to "ext". This option is available because some programmers use .C or another extension as their default extension forC ++ code. -5 Generate assembler source compiles the named source files and produces assembly language output files (.ASM), but does not assemble. When you use this option, Borland C++ includes the C or C++ source lines as comments in the produced .ASM file. -T- Remove all previous assembler options. -Tstring -tWM -Uname Make a multithreaded application or DLL. Pass "string" as an option to TASM, TASM32, or assembler specified with -E. Undefines any previous definitions of the named identifier "name". -Vo This option is a "master switch" that sets on all of the backward-compatibility options listed in this section. It can be used as a handy shortcut when linking with libraries built with older versions of Borland C++. -Vv This option directs the compiler not to change the layout of any classes (which it needs to do to allow pointers to virtual base class members, which were not supported in previous versions of Borland C++). If this option is used, the compiler will not be able to create a pointer to a member of a base class that can be reached only from the derived class through two or more levels of virtual inheritance (16-bit compiler only). -W Creates a Windows GUI application. -WC Creates a 32-bit console mode application. -WCD Creates q 32-bit console mode DLL with all functions exportable and exported. --WD Creates a GUI DLL with all functions exportable. -WDE Creates a GUI DLL with explicit functions exportable and exported. -weas 'type' assigned to 'enumeration'. (Default) -WM Make a multithreaded application or DLL. -zX* Use default name for X. For example, -zA assigns the default class name CODE to the code segment class. C hap t e r 3, S pee i f yin 9 pro j e c top t ion san d com p iii n 9 125 126 C++ Use r 's G u ide Building Applications with AppExpert AppExpert lets you create ObjectWindows-based Windows applications with features such as a tool bar, a status bar, a menu structure, online Help, and MDI windows. You can also select options to support printing, print preview, aJ;ld document/view. AppExpert works with Resource Workshop, ObjectWindows classes, and the IDE's project manager to form a visual approach to application generation. Creating applications with AppExpert consists of four steps: Use AppExpert to define the user interface and application features and to generate the code. 2 Use ClassExpert to add classes and event handlers, to implement virtual functions, to navigate to existing class source code, and automate classes. ClassExpert can also associate Resource Workshop objects (such as menus and dialog boxes) with classes or handlers. 3 Use Resource Workshop to edit or add resources. 4 Use the project tree to build your application. AppExpert always creates the following files for each application: • • • • • • A database file for the AppExpert source (.APX) that ClassExpert uses A main header file (.H) A main source file (.CPP) A project file (.IDE) A resource header file (.RR) A resource script file (.RC) Depending on which options you choose, AppExpert can create the following files: C hap t e r 4, B u i I din gAp Plie a ti 0 ns wit hAp PEx per t 127 • Help source files (.RTF) • A Help project file (.HPJ) • Icon and bitmap files (.lCO and .BMP) Steps for Creating an Application with AppExpert To create an AppExpert application: 1 Start the IDE and choose File INew IAppExpert. A dialog box appears. 2 Type a name for your project file. By default, most generated files (including the .EXE) are derived from the target name (for example, . cpp). Select a path where you want the AppExpert project and source files to be stored. AppExpert will create the directory if it does not already exist. Click OK. The AppExpert . Application Generation Options dialog box appears. 3 The Application Generation Options dialog box contains a list of topics on the left and a brief description of the topic on the right. You can change options in the dialog box to customize the type of application you want generated. 4 Click the Generate button at the bottom of the Options dialog box. 5 The Generate dialog box appears, asking you to confirm that you want the code generation for your application to begin. Click Yes to generate the code for your application. While AppExpert is generating your application, a message box displays the current status. 6 The project window appears, listing some of the files required for your application (files for bitmaps, icons, and help text are not displayed). You can use ClassExpert to modify your application or you can build it first. To build your application, choose either Project IMake All or Project IBuild All. Hint The application generates and builds faster, if you uncheck unneeded options. Note With AppExpert, you choose your application options once, then generate the code. After you generate the code and resources, you can edit and add to them, but you cannot go back to AppExpert and change options. For example, if you use AppExpert to generate an application that does not contain a status line and then decide to add one. You will need to write code to add that functionality. Application options • Use the AppExpert IApplication options to define the specific characteristics of the application you want to generate. • Use the Customize Application button to open the group (if necessary) and go to the first option in the first subtopic available for the Application section of the AppExpert options. • If you simply want to use the default options, you can generate your application now by pressing the Generate button. 128 c++ User's Guide Application I Window Model The Application I Window Model options determine which model to use for your application and how application objects will be handled. MOl (Multiple Document Interface) The MOl option sets the style of your application to follow the Multiple Document Interface (MOl) model. This model causes child windows to be constrained within the boundaries of the application window. SOl (Single Document Interface) The SOl option sets the style of your application to follow the Single Document Interface (SOl) model. This model supports child windows that can exist outside of the constraints of the application window without being clipped. Dialog Client The Dialog Client option sets the style of your application so that the main (and only) window of your application is a dialog window, making the client area of the application a dialog box. Document/View The Document/View option determines whether your application supports the Document/View model for handling application objects. The Document/View model breaks data handling into two discrete parts: data storage and control, in the document class (derived from TDocument), and data display and manipulation, in the view class (derived from TView). You can use the Document/View option with either SOl, MOl, or Dialog Client applications. Application I Basic Options The Application I Basic Options options define the general characteristics of the application you are going to generate, such as the initial state of the application's main window, and the generation of help files, as well as the directories where files will be stored. If you simply want to use the default options, you can generate your application now by pressing the Generate button. Target Name Use Application I Basic Options I Target Name to name the AppExpert target that will be .used to build your application. This name is the basis for the default names of other elements in your project (e.g., header files, class database, application class, and source files). The default name is the same as the IDE project. You can use this name or enter your . , own. C hap t e r 4, B u i I din gAp Plie a t ion 5 wit hAp PEx per t 129 Base -Directory Use Application IBasic Options IBase Directory to define the main project directory. All other directories associated with the project are placed relatively to this directory. You can enter a directory by entering it yourself or press the Browse button to select one from the Select Directory dialog box. The default base directory is the one you choose in the New AppExpert Project dialog box. The name of this directory is passed to the Project Manager for the new AppExpert target. Application I Basic Options I Features to Include Use the Application IBasic Options IFeatures to Include options to specify which additional user interface elements your application supports. Dockable Toolbar Turn on the Dockable Toolbar option to include a dockable toolbar in your application. Status Line Tum on the Status Line option to place a status line at the bottom of your application's main window. The code generated will display help hints in the status line when menu items are highlighted. Recently Used Files List Tum on the Recently Used Files List option to include a list of the four most recently accessed files under the File menu of your application. Registry Support Tum on the Registry Support option to register your application's icons and document types with the system registry when the application is run. Drag/Drop Tum on the Drag/Drop option to have code generated so that your application will support drag-and-drop actions from File Manager and Explorer. Printing Tum on the Printing option if you want your application to support printing-related activities. The code generated will handle the Print Setup, Print Preview, and Print commands. Mail Support Tum on the Mail Support option to include support for Common Message Call (CMC) mail in your application. 130 C++ Use r 's G u ide Help File Support If you select the Application IBasic Options IInclude Help File Support option, AppExpert will generate RTF source files and a Help project file when it generates your application. The Help project file will be added to the Project Manager project and automatically built with the target application. This Help file contains placeholder text for the menus and menu options present in the generated application. Help File Name Use Application IBasic Options IHelp File Name to specify the name of the help file associated with your application. This file name identifies the source and Help project files. The default value for the file name is the same as the application project. You can also enter your own file name. Application I Advanced Options The Application IAdvanced Options options define some specific characteristics of the application you are going to generate, such as the initial state of the application's main window, and the type of controls the application will use. Application Startup State Use the Application Startup State options to set the initial state of the application's main window. Control Style Use the Control Style options to determine which type of controls the application will use. Application I Advanced Options I Application Startup State Use the Application I Advanced Options I Application Startup State options to set the initial state of the application's main window. Normal (sizeable) Turn on the Normal option to set the application window to start in a default size. This is the default setting. Minimized (iconic) Turn on the Minimized option to set the application window to start in a minimized state (as an icon on the Windows desktop). C hap t e r 4, B u i I din gAp Plie at ion s wit hAp PEx per t 131 Maximized (entire screen) Tum on the Maximized option to set the application window to fill the entire Windows desktop when it starts running. Application I Advanced Options I Control Style ,' Use the Application I Advanced Options. I Control Style options to determine which type of controls the application will use. Standard Windows Tum on the Standard Windows option to specify that the application will use standard Windows controls. This is the default setting. Borland BWCC Tum on the Borland BWCC option to specify that the application will use the Borland custom control style. MS Control 30 Tum on the MS Control 3D option to specify that the application will use the threedimensional Windows controls provided by CTL3DV2.DLL and CTL3D32.DLL. Application I OLE 2 Options Use the Application I OLE 2 Options options to set the behavior of your OLE 2 application. OLE 2 Container Options Choose whether or not you want your application to be an OLE 2 and OCX container application. AppExpert only allows MDI and SDI applications which use the DocView model to be containers. OLE 2 Server Options Choose whether you want your application to be an OLE 2 Server EXE, DLL, or not a server at all. AppExpert only allows MDI and SDI applications which use the DocView model to be servers. Enable Automation in the Application Select the Enable Automation in the Application option if you want your application to be an OLE 2 automation server. Server 10 If you set your application to be an OLE 2 Server, use the Server ID field to specify the identifier for your application. 132 C++ Use r 's G u ide Application I Code Generation Control Use the Application ICode Generation Control options to control various aspects of the code generation process. Target Name Displays the name of the project as defined in Basic Options ITarget Name. Base Directory Displays the base directory for the project as defined in Basic Options IBase Directory. Source Directory Use Application ICode Generation Control ISource Directory to specify the directory where the source files for the application will be placed during code generation. This path is relative to the directory specified as the Base Directory. If an absolute path is specifed, it is converted to a path relative to the Base Directory. You can enter a directory or press the Browse button to select one from the Select Directory dialog box. The default value for the Source Path is the current directory, which is the directory specified in Base Directory. Header Directory Use Application ICode Generation Control IHeader Directory to specify the directory where the header files for the application will be placed during code generation. This path is relative to the directory specified as the Base Directory. If an absolute path is specifed, it is converted to a path relative to the Base Directory. You can enter a directory or press the Browse button to select qne from the Select Directory dialog box. The default value for the Header Path is " . \ whjch causes source files to be placed in the current directory. II , Main Source File Use Main Source File to name the main application source file. The default filename is the name of the project: App. CPP. AppExpert will parse and shorten the project name if it is longer than eight characters, unless the Use Long File Names option is enabled. Main Header File Use Main Header File to name the main application header file. The default filename is the name of the project: App. H. AppExpert will parse and shorten the project name if it is longer than eight characters, unless the Use Long File Names option is enabled. Application Class Use Application Class to name the class that AppExpert will derive from TApplication. The default class name is T App. C hap t e r 4, B u i I din gAp Plie at ion s wit hAp PE x per t 133 About Dialog Class Use About Dialog Class to name the class that AppExpert will derive from TDialog. The default class name is T AboutDlg. Use Long File Names The Use Long File Names option determines whether or not the source files of your application are generated using long file names. Note Some installations of Novell Netware do not support long file names. Comments Use the Comments options to specify how the generated code is documented. Terse Turn on the Terse option to sparsely comment the generated code. Verbose Tum on the Verbose option to heavily comment the generated code. Application I Administrative Options Use the Application IAdministrative Options to specify identifying information that will be placed in a comment block at the beginning of all of the generated project files. Some of the information is also displayed in the About... dialog box of the application. Version Number Use Version Number to provide the version number for the project. This value will be displayed in the application's 1/ About ... " dialog box. The default version number is 1/1.0." Copyright Use Copyright to provide the copyright information for your application. This value will be displayed in the application's 1/ About ... " dialog box and will be placed in all of the comment blocks generated by AppExpert. Description Use Description to provide a description of your application. This value will be displayed in the application's 1/About ... " dialog box. The default value is the name of the project. Author Use Author to provide the name of the programmer who generated the source code. This will be placed in all of the comment blocks generated by AppExpert. 134 C++ Use r 's G u ide Company Use Company to provide the name of the programmer's company. This will be placed in all of the comment blocks generated by AppExpert. Main Window options • Use the AppExpert IMain Window options to control the appearance and operation of the main window of the generated application. • Use the Customize Main Window button to open the group (if necessary) and go to the first option in the first subtopic available for the Main Window section of the AppExpert options. • If you want to simply use the default options, you can generate your application now by pressing the Generate button. Window Title Use Window Title to specify the name that will be displayed as the caption for the application's main window. Main Window I Background Color The Main Window IBackground Color options determine the background color of the application's main window. Use Default Color The Use Default Color options causes no code to be generated to set the main window background color. In this way, the color used will be the current default for the system. Use System Color Constant The Use System Color Constant option sets the background color of the main window to a specified constant. Choose the constant from the list box provided. Use Specified Color The Use Specified Color option sets the background color of the main window to a specified color. Choose the color from the Color dialog. Main Window I Basic Options Use the Main Window IBasic Options to control the general appearance of the main window of your application. C hap t e r 4, B u i I din gAp Plie a t ion 5 wit hAp PE x per t 135 Window Styles Use the Window Styles options to control the appearance of the application's main window, specifying its border style and whether it contains system and control menus. Caption Turn on the Caption radio button to create a single, thin border and a title bar where a caption can be displayed. Border Turn on the Border option to get a single, thin border without a caption for the application's main window. Max Box Turn on the Max Box option to add a maximize button to the right side of the application's main window caption. Min Box Tum on the Min Box option to add a minimize button to the right side of the application's main window caption. Vertical Scroll Turn on the Vertical Scroll option to add a vertical scroll bar to the right side of the application's main window. Horizontal Scroll Turn on the Horizontal Scroll option to add a horizontal scroll bar to the bottom of the application's main window. System Menu Turn on the System Menu option to add a system menu button on the left side of the application's main window caption. Visible Turn on the Visible option to make the application's main window visible. This is the default setting. When this option is off, the WS_VISIBLE style is changed to NOT WS_VISIBLE. Disabled Turn on the Disabled option to disable the application's main window. Thick Frame Turn on the Thick Frame option to place a double border around the application's main window. If this option if off, users cannot resize the main window. 136 C++ Use r 's G u ide Clip Siblings Turn on the Clip Siblings option to protect the siblings of the application's main window. Painting is restricted to that window. Clip Children Turn on the Clip Children option to protect child windows from being repainted by the application's main window. Main Window I SOl Client Window Use the Main Window I SDI Client Window options to define the class that represents the client area of the Single Document Interface main window. These options are only applicable if you select the Single Document Interface option from Application I Window Model options. ClientNiew Class Use Client/View Class to name the class of the SDI client area window or view. Document Class Use Document Class to name the class of the default document. If the Doc/View option in the Application I Window Model options is selected, the default value is TFileDocument; otherwise, Document Class is blank. Description Use Description to describe the class of files associated with the Files of Type List in Windows common file dialog boxes. The default value is All Files (*. *). This value serves as the description for the value entered in Filters. Filters Use Filters to list wildcard file specifications (separated by semicolons) for the file names you want the application to recognize. This value is passed to Windows common file dialog boxes to filter files displayed in the list box of those dialog boxes. The default value is * . *. The values entered in Description serves as the explanation of this value. Default Extension Use Default Extension to specify the default filename extension. This value is passed to Windows common file dialog boxes and added to filenames without extensions. The default value is TXT. Class Name Use Class Name to specify the name AppExpert uses for the class derived from Client/ View Class that represents the client area of the SDI frame window. The default value is T (without the leading "Til). C hap t e r 4, 8 u i I din gAp Plie a t ion s wit hAp PEx per t 137 Source File Use Source File to name the source file that will store the implementation of the class named in Client/View Class. The default value is . CPP. AppExpert will parse and shorten the class name if it is larger than eight characters, unless the Use Long File Names option is enabled. Header File Use Header File to name the header file that will store the definition of the class named in Client/View Class. The default value is . H. AppExpert will parse and shorten the class name if it is larger than eight characters, unless the Use Long File Names option is enabled. Client/View Class Use Main Window I SDI Client I Client/View Class to name the class of the SDI client area or view. The interpretation of this value depends on whether you select the Doc/View option in the Application I Window Model options. If the Doc/View option is not selected, Client/View Class selects the class of the client window; otherwise, Client/View Class selects the class of the view of the default document/view. TEditView (default) TListView TWindowView TEditFile (default) TListBox TWindow This value is automatically mapped to the Doc/View options. For example, if you turn off the Doc/View option, TListView is switched to TListBox. Conversely, if you select the Doc/View option, TListBox changes to TListView. Main Window I MOl Client Window Use the Main Window I MDI Client Window options to describe the class that defines the client window of the Multiple Document Interface main window. These options are only applica~le if you select the Multiple Document Interface option from Application I Window Model options. Client Class Use Client Class to specify the name AppExpert uses for the class derived from TMDIClient that represents the client area of the MDI frame window. The default value is T . Source File Use Source File to name the source file that will store the implementation of the class named in Client Class. The default value is . CPP. AppExpert will parse 138 C++ Use r '5 G U ide and shorten the client class name if it is larger than eight characters, unless the Use Long File Names option is enabled. Header File Use Header File to name the header file that will store the definition of the class named in Client Class. The default value is . H. AppExpert will parse and shorten the client class name if it is larger than eight characters, unless the Use Long File Names option is enabled. Main Window I Dialog Client Window Use the Main Window I Dialog Client Window options to describe the characteristics of an application where the main window is a dialog window. Client Class Use Client Class to specify the name AppExpert uses for the class derived from TDialog that represents the main window of the application. The default value is T . Source File Use Source File to name the source file that will store the implementation of the class named in Client Class. The default value is . CPP. AppExpert will parse and shorten the project name if it is larger than eight characters, unless the Use Long File Names option is enabled. Header File Use Header File to name the header file that will store the definition of the class named in Client Class. The default value is . H. AppExpert will parse and shorten the class name if it is larger than eight characters, unless the Use Long File Names option is enabled. Dialog ID Use Dialog ID to specify the identifier associated with the dialog that functions as the main window of your application. Include a Menu Bar Select Include a Menu Bar if you want a menu bar on your main window. MOl ChiidNiew Options Use the AppExpert I MDI Child/View options to define the class that will define a default child window or document/view of the Multiple Document Interface application: These options are only applicable if you select the Multiple Document Interface option from Application I Window Model options. C hap t e r 4, B u i I din gAp Plie a t ion s wit hAp PE x per t 139 MOl Child Class Use MDI Child Class to name the class derived from TMDIChild that represents the frame of the default MDI child windows. The default value is T MDIChild. Source File Use Source File to name the source file that will store the implementation of the class named in MDI Child. The default value is . CPP. AppExpert will parse and shorten the child class name if it is larger than eight characters, unless the Use Long File Names option is enabled. Header File Use Header File to name the header file that will store the definition of the class named in Client Class. The default value is . H. AppExpert will parse and shorten the child class name if it is larger than eight characters, unless the Use Long File Names option is enabled. MOl ChiidNiew I Basic Options Use the MDI Child/View I Basic Options to define the default child window of an MDI application. MOl Client/View Class Use MDI Child/View I Basic Options I MDI Client/View Class to name the class of the MDI client area or view. The interpretation of this value depends on whether you selected the Doc/View option in the Application I Window Model options. If the Doc/View option is not selected, MDI Client/View Class selects the class of the client window; otherwise, MDI Client/View Class selects the class of the view of the default document/view. TEditView (default) TListView TWindowView TEditFile (default) TListBox TWindow This value is automatically mapped to the Doc/View options. For example, if you tum off the Doc/View option, TListView is switched to TListBox. Conversely, if you select the Doc/View option, TListBox changes to TListView. Document Class Use Document Class to name the class of the default document. If the Doc/View option in the Application I Window Model options is selected, the default value is TFileDocument; otherwise, Document Class is blank. 140 c++ User's Guide Description Use Description to describe the class of files associated with the Files of Type List in Windows common file dialog boxes. The default value is All Files (*. *) . This value serves as the description for the value entered in Filters. Filters Use Filters to list wildcard file specifications (separated by semicolons) for the file names you want the application to recognize. This value is passed to Windows common file dialog boxes to filter files displayed in the list box of those dialog boxes. The default value is * . *. The values entered in Description serves as the explanation of this value. Default Extension Use Default Extension to specify the default filename extension. This value is passed to Windows common file dialog boxes and added to filenames without extensions. The default value is TXT. Class Name Use Class Name to specify the name AppExpert uses for the class derived from the MDI Client/View Class that represents the client area of the MDI frame window. The default value is (without the leading "T"). Source File Use Source File to name the source file that will store the implementation of the class entered in Class Name. The default value is . CPP. AppExpert will parse and shorten the project name if it is larger than eight characters, unless the Use Long File Names option is enabled. Header File Use Header File to name of the header file that will store the definition of the class entered in Class Name. The default value is . H. AppExpert will parse and shorten the class name if it is larger than eight characters, unless the Use Long File Names option is enabled. C hap t e r 4, B u i I din gAp Plie a t ion s wit hAp PEx per t 141 142 C++ User's Guide Managing your classes with ClassExpert ClassExpert lets you create new classes, edit and refine the implementation of classes, and navigate through the source code for existing classes in your AppExpert applications. You cart use ClassExpert with Resource Workshop to associate classes to resources (for example, associating a TDialog class to a dialog resource). ClassExpert displays virtual functions and events for existing classes and checks the ones implemented in your application. You can also use ClassExpert to instantiate and automate classes in your AppExpert project. Starting ClassExpert To start ClassExpert: 1 Open an AppExperCIDE project file by choosing File I Open. 2 Double-click the AppExpert target node (ClassExpert is the default viewer for AppExpert targets), or choose View I ClassExpert. ClassExpert appears, listing the classes and their implementation for your application. The ClassExpert window contains three panes, each with a specific function: • Classes displays the classes used in the application. • Events displays the events handled by the selected class. • Edit lets you view and edit the source associated with the selected class. Chapter 5, Managing your classes with ClassExpert 143 Class Expert Classes pane The Classes pane lists the set of classes known to ClassExpert that are used in the current project. This includes all classes created during code generation and any classes you might have added afterward using ClassExpert. Selecting a class from this list changes the contents displayed in the Events and Edit panes to show the events and source file associated with the selected class. Classes pane SpeedMenu Use the Classes pane SpeedMenu to access frequently used Edit commands. Add New Class Use the Add New Class command from the Classes pane SpeedMenu to create a new class in your application. Choosing this option displays the Add New Class dialog box which you can use to define the new class you are creating. Automate Class Use the Automate Class command from the Classes pane SpeedMenu to expose existing classes in your application to OLE 2 automation. This will cause additional code to be added to your source files to support the automation of the class currently selected in the Classes pane. If the TApplication class is not already exposed, automating a class will automatically automate it. Delete Automation Use the Delete Automation command from the Classes pane SpeedMenu to remove the OLE 2 automation code from the class currently selected in the Classes pane. Choosing this command displays a dialog box warning you that the class will be removed from automation. Click Yes to remove the automation code, or No to cancel the operation. Note This command is only available if the class has already been automated. View Document Templates Use the View Document Templates command from the Classes pane SpeedMenu to create, delete, and view document and view pairings. Choosing this option displays the Document Templates dialog box in which you can define the document templates. This option is only applicable if you selected the Document/View option from the Application IWindow Model settings in AppExpert when you set the options for your application. View Class Info Use the View Class Info command from the Classes pane SpeedMenu to view a summary of the properties of the class currently selected in the Classes pane. Choosing this command displays the Class Info dialog box. 144 c++ User's Guide If the selectedclass is derived from TFrameWindow, you can also use this option to change the client class. Edit Source Use the Edit Source command from the Classes pane SpeedMenu to edit the source file associated with the class currently selected in the Classes pane. Choosing this option opens the source file in an IDE editor window (not in the ClassExpert Edit pane) and positions the cursor on the class constructor. Edit Header Use the Edit Header command from the Classes pane SpeedMenu to edit the header file associated with the class currently selected in the Classes pane. Choosing this option opens the header file in an IDE editor window (not in the ClassExpert Edit pane) and positions the cursor on the class definition. Edit Dialog Use the Edit Dialog command to edit the dialog template associated with the class currently selected in the Classes pane. Choosing this command starts Resource Workshop and loads the associated dialog resource into the Dialog Editor. Note This option is only applicable if the currently selected class is derived from TDialog. Edit Menu Use the Edit Menu command to edit the menu resource associated with the class currently selected in the Classes pane. Choosing this command starts Resource Workshop and loads the associated menu resource into the Menu Editor. Typically, an application has only one menu. ClassExpert Events pane The Events pane contains an outliner list with several categories. The available categories depend on the derivation of the class currently selected in the Classes pane. These are the categories that can be displayed: • Automation (automated classes only) • Command Notifications • Control Notifications (dialog classes only) • Virtual Functions • Windows Messages Events pane SpeedMenu Use the Events pane SpeedMenu to access frequently used ClassExpert commands. Chapter 5, Managing your classes with ClassExpert 145 Add Handler Use the Add Handler option from the Events pane SpeedMenu to create a default member function skeleton in the, source file for the class currently selected in the Classes pane. The source file will appear in the Edit pane. • If you add a handler for a Windows message, ClassExpert adds an entry to the response table whose name is defined by default. The function associated with the handler appears in the edit window with the appropriate default handling. • If you add a handler for a Virtual Function, the function associated with the handler appears in the edit window with the appropriate default handling. • If you add a handler for either Commands or Control Notifications, ClassExpert will prompt you for the function name before adding the entry to the response table. This option is only applicable if the event currently selected in the Events pane is not already handled by a member function of the selected class. Unhandled events and nonoverriden virtual functions will not have a check mark next to them. Delete Handler Use the Delete Handler option from the Events pane SpeedMenu to delete a member function from the event currently selected in the Edit pane. Note The member function is removed, but the code that implements the function is not deleted. You will be warned of this and will need to remove the code. For events, commands, and control notifications, the response table entries are removed. This option is only applicable if the currently selected event has a member function associated with it; the handled event will have a check mark next to it. For dialog classes (those derived from TDialog), you will get these additional commands: . Add Instance Variable Use the Add Instance Variable option from the Events pane SpeedMenu to add an instance variable for the item currently selected in the Events pane. Choosing this option prompts you for the name of the variable. The type of the variable is fixed and determined by the associated controL ClassExpert then adds the following to your application code: • In the header file, a structure declaration is added with an entry for the instance variable. • In the source file, 1 The instance variable is allocated in the class constructor (this associates the ObjectWindows class with the resource object). 2 A static instance of the transfer structure is declared. Note 146 ett This command is only available if the class currently selected in the Classes pane is derived from TDialog. User's Guide Delete Instance Variable Use the Delete Instance Variable option from the Events pane SpeedMenu to delete the instance variable associated with the item currently selected in the Events pane. ClassExpert deletes the following from your code: • The entry from the structure • The pointer variable in the class declaration • The allocation of the class variable associated with the resource control in the constructor If you delete all instance variables from your code, you will have an empty structure and the set transfer buffer call. This information does not affect the rest of your code, so you do not need to delete it manually. Note This command is only available if the class currently selected in the Classes pane is derived from TDialog. For Automation events, you will get these additional commands: Add Data Use the Add Data command to add automation data to the class currently selected in the Classes pane. Choosing this command displays the Automate Data dialog box where you can enter information about the automation data. Note This command is only available for classes that you have exposed to OLE 2 automation using the Automate Class command. Delete Data Use the Delete Data command to remove automation data from the class currently selected in the Classes pane. Note The automation data is removed from the OLE 2 automation symbol table, but the code that implements the data is not deleted. You will be warned of this and will need to remove the code. This option is only applicable if the currently selected class has automation data associated with it and you have selected a data member in the Events pane. View Data Use the View Data command to view the automation data for the class currently selected in the Classes pane. Choosing this command displays the Automate Data dialog box where you can view (but not change) the information about the selected automation data. This option ~s only applicable if the currently selected class has automation data associated with it and you have selected a data variable in the Events pane. Add Method Use the Add Method command to expose an automation method to OLE 2 automation in the class currently selected in the Classes pane. Choosing this command displays the Chapter 5, Managing your classes with ClassExpert 147 Automate Method dialog box where you can enter information about the automation method. Note This command is only available for classes that you have exposed to OLE 2 automation using the Automate Class command. Delete Method Use the Delete Method. command to remove an exposed method selected in the Classes pane from the OLE 2 automation symbol table. Note The automation method is removed from the OLE 2 automation symbol table, but the code that implements the method is not deleted. You will be warned of this and will need to remove the code. This option is only applicable if the currently selected class has an automation method associated with it and you have selected a method in the Events pane. View Method Use the View Method command to view the automation method for the class currently selected in the Classes pane. Choosing this command displays the Automate Method dialog box where you can view the information (but not change it) about the selected . automation method. This option is only applicable if the currently selected class has an automation method associated with it and you have selected a method in the Events pane. Add Property Use the Add Property command to expose a property to OLE 2 automation of the class currently selected in the Classes pane. Choosing this command displays the Automate Property dialog box where you can enter information about the automation property. Delete Property Use the Delete Property command to remove an exposed automation property from the class currently selected in the Classes pane. Note The automation property is removed from the OLE 2 automation symbol table, but the code that implements the property is not deleted. You will be warned of this and will need to remove the code. This option is only applicable if the currently selected class has an automation property associated with it and you have selected a property in the Events pane. View Property Use the View Property command to view the automation property for the class currently selected in the Classes pane. Choosing this comrriand displays the Automate Property dialog box where you can view information about the selected automation property. This option is only applicable if the currently selected class has an automation property associated with it and you have selected a property in the Events pane. 148 c++ User's Guide Events I Automation The Events IAutomation category lists all of the automation data, methods, and properties for the automated ~lass currently selected in the Classes pane. Events I Command Notifications The Events ICommand Notifications category lists all of the commands inherited from the base class of the class currently selected in the Classes pane, as well as command events that can be generated by other objects in the application, such as menus. This list is dynamically updated to reflect any changes you might make to objects that generate commands in your application. Each item in the Command Notifications category expands to two items: Command and Command Enabled. The Command handler causes the associated class to handle the command event, while the Command Enabled handler allows the associated class to control whether the command event is enabled or disabled (grayed). A check mark next to an event indicates that it is handled by the class currently selected in the Classes pane. Events I Control Notifications The Events IControl Notifications category appears only for classes derived from TDialog. This category lists the identifiers for all of the controls in the dialog associated with the class. Each control identifier expands to a list of messages it can send to or receive from the dialog class. A check mark next to an event indicates that it is handled by the class currently selected in the Classes pane. A light gray check mark indicates that one or more of the child events are handled. Events I Virtual Functions The Events IVirtual Functions category lists all of the virtual functions inherited from the base class of the class currently selected in the Classes pane. The contents of this list is fixed for a given class. A check mark next to an event indicates that it is handled by the class currently selected in the Classes pane. Events I Windows Messages The Events IWindows Messages category lists the set of Windows messages. This set includes: • Basic Messages • Other Messages • Win32 Messages • OLE 2 Messages A check mark next to a message indicates that it is handled by the event currently selected in the Events pane. C hap t e r 5, Man a gin 9 you rei ass e s wit h C I ass E x per t 149 ClassExpert Edit pane The Edit pane is an Edit window that supports most of the features of the editor in the IDE. It contains the c++ source file associated with the class currently selected in the Classes pane. You can freely edit the file displayed in the Edit pane, adding, deleting, and modifying code as needed. Edit pane SpeedMenu Use the Edit pane SpeedMenu to access frequently used ClassExpert commands. Use Class Use the Use Class command to generate the code to instantiate a class in your application. Choosing this commands displays the Use Class dialog box that allows you to choose which class you want to instantiate. Using Resean Rescan is a special project tool that examines all the source code listed in your AppExpert project (.IDE file) and updates or rebuilds the project's database (the .APX file) according to what it finds in the source code. Rescan looks for special markers in the source code to reconstruct the AppExpert database file and then starts Resource Workshop to reconstruct information about project resources. IfRescan is successful, the original project database file is renamed to *.~AP and a new database file is created; otherwise, the original database is left as *.APX. You can use Rescan to: • Delete a class • Move a class from one source file to another • Rename a class, handler, instance variable, or dialog ID • Import a class from another AppExpert project • Rebuild a lost or damaged project database (*.APX) file Deleting a class To delete a class: 1 Remove the class source file from the IDE project by selecting the source node, rightclicking the node, and choosing Delete Node. If the class shares a source file with other classes, delete the code related to the class from the source file and delete references to the class from other source files; otherwise, you will get errors during compilation. 2 Select the AppExpert target in the project, right-click it, then choose Special I Rescan. Rescan scans the source files listed as dependencies for the AppExpert target. 150 C++ Use r 's G u ide Resource Workshop scans and updates the resource files. When Rescan is complete, you will return to the updated project file where you can either build your application or use ClassExpert. You can add the deleted class back to the project by adding the class source file (and its associated header file as a dependent node under the class source file) as a dependent of the AppExpert target (use Add Node from the SpeedMenu), then rescanning. 3 Look at the Classes pane in ClassExpert to see that the class is now omitted from the list. Moving a class To move a class from one source file to another: Move (cut and paste) the code or definition of the class to the new source or header file. Be certain to also copy the comments generated by AppExpert or else ClassExpert will be unable to locate the correct location in the new source or header files where the class is referenced or defined. 2 Add the new source file if it is not in the project (and its associated header file as a dependent node under the class source file) as a dependent node of the AppExpert target (use Add Node from the SpeedMenu). If the moved class was in its own source file, you can delete the now-empty source file from the project. 3 Select the AppExpert target in the project, right-click it to view the SpeedMenu, then select Special I Rescan. When Rescan is finished, it returns you to the project window in the IDE. Renaming an AppExpert element To rename a class, event handler function, instance variable, or dialog IO: 1 Use the IDE editor to search and replace all occurrences of the original name with the new name. Be sure to check all source files associated with the project (.CPP, .H, .RC, and.RH files). 2 In the project window, select the AppExpert target, right-click it, then choose Special I Rescan. When Rescan is finished, it returns you to the project window in the IDE. Note After following this procedure, check your #include statements, as well as the #ifdef and #define statements that AppExpert created. Verify that none of these have changed as a result of searching and replacing the name of your class within the source files. Importing a class To import a class from one AppExpert project to another: Move or copy the source and header file that defines the class to the source and header directory of the other project. All source files for a project must be in the C hap t e r 5, Man a gin 9 you rei ass e s wit h C I ass E x per t 151 project's source directory (.CPP file~) or header directory (.H files). These directories were created when you first generated the AppExpert project. (Unless you specified a different source or header directory, your source and header files will be in the same directory as your project [.IDE] file.) 2 Add the class source file as a dependent node under the AppExpert target in the IDE project (use Add Node from the SpeedMenu). 3 Add the header file that contains the class definition as a dependent node under class source file in the AppExpert project (use Add Node from the SpeedMenu). 4 In the project window, select.the AppExpert target, right-click, then choose Special I Rescan. Rebuilding the .APX database file To rebuild a lost or damaged database file (the .APX file): 1 Open the project (.IDE) file that contains the AppExpert target and dependent nodes. 2 Select the AppExpert target, right-click it, then choose Special I Rescan from the SpeedMenu. Rescan automatically creates a new database file using markers and the source code from the AppExpert application. 152 C++ Use r 's G u ide Browsing through your code The Browser lets you search through your object hierarchies, classes, functions, variables, types, constants, and labels that your program uses. The Browser also lets you: • Graphically view the hierarchies in your application, then select the object of your choice and view the functions and symbols it contains. • List the variables your program uses, then select one and view its declaration, list all references to it in your program, or go to where it is declared in your source code. • List all the classes your program uses, then select one and list all the symbols in its interface part. From this list, you can select a symbol and browse as you would with any other symbol in your program. Using the Browser If the program in the current Edit window or the first file in your project has not yet been compiled, the IDE must first compile your program before invoking the Browser. If you try to browse a variable or class definition (or any symbol that does not have symbolic debug information), the IDE displays an error message. If you changed the following default settings on the Project Options dialog box, before you use the Browser, be sure to: 1 . Choose Options I Project. 2 Choose Compiler I Debugging and check • Debug information in OBJs. • Browser reference information in OBJs. 3 Choose Linker I General and check Include Debug Information. 4 Compile your application. C hap t e r 6, B row sin 9 t hr 0 ugh you reo d e 153 Starting the Browser You can start browsing through your code the following ways: • Place your cursor on a symbol in your code and choose Browse Symbol from the Edit window SpeedMenu. • From the main menu or the SpeedBar, and choose one of the following commands: • Search IBrowse Symbol • View IClasses • View IGlobals Browser views The Browser provides the following types of views: • Global Symbols • Objects (Class Overview) • Symbol Declaration • Class Inspection • References Browsing objects (class overview) Choose View IClasses to see an overall view of the object hierarchies in your application, as well as the small details. The Browser draws your objects and shows their ancestor-descendant relationships in a horizontal tree. The red lines in the hierarchy help you see the immediate ancestordescendant relationships of the currently selected object more clearly. To see more detail about a particular object, double-click it. The Browser lists the symbols (the procedures, functions, variables, and so on) used in the object. One or more letters appear to the left of each symbol in the object that describe what kind of symbol it is. See "Browser filters and letter symbols." Browsing global symbols Choose View IGlobals to open a window that lists every global symbol in your application in alphabetical order. To see the declaration of a particular symbol listed in the Browser, use one of the following methods: • Double-click the symbol. • Select the symbol and press Enter. 154 C++ Use r 's G u ide • Select the symbol and choose Browse Symbol from the SpeedMenu. Search The Search input box at the bottom of the window lets you quickly search through the list of global symbols by typing the first few letters of the symbol name. As you type, the highlight bar in the list box moves to a symbol that matches the typed characters. Browser SpeedMenu Once you select the global symbol you are interested in, you can use the following commands on the Browser SpeedMenu: • Edit Source • Browse Symbol • Browse References • Return to Previous View • Toggle Window Mode • Set Options Browsing symbols in your code You can browse any symbol in your code without viewing object hierarchies or lists of symbols first. To do so, highlight or place your cursor on the symbol in your code and choose either • Search IBrowse Symbol from the main menu • Browse Symbol from the Edit window SpeedMenu If the symbol you select to browse is a structured type, the Browser shows you all the symbols in the scope of that type. You can then choose to inspect any of these further. For example, if you choose an object type, you will see all the symbols listed that are within the scope of the object. Symbol declaration window This Browser window shows the declaration of the selected symbol. You can use the following commands on the Browser SpeedMenu: • Edit Source • Browse References • Browse Class Hierarchy • Return to Previous View • Toggle Window Mode C hap t e r 6, B row sin 9 t h r 0 ugh you reo d e 155 Browsing references This Browser window shows the references to the selected symbol. You can use the following commands on the Browser SpeedMenu: • Edit Source • Browse Class Hierarchy • Return to Previous View • Toggle Window Mode • Set Options Class inspection window This Browser window shows the symbols (functions and variables) used in the selected class. Once you select the symbol you are interested in, you can use the following commands on the Browser SpeedMenu: • Edit Source • / Browse Symbol • Browse References • Browse Class Hierarchy • Return to Previous View • Toggle Window Mode • Set Options Browser filters and letter symbols When you browse a particular symbol, the same letters that appear on the left that identify the symbol appear in a Filters matrix at the bottom of the Browser window. The Filters matrix has a column for each letter which can appear in the top or bottom row of the column. Use the filters to select the type of symbols you want to see listed. (You can also use the Browser Options settings to specify the types of symbols you want to see listed.) F T V C ? 156 C++ Use r 's G u ide Function Type Variable Integral constants Debuggable v Note Inherited from an ancestor Virtual method In some cases, more than one letter appears next to a symbol. Additional letters appear to the right of the letter identifying the type of symbol and further describe the symbol: To view all instances of a particular type of symbol Click the top cell of the column. For example, to view all the variables in the currently selected object, click the top cell in the V column. All the variables used in the object appear. To hide all/instances of a particular type of symbol Click the bottom cell of the letter column. For example, to view only the functions and procedures in an object, you need to hide all the variables. Click the bottom cell in the V column, and click the top cells in the F and P columns. To change several filter settings at once Drag your mouse over the cells you want to select in the Filters matrix. Customizing th~ Browser Use the Environment Options dialog box to select the Browser options you want to use. 1 Choose Options IEnvironment. 2 Choose Browser. 3 Specify the types of symbols you want to have visible in the Browser using the Visible Symbols option. 4 Specify how many Browser views you can have open at one time. See single or multiple Browser window mode in the Browser Window Behavior option. C hap t e r 6, Brow sin 9 t h r 0 ugh you reo d e 157 158 C++ Use r 's G u ide Using the integrated debugger No matter how careful you are when you write code, a newly completed program is likely to contain errors, or bugs, that prevent it from running the way you intended it to. Debugging is the process of locating and fixing the errors in your programs. The Borland C++ IDE contains an integrated debugger that lets you debug 32-bit Windows programs from within the IDE. Among other things, the integrated debugger lets you control the execution of your program, inspect the values of variables and items in data structures, modify the values of data items while debugging. You can access the functionality of the integrated debugger through two menus: Debug and View along with Ideal menus and keystrokes. This chapter introduces you to the functionality of the integrated debugger and gives a brief overview of the debugging process. Note The integrated debugger does not support 16-bit Windows or DOS debugging. This functionality is supported by Turbo Debugger. Types of bugs The integrated debugger can help find two basic types of programming errors: run-time errors and logic errors. Run-time errors If your program successfully compiles, but fails when you run it, you've encountered a run-time error. Your program contains valid statements, but the statements cause errors when they're executed. For example, your program might be trying to open a nonexistent file, or it might be trying to divide a number by zero. The operating system detects run-time errors and stops your program execution if such an error is encountered. C hap t e r 7, U sin 9 the i n t e9 rat e d deb u 9 9 e r 159 Without a debugger, run-time errors can be difficult to locate because the compiler doesn't tell you where the error is located in your source code. Often, the only clue you have to work with is where your program failed and the error message generated by the run-time error. Although you can find run-time errors by searching through your program source code, the integrated debugger can help you quickly track down these types of errors. Using the integrated debugger, you can run to a specific program location. From there, you can begin executing your program one statement at a time, watching the behavior of your program with each step. When you execute the statement that causes your program to fail, you have pinpointed the error. From there, you can fix the source code, recompile the program, and resume testing your program. Logic errors Logic errors are errors in design and implementation of your program. Your program statements are valid (they do something), but the actions they perform are not the actions you had in mind when you wrote the code. For instance, logic errors can occur when variables contain incorrect values, when graphic images don't look right, or when the output of your program is incorrect. Logic errors are often the most difficult type of errors to find because they can show up in places you might not expect. To be sure your program works as designed, you must thoroughly test all of its aspects. Only by scrutinizing each portion of the user interface and output of your program can you be sure that its behavior corresponds to its design. As with run-time errors, the integrated debugger helps you locate logic errors by letting you monitor the values of your program variables and data objects as your program executes. Planning a debugging strategy After program design, program development consists of a continuous cycle of program coding and debugging. Only after you thoroughly test your program should you distribute it to your end users. To ensure that you test all aspects of your program, it's best to have a thorough plan for your debugging cycles. One good debugging method involves breaking your program down into different sections that you can systematically debug. By closely monitoring the statements in each program section, you can verify that each area is performing as designed. If you do find a programming error, you can correct the problem in your source code, recompile the program, and then resume testing. Starting a debugging session To start a debugging session: 1 Build your program with debug information. 2 Run your program from within the IDE. 160 C++ Use r 's G u ide When debugging, you have complete control of your program's execution. You can pause the program at any point to examine the values of program variables and data structures, to view the sequence of function calls, and to modify the values of program variables to see how different values affect the behavior of your program. Compiling with debug information Before you can begin a debugging session, you must compile your project with symbolic debug information. Symbolic debug information, contained in a symbol table, enables the debugger to make connections between your program's source code and the machine code that's generated by the compiler. This lets you view the actual source code of your program while running the program through the debugger. To generate symbolic debug information for your project: 1 In the Project window, select the project node. 2 Choose Options I Project to open the Project Options dialog box. 3 From the Compiler I Debugging topic, check Debug Information In OBJs to include debug information in your project .OBJ files. (This option is checked by default.) 4 From the Linker I General topic, check Include Debug Information. This option transfers the symbolic debug information contained in your .OBJ files to the final .EXE file (this option is checked by default)., Adding debug information to your files increases their file size. Because of this, you'll want to include debug information in your files only during the development stage of your project. Once your program is fully debugged, compile your program without debug information to reduce the final.EXE file size. Or you can also use TDSTRIP. Note Not all of the .OBJ files in your project need symbolic debug information-only those modules you need to debug must contain a symbol table. However, since you can't statement step into a module that doesn't contain debug information, it's best to compile all your modules with a minimum of line number debug information during the development stages of your project. Running your program in the IDE Once you've compiled your program with debug information, you can begin a debugging session by running your program in the IDE. By running your program in the IDE, you have control of when the program runs and when it pauses. Whenever the program is paused in the IDE, the debugger takes control. When your program is running under the IDE, it behaves as it normally would: your program creates windows, accepts user input, calculates values, and displays output. During the time that your program is not running, the debugger has control, and you can use its features to examine the current state of the program. By viewing the values of variables, the functions on the call stack, and the program output, you can ensure that the area of code you're examining is performing as it was designed. C hap t e r 7, U5 i n 9 the i n t e9 rat e d deb u 9 9 e r 161 As you run your program through the debugger, you can watch the behavior of your application in the windows it creates. For best results during your debugging sessions, arrange your screen so you can see both the IDE Edit window and your application window as you debug. To keep windows from flickering as the focus alternates between the debugger windows and those of your application, arrange the windows so they don't overlap (tile the windows). With this setup, your program's execution will be quicker and smoother during the debugging session. Specifying program arguments If the program you want to debug uses command-line arguments, you can specify those arguments in the IDE in two ways: First: 1 Choose Options I Environment, then select the Debugger topic. 2 In the Arguments text box, type the arguments you want to use when you run your program under the control of the integrated debugger. Second: Choose Debug I Load. 2 Type your program name and arguments in the Load dialog box. Controlling program execution An important advantage of a debugger is that it lets you control the execution of your program; you can control whether your program will execute a single machine instruction, a single line of code, an entire function, or an entire program block. By dictating when the program should run and when it should pause, you can quickly move over the sections that you know work correctly and concentrate on the sections that are causing problems. The integrated debugger lets you control the execution of your program in the following ways: • • • • Running to the cursor location Stepping through code Running to a breakpoint Pausing your program When running code through the debugger, program execution can be based on lines of source code or on machine instructions. When debugging at the source level, the integrated debugger lets you control the rate of debugging to the level of a single line of code. However, the debugger considers multiple program statements on one line of text to be a single line of code; you cannot individually debug multiple statements contained on a single line of text. In addition, the debugger regards a single statement that's spread over several lines of text as a single line of code. 162 C++ Use r' 5 G u i d e- Running to the cursor location Often when you start a debugging session, you'll want to run your program to a spot just before the suspected location of the problem. At that point, use the debugger to ensure that all data values are as they should be. If everything is OK, you can run your program to another location, and again check to ensure that your program is behaving as it should. To run to a specific source line: 1 In the Edit window, position the cursor on the line of code where you want to begin (or resume) debugging. 2 Run to the cursor location in one of the following ways: • Click the Run To Here button on the SpeedBar. • Choose Run To Current from the Edit window SpeedMenu. To run to a specific machine instruction: 1 After your process is loaded, open a CPU view and position the disassembly pane so that the highlight is on the address to which you want to run. 2 Choose Run To Current from the disassembly pane SpeedMenu. or Click the Run To Here button on the SpeedMenu. When you run to the cursor, your program executes at full speed until the execution reaches the location marked by the cursor in the Edit window, or highlight in the CPU window. When the execution encounters the code marked by the text cursor or highlighted, the debugger regains control and places the execution point on that line of code. The execution point The execution point marks the next line of source code to be executed by the debugger. Whenever you pause your program execution within the debugger (for example, whenever you run to the cursor or step to a program location), the debugger highlights a line of code using a green arrow and colored background (depending on your color setup), marking the location of the execution point. The execution point always shows the next line of code to be executed, whether you are going to step through, step into, or run your program at full speed. If there is no source associated with the code at the current execution point, a CPU window is opened showing the instruction with the instruction at the current execution point. Finding the execution point While debugging, you're free to open, close, and navigate through any file in an Edit window. Because of this, it's easy to lose track of the next program statement to execute, or the location of the current program scope. To quickly return to the execution point, choose Debug ISource At Execution Point or click the SpeedBar button. Even if you've C hap t e r 7, Us in 9 the in t e 9 rat e d deb u 9 9 e r 163 closed the Edit window containing the execution point, Find Execution Point opens an Edit window, and highlights the source code containing the execution point. If there is no source associated with the code at the current execution point, you will get an error stating that no line corresponds to the address. If this happens, you can see the current execution point by opening the CPU window. Stepping through code Stepping is a simple way to move throu.gh your code a little bit at a time. Stepping lets you run your program one line at a time; the next line will not execute until you tell the debugger to continue. You can step until you reach the line in your code that contains the error and then examine the state of the program and its data, view the program output and the value of its variables, or modify or evaluate expressions in your program before you tell the debugger to execute the next line. Using the Statement Step Over and Statement Step Into commands available on the Speedmenu in the Edit window (and the corresponding commands for instruction skipping in the CPU window) or using F7 and FB offer the simplest ways of moving through your program code. While the two commands are very similar, they offer different ways to step through code. When you step, you watch your program execute statements or instructions one at a time. After stepping, the program execution pauses and you can use the debugger to investigate different aspects of your program. The integrated debugger allows you to step through both statements and machine instructions. Most programming errors can be identified by stepping through source, although there will be times when you need th~_greater granularity provided by stepping through machine instructions. Your program need not be compiled with debugging information to step through modules which do not have debugging information. Although statement stepping is usually done in an edit window, you can statement step while in the CPU window. Likewise, it is also possible to instruction step while in an edit window. Statement Step Into The Statement Step Into commands execute a single program statement or instruction at a time. If the execution point is located on a call to a function that was compiled with debugging information, Statement Step Into causes the debugger to step into that function by placing the execution point on the function's first statement or instruction. However, if the execution point is located on a function call that doesn't contain debugging information (a library function, for example), then Statement Step Into runs that function at full speed, (however, Instruction Step Into will actually step into the function) after which the execution point is positioned on the statement following the function call. If the execution point is located on the last statement of a function, Statement Step Into (or a ret instruction) causes the debugger to return from the function, placing the execution point on the line of code that follows the function calL The term single stepping refers to using Statement Step Into to successively run though the statements or instructions in your program code. 164 C++ Use r 's G u ide To choose Statement Step Into, you can: • Click the Step Into SpeedBar button. • Choose Statement Step Into on the Speedbar in the Edit window. • Press F7 under default keyboard mapping. The following example helps explain how single stepping through statements works. Suppose you want to follow the sequence of events through the following two functions contained in a bubble sort program: void bubble( int *ptr, int n) { int i, ji for (i=Oi i *n2) { int temp = *nli *nl = *n2i *n2 = tempi If you load the program into the Edit window and place the cursor on the first for statement in the bubble function, pressing F4 runs the program to that location. Rightclicking and choosing Statement Step Into executes that line of code, and moves the execution point to the next line of code in the program (the second for statement). Choosing Statement Step Into again causes the debugger to execute the second for statement, this time placing the execution point on the line containing the call to the function order: order (ptr+i, ptr+j)i Choosing Statement Step Into a third time calls the function order, causing the debugger to step through that function by placing the execution point on the first line of the function definition: void order (int *nl, int *n2) From here, successive Statement Step Into commands execute the lines of code in that function one at a time. When the execution point is located on the last line in the function, stepping (with either the Step Into or Step Over commands) causes the function to return, which places the execution point on the statement following the function call. In this case, the debugger returns the execution point to the call to order bubble. C hap t e r 7, Us in 9 the in t e9 rat e d deb u 9 9 e r 165 Statement Step Over The Statement Step Over command, like Statement Step Into, lets you execute program statements or instructions one at a time. However, if you issue the Statement Step Over command when the execution point is located on a function call, the debugger runs that function at full speed (instead of stepping into it), then positions the execution point on the statement following the function call. You can choose Statement Step Over: • Click the Step Over button on the SpeedBar. • Choose Statement Step Into on the Speedbar in the Edit window. For example, in the previous bubble sort code, choosing Statement Step Over while the execution point highlights the function call order causes the debugger run order at full speed. The debugger then places the execution point on the statement following the function call, which in this case is the call to order bubble. As you debug, you can choose to step through some functions and step over others. If you know a function performs as it was designed, you can step over calls to that function with confidence that the function call will not cause an error. If, on the other hand, you aren't sure that a function is well behaved, you can choose to step through the function to verify that it works as designed. Debugging member functions and external code If you implement classes in your C++ programs, you can still use the integrated debugger to step through code. The debugger handles member functions the same way it would step through functions in a program that is not object-oriented. You can also step through or step over external code written in any language (including C and C++) as long as the code meets all the requirements for extemallinking and the linked object file contains full Borland symbol debugging contains full Borland symbolic debugging information. Running to a breakpoint You set breakpoints on lines of source code where you want the program execution to pause during a run. Running to a breakpoint is similar to running to a cursor position, in that the program runs at full speed until it reaches a certain source-code location. However, unlike Run To Cursor, you can have multiple breakpoints in your code and you can customize each one so it pauses the program's execution only when a specified condition is met. For more information on breakpoints, see "Examining program data values" on page 181. Pausing the program In addition to stepping over or through code, you can also pause your program while it's running. Choosing Debug IPause Process causes the debugger to pause your program. You can then use the debugger to examine the state of your program with respect to this program location. When you're done examining the program, continue debugging by running as usual. 166 C++ Use r 's G u ide Terminating the program Sometimes while debugging, you'll find it necessary to restart or reset the program from the beginning. For example, you might need to restart the program if you step past the location of a bug, or if variables or data structures become corrupted with unwanted values. Choose Debug I Terminate Process (or press Ctrl+F2) to end the current program run. Terminating a program closes all open program files, releases all memory allocated by the program, and clears all variable settings. However, terminating a program does not delete any breakpoints or watches that you might have set. This makes it easy to resume a debugging session. Using breakpoints You use breakpoints to pause your program execution at designated source code locations during a debugging session or to perform other actions. By setting breakpoints in potential problem areas of your source code, you can run your program at full speed, knowing that its execution will pause at a location you want to debug. When your program execution encounters a breakpoint, the program pauses (before executing the line containing the breakpoint) and the debugger displays the breakpoint line in the Edit window. You can then use the debugger to view the state of your program. Breakpoint behavior falls into two categories: • Unconditional (or simple). The breakpoint is activated whenever the debugger reaches the line in your source or the machine instruction where you set the breakpoint. • Conditional. The breakpoint is activated only when it satisfies the conditions specified on the Breakpoint Conditions/Action Options dialog box and saved in a breakpoint options set. A source breakpoint has to be set on a line or program location that contains executable code. For example, you cannot set a breakpoint on a blank line, comment, or declaration. The IDE keeps track of all your breakpoints during a debugging session and associates them with your current project. You can maintain all your breakpoints from a single Breakpoints window and not have to search through your source code files to look for them. Debugging with breakpoints When you run your program from the IDE, it will stop whenever the debugger reaches the location in your program where the breakpoint is set, but before it executes the line or instruction. The line that contains the breakpoint (or the line that most closely corresponds to the program location where the breakpoint is set) appears in the Edit window highlighted by the execution point. At this point, you can perform any other debugging actions. C hap t e r 7, Us i n 9 the in t e 9 rat e d deb u 9 9 e r 167 Setting breakpoints You can set a breakpoint the following ways: To set an unconditional breakpoint on a line in your source code, use one of the following methods: • Place the insertion point on a line in an Edit window and choose Toggle I Breakpoint from the Edit window SpeedMenu or press F5 (default keyboard setting). • Click the gutter in an Edit window next to the line where you want to set a breakpoint. Setting an unconditional breakpoint To set an unconditional breakpoint on a machine instruction: Highlight a machine instruction in the Disassembly pane in the CPU window. 2 Choose Toggle Breakpoint on the SpeedMenu or press F5 (default keyboard setting). Setting a conditional breakpoint To set a conditional breakpoint on a line or machine instruction: Place the insertion point on a line in an Edit window or highlight a line in the Disassembly pane of the CPU window. 2 Choose Debug I Add breakpoint or choose Add Breakpoint from the SpeedMenu. 3 Complete the information on the Add Breakpoint dialog box. 4 Do one of the following: • Click the Advanced button to display the Breakpoint Conditions/Action Options dialog box. • Supply the conditions and action settings you want. See "Creating conditional breakpoints." • Specify option set in the Options input box. Setting other breakpoints To set other types of breakpoints: 1 Choose Debug I Add breakpoint from anywhere in the IDE or choose Add Breakpoint from the SpeedMenu in an active Edit or· Breakpoint window, or the Disassembly pane of the CPU window. 2 Select a breakpoint type on the Add Breakpoint dialog box and supply any additional information associated with the type of breakpoint selected. 3 Either • Click OK to set an unconditional breakpoint. • Click the Advanced button to display the Breakpoint Conditions/Action Options dialog box. See "Creating conditional breakpoints." 168 C++ Use r' s Gu ide Setting breakpoints after program execution begins . While your program is running, you can switch to the debugger (just like you switch to any Windows application) and set a breakpoint. When you return to your application, the new breakpoint is set, and your application will pause or perform a specified action when it reaches the breakpoint. Creating conditional breakpoints Use a conditional breakpoint when you want the debugger to activate a breakpoint only under certain conditions. For example, you may not want a breakpoint to activate every time it is encountered, especially if the line containing the breakpoint is executed many times before the actual occurrence in which you are interested. Likewise, you may not always want a breakpoint to pause program execution. In these cases, use a conditional breakpoint. To set a conditional breakpoint: Choose Debug IAdd breakpoint to open the Add Breakpoint dialog box (Figure 7.1). Figure 7.1 Add Breakpoint dialog box 2 Select a breakpoint type and supply the applicable information. 3 Click Advanced to display the Breakpoint Conditions / Action Options dialog box. 4 Click Expr. True and enter an expression that tells the debugger when to trigger the breakpoint. If the condition is not met, the debugger ignores the breakpoint along with any of its actions. 5 If you want the breakpoint to activate only while a specific thread is in process, click Thread ID and enter a Thread ID. Otherwise leave Thread ID unchecked. 6 If you want the debugger to activate a breakpoint only after it has been reached a certain number of times, click Pass count and enter the number of passes. Otherwise, your program will pause every time the brea,kpoint is activated. 7 If you want program execution to pause when the breakpoint is activated, click Break (the default). Otherwise, your program will not pause when the debugger activates the breakpoint. S If you want the debugger to perform various actions when the breakpoint activates, use the Actions. settings. Otherwise, click OK. C hap t e r 7, Us i n 9 the i nt e 9 rat e d deb u 9 9 e r 169 Figure 7.2 Breakpoint Conditions/Actions Options dialog box Removing breakpoints You can remove a breakpoint in the following ways: • From an Edit window • From an Edit window or the Disassembly pane of the CPU window • From the Breakpoints window From an Edit window To remove a breakpoint from an Edit window: • Click the gutter in an Edit window next to the line that contains the breakpoint you want to remove. From an Edit window or the Disassembly pane of the CPU window To remove a breakpoint from an Edit window or the Disassembly pane of the CPU window: 1 Place the insertion point on the line or highlight the instruction where the breakpoint is set. 2 Choose Toggle Breakpoint from the SpeedMenu. From the Breakpoints window To remove a breakpoint from the Breakpoints window: 1 Choose View IBreakpoint to display the Breakpoints window. 2 Select one or more breakpoints. 3 Choose Remove Breakpoint(s) from the SpeedMenu. To select multiple breakpoints in the Breakpoints window, hold down the Shift or etr/key as you select each breakpoint. 170 C++ Use r' 5 G u ide Disabling and enabling breakpoints Disable a breakpoint when you prefer not to activate it the next time you run your program, but want to save it for later use. The breakpoint remains listed in the Breakpoints window and available for you to enable when you want. To enable or disable a breakpoint: Choose View I Breakpoint to open the Breakpoints window. 2 Click the checkbox next to the breakpoint to enable it or clear the checkbox to disable it. To disable or enable selected breakpoints: 1 In the Breakpoints window, hold down the Shift or etr/key as you select each breakpoint. 2 Choose Enable/Disable Breakpoints from the SpeedMenu~ To use a breakpoint to disable or enable a group of breakpoints: Choose Debug I Add Breakpoint to open the Add Breakpoint dialog box. 2 Click Options to open the Breakpoint Conditions / Action Options dialog box. 3 Click Enable Group or Disable Group and enter a group name. Viewing and editing code at a breakpoint Even if a breakpoint is not in your current Edit window, you can quickly locate it in your source code. Viewing code at a breakpoint To view the code where a breakpoint is set: 1 Choose View I Breakpoint to display the Breakpoints window. 2 Select a breakpoint. 3 Choose View Source on the Breakpoints window SpeedMenu. The source code displays in an Edit window at the breakpoint line and the Breakpoints window remains active. If the source code is not currently open in an Edit window, the IDE opens a new Edit window. Editing code at a breakpoint To edit the code where a 1;>reakpoint is set: 1 Choose View I Breakpoint to display the Breakpoints window. 2 Select a breakpoint. 3 Choose Edit Source from the Breakpoints window SpeedMenu. Chapter 7, Using the integrated debugger 171 The source code displays in an active Edit window with your cursor positioned on the breakpoint line, ready for you to edit. If the source code is not currently open in an Edit . window, the IDE opens a new Edit window. Resetting invalid breakpoints A breakpoint must be set on executable code, otherwise it is invalid. For example, a breakpoint set on a comment, a blank line, or a declaration is invalid. A common error is to set a breakpoint on code that is conditionalized out using #if or #ifdef. If you set an invalid breakpoint and run your program, the debugger displays an Invalid Breakpoint dialog box. To reset an invalid breakpoint: 1 Close the Invalid Breakpoint dialog box. I 2 Find the invalid breakpoint in the Breakpoints window and delete it. 3 Set the breakpoint in a proper location and continue to run your program. If you ignore the Invalid Breakpoint (by dismissing the dialog box) and then choose Run, the IDE executes your program, but does not enable the invalid breakpoint. Using breakpoint groups The integrated debugger lets you group breakpoints together so you can enable or disable several breakpoints with a single action. Creating a breakpoint group To create a breakpoint group: 1 Choose Debug I Add Breakpoint to open the Add Breakpoint dialog box. 2 Enter a name in the Group input box. Disabling or enabling a breakpoint group To disable or enable a group of breakpoints by using another breakpoint's option: 1 Choose Debug I Add Breakpoint to open the Add Breakpoint dialog box. 2 Click Options to open the Breakpoint Conditions/ Action Options dialog box. 3 Click Enable Group or Disable Group and enter a group name. To remove a breakpoint from a group, select the group name and press Delete. Using breakpoint option sets To quickly specify the behavior of one more breakpoints as you create or modify them, store breakpoint settings in an option set. 172 C++ Use r 's Gu ide Creating a breakpoint option set To create an option set: 1 Choose Debug IBreakpoint options to open the Breakpoint Conditions/Action Options dialog box. 2 Enter the conditions and actions. See uCreating conditional breakpoints." 3 Click Add. 4 Enter a name the dialog box that displays and click OK. You can also create an option set when you create or edit a breakpoint. Associating a breakpoint with an option set To associate a breakpoint with an option set: • Enter the Option name in the Add or Edit Breakpoints dialog box. Changing breakpoint options To change the conditions and actions of a breakpoint: 1 Choose View I Breakpoint to open the Breakpoints window. 2 Double-click on a breakpoint or choose Edit Breakpoint from the SpeedMenu. 3 Change the option set in the Options input box on the Edit Breakpoint dialog box. or Supply new information as described in uCreating conditional breakpoints." Changing the color of breakpoint lines To use colors to indicate if a breakpoint is enabled, disabled, or invalid: 1 Choose Options IEnvironment. 2 Select Syntax Highlighting and choose Customize. 3 From the Element list, select the following breakpoint options you want to change: • Enabled Break • Disabled Break • Invalid Break 4 Select the background (BG) and foreground (FG) colors you want. S If you want highlighting, choose DefaUlt Color. C hap t e r 7, Us i n 9 the in t e 9 ra ted deb u 9 9 e r 173 Using the Breakpoints window The Breakpoints window lists all breakpoints currently set in the loaded project (or the file in the active Edit window if a project is not loaded) and contains a tab for each of the following types of breakpoints: • To display the Breakpoints window, choose View I Breakpoint (Figure 7.3). Figure 7.3 Breakpoints window The Breakpoints window lets you perform the following actions: • Click the checkbox beside a breakpoint to enable it or clear the checkbox to disable the breakpoint. • Double-click or press Enter on a breakpoint to open the Edit Breakpoint dialog box to change breakpoint settings. • Choose a command from the Breakpoint Window SpeedMenu. About the Breakpoints window The Breakpoints window provides the following information about each breakpoint: • Name of the source code file in which the breakpoint is set (for source breakpoints). • Location (such as line number, file name, module, thread ID, or address number) where the breakpoint is set. • Current state of the breakpoint: Verified The breakpoint is legal and validated when the process was loaded. Unverified The process has not been loaded since you added the breakpoint. Invalid The breakpoint is illegal. The line on which you set the breakpoint does not contain executable coae (such as a blank line, comment, or declaration) and the debugger will ignore it. • Number of times the debugger must reach the breakpoint before activating the breakpoint. This information appears after a breakpoint has been activated. 174 C++ User's Guide • Associated option set and group name as well as the conditions/ action options specified. See "Creating conditional breakpoints." • Last Event Hit shows the last breakpoint that was encountered. Integrated debugger features Add breakpoint Use the Add Breakpoint dialog box to create a breakpoint. The options that appear in the middle of the dialog box change according to the breakpoint type selected: • • • • Source Address Data Watch C++ Exception • as Exception • Thread • Module The following options always display on the right side of the dialog box: • Qualifiers • Other If you want to set conditions and actions that control breakpoint behavior, click Advanced to open the Breakpoint Conditions / Action Options dialog box. Qualifiers Contains the following options:. Program Module Causes a breakpoint to activate only in a specific executable (.EXE) program. Leave it blank if you want a breakpoint to activate in all loaded processes. Causes a breakpoint to activate only when conditions are satisfied within a specific dynamic-link library (DLL). Leave this setting blank if you clicked Module under Breakpoint type. Other Contains the following options: Options Group Indicates the name of the option set that defines breakpoint behavior. Indicates the name of group to which the breakpoint belongs. Source breakpoint Sets a breakpoint on a line in your source code. File Indicates the file that contains the source code where the breakpoint is set. C hap t e r 7, Us in 9 the in t e 9 rat e d deb u 9 9 e r 175 Line # Indicates the line in the source file on which the breakpoint is set. H you select a line of code in an Edit window and choose Add Breakpoint from the SpeedMenu, the debugger completes these settings for you. Address breakpoint Sets a breakpoint on a a machine instruction. Offset Indicates the address of the machine instruction on which the breakpoint is set. Data watch breakpoint Use a Data Watch breakpoint to pause your program when a specific location in memory changes value. Data Watch breakpoints (also called watchpoints.or changed memory breakpoints) let you monitor expressions that evaluate to a specific data object or memory location. Data watch breakpoints are monitored continuously during your program's execution. Because the debugger checks the breakpoint conditions after the execution of every machine instruction, data watch breakpoints are excellent tools for pinpointing code that is corrupting data. Address Enter a specific starting address or any symbol (such as a variable or a class data member) that evaluates to an address. Length When entering an expression symbol, you can also enter a count of the number of bytes you want monitored. For example, coding in C, suppose you have declared the following array: int string [81] i You can watch for a change in the first ten elements of this array by entering the following item into the Condition Expression input box: &string[O] , 40 The area monitored is 40 bytes long which equals ten elements in the array (an int is 4 bytes). c++ exception breakpoint Sets a breakpoint that pauses you program when it throws or catches a C++ exception. Type Specifies the data type (such as int,long, char, or a class name) used with the exception. 176 C++ Use r' s Gu ide Stop on Throw Pauses program execution when an exception is thrown. Stop on Catch Pauses program execution when an exception is caught. OS exception breakpoint Sets a breakpoint that pauses you program when it throws or catches an operating system defined exception. Exception # Specifies the integer value assigned to the exception. Pick from the list that provides the most common as exceptions or enter one defined in your application. Thread breakpoint Sets a breakpoint on a specified thread. Programs will pause on thread creation and thread destruction. Thread Specifies the thread ID on which the breakpoint is set. Program execution pauses whenever the thread is created. • To obtain a thread ID, choose View I Process. Module breakpoint Sets a breakpoint in a specified DLL. Module Name Specifies the name of a DLL in which the breakpoint is set. The debugger activates the breakpoint each time the DLL startup code (as defined in DllEntryPoint) is executed. For example, if the Break action is on (the default), program execution will pause whenever your program attaches or detaches the DLL. Breakpoint Conditions/Action Options Use this dialog box to • Specify settings that control the behavior of one or more breakpoints, such as the conditions under which a breakpoint is activated and the type of actions that take place when it does. C hap t e r 7, Us i n 9 the in t e 9 rat e d deb u 9 9 e r 177 • Enable and disable breakpoint groups To display this dialog box, use any of the following methods: • Choose Debug IBreakpoint Options. • Choose Debug IAdd Breakpoint and click the Advanced button on the Add Breakpoint window. • Choose View IBreakpoint and double-click a breakpoint listed in the Breakpoints window. Then click the Advanced button on the Edit Breakpoint window. The Breakpoint Conditions / Action Options dialog box contains the following options: Names Conditions Actions Lists the names of Option Sets that have been created. Provides settings that determine when and where a breakpoint is activated. Provides settings that determine what actions take place when a breakpoint is activated. Names (Breakpoint Conditions/Action Options) Lists the names of existing option sets. Use the checkbox next to each option set to enable or disable it. For example, if you clear the checkbox next to an option set called MyOptionSet, the debugger ignores its settings and all breakpoints that use this option set behave like unconditional breakpoints. To reactivate the breakpoint settings in MyOptionSet so that they will used by the debugger, click its checkbox. Conditions (Breakpoint Conditions/Action Options) This group of settings determines when and where a breakpoint. is activated: Expr. True ThreadID Pass Count Each time the debugger encounters the breakpoint, it evaluates an expression to determine if the breakpoint should activate. Activates a breakpoint only while a specific thread is in progress. Indicates the number of times the debugger encounters the breakpoint line before it activates. • Click Add or Delete to create or remove an option set. Expr. True (Breakpoint Conditions/Action Options) Enter the expression you want to evaluate each time the debugger reaches the breakpoint. If the expression becomes true (nonzero) when the breakpoint is encountered, the debugger activates the breakpoint and carries out any actions specified for it. You can enter a Boolean expression that, for instance, tests if a value falls within a certain range or if a flag has been set. For example: If you enter the expression x 178 == 1 c++ Use r' s Gu ide the debugger activates the breakpoint only if x has been assigned the value 1 ~t the time the breakpoint is encountered. If you enter the expression x > 3 and select Break, when the debugger reaches the breakpoint, your program pauses if the current value of x is greater than 3. Otherwise, the breakpoint is ignored. Thread 10 (Breakpoint Conditions/Action Options) Programs written for 32-bit operating systems consist of one or more executable threads. You can set a breakpoint on a specific thread, even though the code at the breakpoint location is shared by multiple threads. Unless specified, a breakpoint is set for all program threads. Use this option to prevent a breakpoint from activating unless a specified thread is running. When the debugger reaches the breakpoint, it will not be activated unless the thread is in progress. If you leave this option blank, the breakpoint may activate while any thread is in progress. Pass Count (Breakpoint Conditions/Action Options) This option includes the following settings: Vpto Current Specifies the number of times you want debugger to reach the breakpoint before it is activated. Shows the actual number of times the debugger has reached the breakpoint so far. You can change this setting if you want to. Conditional breakpoint example If Break is checked and you enter the expression x>3 and you enter 2 in the Pass Count box, your program will not stop until the second time the debugger reaches the breakpoint (that is, when the value of x is greater than 3). Actions (Breakpoint Conditions/Action Options) This group of options lets you specify the actions you want carried out each time the breakpoint is activated: Break Stop Log Start Log Log Expr EvalExpr Log Message Enable Group Disable Group Pauses program execution Stops posting debugger generated messages Starts posting debugger generated messages Displays the value of an expression in the message window Evaluates an expression Displays a message in the message window Reactivates a group of breakpoints Disables a group of breakpoints C hap t e r 7, Us i n 9 the in t e 9rat e d deb u 9 9 e r 179 Break (Breakpoint Conditions/Action Options) Click Break (the default) to pause program execution when the debugger activates the breakpoint. Clear this checkbox if you do not want your program to pause at the breakpoint. Stop Log (Breakpoint Conditions/Action Options) Stops displaying debugger messages in the Runtime Tab of the Message window when the breakpoint is activated. Start Log (Breakpoint Conditions/Action Options) Starts displaying debugger messages in the Runtime Tab of the Message window when the breakpoint is activated. Log Expr (Breakpoint Conditions/Action Options) Click Log Expr if you want to display the value of an expression in the Runtime tab of the Message window. Then, enter the expression in the input box next to it. The debugger logs the value each time the breakpoint activates. Use this option when you want to output a value each time you reach a specific place in your program- this technique is known as instrumentation. For example, you can place a breakpoint at the beginning of a routine and set it to log the values of the routine arguments. Then, after running the program, you can determine from where the routine was called, and if it was called with erroneous arguments. This will give you no idea where it was called from, but will tell you what the arguments are. When you log expressions, be careful of expressions that unexpectedly change the values of variables or data objects (side effects). Eval Expr (Breakpoint Conditions/Action Options) Click Eval Expr if you want the breakpoint to evaluate an expression. Then, enter an expression in the input box next to it. Use an expression that changes the value of a variable or data object (side effects), or this is a waste of time. By "splicing in" a piece of code before a given source line, you can effectively test a simple bug fix; you do not have to go through the trouble of compiling and linking your program just to test a minor change to a routine. You cannot use this technique to directly modify your compiled program. Log Message (Breakpoint Conditions/Action Options) Click Log Message if you want the breakpoint to display a message in the Runtime tab of the Message window when the breakpoint is activated. Then, enter the text of the message in the input box next to it. 180 c++ Use r' s G u ide Disable Group (Breakpoint Conditions/Action Options) Click Disable Group if you want the breakpoint to disable a group of breakpoints. Then, enter a group name in the input box next to it. When a group of breakpoints is disabled, the breakpoints are not erased, they are simply hidden from th:e debugger until you enable them. Enable Group (Breakpoint Conditions/Action Options) Click Enable Group if you want the breakpoint to reactivate a group of breakpoints that have been previously disabled. Then, enter a group name in the input box next to it. Add Breakpoint Conditions/Action Option Set. .. Enter a name for the option set and click OK to create a new set of options based on the current settings in the Breakpoint Conditions/Action Options dialog box. Edit Breakpoint dialog box Use this dialog box to modify an existing breakpoint. The options that appear on left side of the dialog box change according to the breakpoint type selected. The integrated debugger provides the following types of breakpoints: • • • • Source Address Data Watch C++ Exception • as Exception • Thread • Module The following options always display on the right side of the dialog box: • Qualifiers • Other If you want to set conditions and actions that control breakpoint behavior, click Advanced to open the Breakpoint Conditions/Action Options dialog box. Examining program data values Even though you can discover many interesting things about your program by running and stepping through it, you'll usually need to examine the values of program variables to uncover bugs. For example, it's helpful to know the value of the index variable as you step though a for loop, or the values of the parameters passed to a function call. After you have paused your application within the integrated debugger, you can examine the different symbols and data structures with regard to the location of the current execution point. C hap t e r 7, Usin 9 the i n t e 9rat e d deb u 9 9 e r 181 You can view the state of your program by: • • • • • Watchlngprogram values Inspecting data elements Evaluating expressions Viewing the low-level state of your program Viewing the functions in the Call Stack window You can also use the Browser to view the global variables and classes contained in your program. MQdifying program data values Sometimes you will find that a programming error is caused by an incorrect data value. Using the integrated debugger, you can test a "fix" by modifying the data value while your program is running. You can modify program data values using: • • • • • The Evaluate dialog box The Inspector window's Change SpeedMenu command A breakpoint's Evaluate action The CPU window's Dump pane The Register & Stack window Understanding watch expressions You use watches to monitor the changing values of variables or expressions during your program run. After you enter a watch expression, the Watch window displays the current value of the expression. Each time your program pauses (such as when it encounters a breakpoint), the value of the watch changes to reflect the current value of the expression according to the values of the variables in your program. Using the Watches window To display the Watches window, choose View IWatch. Figure 7.4 Watches window The Watches window lists the watches you are currently monitoring. Check the checkbox beside a watch to enable it. Clear the checkbox beside a watch to disable it. 182 C++ Use r 's G u ide Note The Watches window will be blank if you have not added any watches. The left side of the Watches window lists the expressions you enter as watches and their corresponding data types and values appear on the right. The values of compound data objects (such as arrays and structures) appear between braces ({ }). Note If the execution point steps out of the scope of a watch expression, the watch expression is undefined. When the execution point re-enters the scope of the expression, the Watches window again displays the current value of the expression. Formatting watch expressions You can format the display of a watch expression using the Watch Properties dialog box. By default, the debugger displays integer values in decimal form. However, by checking the Hexadecimal button in the Watch Properties dialog box, you can specify that an integer watch be displayed as hexadecimal. You can also vary the display of the watches using the Display As buttons in the Watch Properties dialog box. For more on these buttons, refer to the online Help. To format a floating-point expression, click the Floating Point button, then indicate the number of significant digits you want displayed in the Watch window by typing this number in the Significant Digits text box. If you're setting up a watch on an element in a data structure (such as an array), you can display the values of consecutive data elements. For example, suppose you have an array of five integers named xarray. Type the number 5 in the Repeat Count text box of the Watch Properties dialog box to see all five values of the array. You can also format watch expressions using the expression format specifiers shown in Table 7.1 on page 186. Format specifier settings override any settings specified in the Watch Properties dialog box. Format specifiers use the following syntax: expression [,format_specifier] Adding a watch You can add a watch using either of the following methods: • Place the insertion point on a word in an Edit window and choose Watch from the Edit window SpeedMenu. The debugger adds a watch on the expression at the insertion point and opens the Watches window. • Use the Add Watch dialog box to create a watch expression on any variable or expression available to the program you are debugging. Add Watch dialog box The Add Watch dialog box lets you monitor the value of both simple variables (such as integers) and compound data objects (such as arrays). In addition, you can watch the values of calculated expressions that do not refer directly to memory locations. For example, you could watch the expression x * y + 4. C hap t e r 7, U sin 9 the i n t e 9 rat e d deb u 9 9 e r 183 To create a watch expression using the Add watch dialog box: Choose Debug I Add watch or choose Add watch from the Watches window SpeedMenu.. Figure 7.5 Add watch dialog box 2 Enter an expression into the Expression input box. 3 Click OK to add the watch or choose any of the following optional settip.gs: Note • Program • ThreadID • Advanced After you add the watch expression, the IDE automatically opens the Watches window if it is not already open. Changing watch properties To change the properties of a watch: 1 Choose Vie~ I Watch, to open the Watches window. 2 Double-click a watch to open the Edit Watch dialog box. Figure 7.6 184 C++ Use r 's G u ide Edit Watch dialog box Edit Watch dialog box Use this dialog box to change the settings for a watch expression: 1 Either accept or change the information in either of the following options: • Program • ThreadID 2 Either • Choose OK to save your changes and close the dialog box. .. Click Advanced to open the Watch Properties if you want to change how a watch expression displays in the Watches window. Disabling and enabling watches Evaluating many watch expressions can slow down the process of debugging. Disable a watch expression when you prefer not to view it in the Watches window, but want to save it for later use. To enable or disable a watch: 1 Choose View I Watch to open the Watch window. 2 Either • Click the checkbox next to a watch to enable it. • Clear the checkbox next to a watch to disable it. To disable or enable selected watches: Hold down the Shift or Ctfl key and click on one or more watches in the Watch window. 2 Choose Enable or Disable watches from the Watch window SpeedMenu. Deleting a watch You can delete a watch the following ways: 1 Choose View I W~tch to display the Watches window. 2 Select one or more watch expressions. (To make multiple selections, hold down the Shift or Ctrl key and click.) . 3 Choose Remove Watch(es) on the SpeedMenu. Evaluating and modifying expressions You can evaluate expressions using the ExpI'ession Evaluator dialog box. The Expression Evaluator dialog box has the advantage that it lets you change the values of variables and items in data structures during the course of your debugging session. This C hap t e r 7, Us i n 9 the in t e 9 rat e d deb u 9 9 e r 185 can be useful if you think you've found the solution to a bug, and you want to try it out before exiting the debugger, changing the source code, and recompiling the program. Evaluating expressions Choose Debug IEvaluate to open the Expression Evaluator dialog box. By default, the token at the cursor position in the current Edit window is placed in the Expression text box. You can accept or modify this expression, enter another one, or choose an expression from the history list of expressions you've previously evaluated. Figure 7.7 Evaluator dialog box To evaluate the expression, click the Evaluate button. Using this dialog box, you can evaluate any valid language expression, except ones that contain • Local or static variables that are not accessible from the current execution point • Symbols or macros defined with #define When you evaluate an expression, the current value of the expression is displayed in the Result field of the dialog box. If you need to, you can format the result by adding a comma and one or more format specifiers to the end of the expression entered in the Expression text box. Table 7.1 details the legal format specifiers. Table 7.1 186 Expression format specifiers HorX Integers C Char, strings D Integers Fn Floating point nM All C++ Use r '5 G U ide Hexadecimal. Shows integer values in hexadecimal with the Ox prefix, including those in data structures. Character. Shows special display characters for ASCn 0-31. By default, such characters are shown using the appropriate C escape sequences (In, It, and so on). Decimal. Shows integer values in decimal form, including those in data structures. Floating point. Shows n significant digits (where n is in the range of 2-18, and 7 is the default). Memory dump. Shows n bytes starting at the address of the indicated expression. If n is not specified, it defaults to the size in bytes of the type of the variable. By default, each byte shows as two hex digits. The C, D, H, 5, and X specifiers can be used with M to change the byte formatting. Table 7.1 P Expression format specifiers (continued) Pointers R Structures, unions S Char, strings Pointer. Shows pointers as seg:ofs instead of the default Ptr(seg:ofs). It tells you the region of memory in which the segment is located, and the name of the variable at the offset address, if appropriate. StructurelUnion. Shows both field names and values such as (X:1;Y:10;Z:5) instead of (1,10,5). String. Shows ASCn ~31 as C escape sequences. Use only to modify memory dumps (see nM above). For example, to display a result in hexadecimal, type , H after the expression. To see a floating-point number to 3 decimal places, type , F3 after the expression. You can also use a repeat count to reference a specific number of data items in arrays and structures. To specify a repeat count, follow the expression with a comma and the number of data items you want to reference. For example, suppose you declared the following array in your program: int my_array[lO]i The following expression evaluates the first 5 elements of this array and displays the result in hexadecimal: my_array, 5h Modifying the values of variables Once you've evaluated a variable or data structure item, you can modify its value. Modifying the value of data items during a debugging session lets you test different bug hypotheses and see how a section of code behaves under different circumstances. To modify the value of a data item: 1 Open the Expression Evaluator dialog box and enter the name of the variable you want to modify into the Expression input box. 2 Click Evaluate to evaluate the data item. 3 Type a value into the New Value text box (or choose a value from the drop down list), then click Modify to update the data item. Note When you modify the value of a data item through the debugger, the modification is effective for that specific program run only; the changes you make through the Expression Evaluator dialog box do not affect your program source code or the compiled program. To make your change permanent, you must modify your program source code in the Edit window, then recompile your program. Keep these points in mind when you modify program data values: • You can change individual variables or elements of arrays and data structures, but you cannot change the entire contents of an array or data structure. • The expression in the New Value text box must evaluate to a result that is assignment-compatible with the variable to which you want to assign it. A good guideline is that if the assignment would cause a compile-time error, it's not a legal modification value. C hap t e r 7, Us in 9 the in t e9 rat e d deb u 9 9 e r 187 Warning! Modifying values (especially pointer values and array indexes), can have undesirable effects because you can overwrite other variables and data structures. Use caution whenever you modify program values from the debugger. Inspecting data elements You can use inspect windows to examine and modify data values. Inspect windows are extremely useful because they format the data according to the type of data being viewed; there are different types of Inspect windows for scalars, arrays; structures, functions, and classes with and without member functions. The easiest way to inspect a data item is to highlight the expression you want to inspect (or just position the text cursor on the token) in the Edit window, and choose Inspect Object from the SpeedMenu (or press Alt+F5). If you inspect expressions using this method, the expression is always evaluated within the scope of the line on which the expression appears. You can also inspect data expressions using the following method, 1 Choose Debug IInspect to display the Inspect Expression window. 2 Type in the expression you want to inspect, or choose a previously entered expression from the drop down list. 3 Choose OK to display an Inspector window. If the execution point is in the scope of the expression you're inspecting, the value appears in the Inspect window. If the execution point is outside the scope of the expression, the value is undefined. If you're inspecting a compound data item, such as an array or a structure, you can view the details of the data item by opening another Inspect window on the element you want to inspect. To inspect an element of a compound data item: 1 In the Inspect window, select the item you want to inspect. 2 Choose Inspect on the Inspect window SpeedMenu, or press Enter. You can also use Inspector windows to change the value of a single data item: 1 Select the data item whose value you want to modify. 2 Choose Change on the Inspect window SpeedMenu. 3 Type the new value into the Change Value dialog box and click OK. If you're inspecting a data structure, it's possible the number of items displayed might be so great that you'll have to scroll in the Inspector window to see data in which you're interested. For easier viewing, you can narrow the display to a range of data items: 1 Left-click in the Inspect window and choose Set Range from the SpeedMenu. 2 In the Starting'Index text box, enter the index of the first item you want to view. 3 In the Count text box, enter the number of items you want to see in the Inspect window. 188 C++ Use r 's G u ide Displaying low-level information about a running program The CPU window consists of five separate panes. Each pane gives you a view into a specific low-level aspect of your running application: • The Disassembly pane displays the assembly instructions that have been disassembled from your application's machine code. In addition, the Disassembly pane displays the original program source code above the associated assembly instructions. • The Dump pane displays a memory dump of any memory accessible to the currently loaded executable module. By default, memory is displayed as hexadecimal bytes. • The Stack pane displays the current contents of the program stack. By default, the stack is displayed as hexadecimal bytes. • The Registers pane displays the current values of the CPU registers. • The Flags pane displays the current values of the CPU flags. Each pane has an individual SpeedMenu that provides commands specific to the contents of that pane. Figure 7.8 CPU window ; 00401231 ret Olt0010 :WinUain{HINSTANCE.,....... *,HINSTANCE,- *, : l1bello,cpp. 256: int PASCAL iinHain( ., : 004.01234 push ebp : 00401235 mav eb as , : whel.la,app, 259: Main; :hln51tance '" hI e.u;. [ebp+OxOS] : 0040123. mav ;004.0123D mov Main;:hlnstanae.eax ;whello.cpp. 26·0 ; Me.ln::hPxeY'Instance : 00401242 mav edlt. [ebp+OltOc] : 00401245 mav. (Ma~n: ;hPreV'ln51tance] : whel.lo.cpp, 261: Mal,n: :nCllldShaw = nC eclt,{ebp+Ox14] ,0040124B maY' ; 0040124E mov tMain" nClltdShow] eclt : whe110. cPP. 268: if· ( . i Main::h:i-evI ,004.01254 ~mp dword ptr [Mal,Xl,;hPr E1Ut 00400000 EEl 8l559F74, ECX8155671S EDX 81559D48 ESI 004.02020 EDl 00000000 EBP 00e8FE30 ESP 00eSE'E04 EIP 00401234 EFL 00000293 CS 0137 o68FE30 06BFE2C 00425810 OeSFE28 0068FF6B og~~~~~6~~~:R~b~ 006BFE1C S1559EF4 00&SFElSS155A038 0068FE14 OOOOOOOA 00G8FEIO 81559F74 . . . . . , 0068FEOC 00000000 . ,X, .. U, e.u, t.U . Resizing the CPU window panes You can customize the layout of the CPU window by resizing the panes within the window. Drag the pane borders within the window enlarge or shrink the windows to your liking. Listing addresses of disassembled instructions The left side of the Disassembly pane lists the address of each disassembled instruction. An arrow to the right of the memory address indicates the location of the current execution point. To the right of the memory addresses, the Disassembly pane displays C hap t e r 7, U sin 9 the i n t e9 rat e d deb u 9 9 e r 189 the assembly instructions that have been disassembled from the machine code produced by the compiler. If you are viewing code that has been linked with a symbol table, the debugger displays the source code that is associated with the disassembled instructions. The Disassembly pane SpeedMenu The Disassembly pane has the following SpeedMenu commands: . • • • • • • Run To Toggle Breakpoint Goto Address Goto Current PC Goto source Change Thread Run to The Run To command lets you run your program at full speed to the instruction that you have selected in the Disassembly pane. This is a quick way to continue debugging at a specific program location. Toggle Breakpoint When you choose Toggle Breakpoint, the debugger sets an unconditional breakpoint at the instruction which you have selected in the Disassembly pane. A unconditional breakpoint has no conditions, and the only action is that it will pause the program's execution. If is a simple breakpoint exists on the selected instruction, then Toggle Breakpoint will delete the breakpoint at that code location. . Goto address The GotoAddress command prompts you for a new area of memory to display in the Code, Dump, and Stack panes of the CPU window. Enter any expression that evaluates to a memory location that your program can access such as main. Be sure to precede hexadecimal values with Ox. The debugger displays dashes if you try to access an address that is not within the scope of the application you are debugging. Goto current PC Goto Current PC places positions the Disassembly pane at the location of the current program counter (the location indicated ,by the EIP register). This location indicates the next instruction to be executed by your program. This command is useful when you have navigated through the Disassembly pane, and you want to return to the next instruction to be executed. 190 C++ Use r 's G u ide Goto source The Goto Source command activates the Edit window and positions the insertion point at the source code that corresponds to the disassembled instruction selected in the Disassembly pane. If there is no corresponding source code (for example, if you're examining Windows kernel code), this command has no effect. Change thread Opens the Change Thread dialog box. Select the thread you want to debug from the thread listed on the process hierarchy. If you choose a new thread from the CPU window, all panes in the window reflect the state of the CPU for that thread. Open multiple instances of the CPU window for lowlevel debugging of different threads. Displaying raw values in addressable areas of your program The Dump pane displays the raw values contained in addressable areas of your program. The display is broken down into three sections: the memory addresses, the current values in memory, and an ASCII representation of the values in memory. By default, the Dump pane displays the memory values in hexadecimal notation. The leftmost part of each line shows the starting address of the line. Following the address listing is an 8-byte hexadecimal listing of the values contained at that location in memory. Each byte in memory is represented by two hexadecimal digits. Following the hexadecimal display is an ASCII display of the memory. Non-printable values are represented with a period. The format of the memory display depends on the format selected with the Display As SpeedMerm command. If you choose one of the floating-point display formats (Floats or Doubles), a single floating-point number is displayed on each line. The Bytes format displays 8 bytes per line, Words displays 4 words per line, and Longs displays 2 long words per line. The Dump pane SpeedMenu The Dump pane has the fGetClientRect(), Width()/2i int centerY = GetMainWindow()->GetClientRect(), Height()/2i int bitmapX = bitmapl.Width()i int bitmapY = bitmapl.Height()i mainWindowDC.BitBlt(centerX-bitmapX/2, centerY-bitmapY/2, bitmapX, bitmapY, memDC, 0, 0, SRCCOPY)i In the code, IDB_BITMAPI is the identifier for the bitmap. Chapter 11, Creating bitmaps, cursors, and icons 231 , Programming a bitmap with the Windows API To program a bitmap the Windows API, use the LoadBitmap, GetObject, GetDC, CreateCompatibleDC, BitBlt, DeleteDC, and ReleaseDC functions. For example, the following code displays a bitmap in the window represented by the HWnd variable: HINSTANCE hInst; HWND hWnd; HDC hOC, hDCMemory; HBITMAP hBitmap, hOldBitmap; BITMAP bitmap; II Get the bitmap resource and its handle. hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1); II Get the bitmap data. GetObject(hBitmap, sizeof(BITMAP), &bitmap); II Get the device context of the target window. hOC = GetDC (hWnd) ; II Create a compatible memory device context. hDCMemory = CreateCompatibleDC(hDC); II Select the bitmap into the memory DC. II hOldBitmap = SelectObject (hDCMemory, hBitmap)i II Copy the bitmap onto the windows device context. BitBlt(hOC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, mDCMemory, 0, 0, SRCCOPY); II Clean up and exit. SelectObject(hDCMemory, hOldBitmap); DeleteDC(hDCMemory); ReleaseDC(hWnd, hOC); In the code, IDB_BITMAPI is the identifier for the bitmap. Working with cursors Cursors are bitmapped images 32 x 32 pixels in size that represent the mouse pointer's current location on the screen. A Windows application often has a number of different cursors that represent different program functions. Windows provides a set of standard cursors you can use in your programs. In addition, you can create your own customized cursors to represent different functions of the program. To design cursors, you use the Graphics editor. Working with cursors involves four basic steps: Start the Graphics editor. 2 Create or edit a cursor. 3 Test the cursor. 4 Save the cursor. 232 C++ Use r 's G u ide Creating a new cursor You can add a new cursor to a resource project file, or create the cursor in a standalone file. To add a new cursor to a new or existing .RC file, 1 Open the resource project you want to add the cursor to, or create a new one by choosing File I New I Resource Project. The New Resource Project dialog box is displayed. Base your project on the .RC file type. 2 Choose Resource I New to create a new resource for that project. Resource Workshop displays the New Resource dialog box. 3 In the Resource Type list, select CURSOR. 4 Click Options to specify attributes for the cursor resource. 5 Click OK to create the new cursor. Resource Workshop opens the Graphics editor where you customize the new cursor resource. Creating a new cursor in a standalone file To create a standalone cursor file with the extension .CUR: 1 Open a resource project or create a new one. 2 Choose Resource I New. Resource Workshop displays the New Resource dialog box. 3 In the Resource Type list box, select CURSOR. 4 Click Options to display the New Cursor Resource Options dialog box. 5 In the Storage Format section, uncheck the Source Form check box. 6 In the Cursor Filename (.CUR) field, enter the path and name of the cursor file. Click OK. 7 Click OK again to create the new cursor. Resource Workshop opens the Graphics editor where you customize the new cursor resource. The standalone cursor file is linked to the current to a resource project file. If you choose File INew IResource Project. and select CURSOR in the New Resource Project dialog box, you automatically create a standalone cursor file. Resource Workshop immediately starts the Graphics editor. You can then link the .CUR file to any resource project with the Add to Project command. Editing an existing cursor To edit an existing cursor: 1 Open an existing resource project. Chapter 11, Creating bitmaps, cursors, and icons 233 2 Double-click the CURSOR resource you want to edit or select it and choose Resource IEdit. After you have the cursor open in the Graphics editor, you can customize it. Before you begin working on your cursor, you may want to zoom it. You can change the cursor's transparent and inverted areas and the number of colors it uses. You can also delete cursors. In addition to creating and modifying cursors directly with the Graphics editor, you can also change the cursor's resource script. It's unlikely that you'll want to do this because the script is almost entirely a series of hexadecimal values. Design issues Before you start, you should have an idea of what your cursor is intended to represent. A typical use of a custom cursor is to represent the task the user is performing. The hot spot is the cursor's active area where the user clicks to activate the task represented by the cursor. You need to make the hot spot obvious. Do not make the cursor complicated. It should be simple enough to fit into a 32 x 32 pixel area. Think about where the user is most likely to display your cursor. Background colors and patterns can affect the cursor's transparent and inverted areas. Setting the hot spot for a cursor An important consideration when you customize a cursor is where to put the hot spot (the cursor's active area). The hot spot is the single pixel in the cursor that fixes the location when the user places the cursor and clicks to make a selection. To set a hot spot: 1 Right-click and choose Zoom In to zoom the cursor image until it is big enough to let you precisely choose the pixel coordinates for the hot spot. 2 Display a grid on the zoomed image. 3 Select the Line tool. 4 Point to the location on the zoomed image where you want the hot spot and look at the coordinates displayed on the status line. Make a note of these coordinates. 5 Choose Cursor ISet Hot Spot. 6 Enter the hot spot's pixel coordinates in the Set Hot Spot dialog box. Press OK to accept the values. Deleting a cursor You can delete a cursor resource or a cursor image. Deleting a cursor resource deletes all the images in that resource. Deleting a cursor image removes that single image in the cursor resource. 234 c++ User's Guide Deleting a cursor resource To delete a cursor resource, select it in the Resource Project window then: Press the Del key or right-click and choose Remove from Project to completely delete it. 2 Choose Edit ICut to cut the resource into the Windows Clipboard so you can paste it elsewhere. Deleting a cursor image To remove an image from a cursor resourc~: Open the cursor resource in the Resource Project window by double-clicking it or selecting it and choosing Resource IEdit. 2 In the Cursor Project window select the image entry you want to delete, then: 3 Press the Del key or right-click and choose Remove from Project to completely delete it. 4 Choose Edit ICut to cut the resource into the Windows Clipboard so you can paste it elsewhere. Testing a cursor Anytime you want, you can test your cursor by choosing Cursor ITest Cursor. Resource Workshop turns the current cursor into a test version of your cursor. You can move it around to see how it looks on different color backgrounds. When you finish testing, just click the mouse to continue customizing your cursor. Adding an image to a cursor resource You may want to put different color formats of the same cursor in one cursor resource project. These color variations on the same cursor are called images. The reason the cursor resource supports different color formats is that Windows picks a color format based on the ability of the display hardware to support the format. Windows picks a 16-color format for the standard Windows VGA driver. Windows 3.x does not fully support the 256-color version of an cursor, even if your display hardware supports it. Your program must supply its own support for 256 colors. To add a new image with different color formats to an existing cursor resource: 1 Open a resource project. 2 Double-click the CURSOR entry you want to edit or select it and choose Resource I Edit. Chapter 11, Creating bitmaps, cursors, and icons 235 3 Choose Cursor I New Image. 4 Resource Workshop displays the New Cursor Resource dialog box, where you choose the color format of the new image. S Choose a new color format and click OK. 6 Double-click the new cursor, or select it and choose Images I Edit Image. You see the Graphics editor where you customize the cursor as needed. Typically, what you do next is open one of the existing cursor images and copy it into the new (still blank) image. You might also have to customize the image if the colors are translated in a way that changes the form of the cursor. Changing the attributes of a cursor You can change an cursor's attributes--color or size--with the Cursor I Size and Attributes command. This command displays the Cursor Image Attributes dialog box, where you change an cursor's size and color format. Copying a cursor image to a new color format You might want to have different color formats of the same image for different displays. To create another version, without starting over, you can copy and paste the image. To copy and paste the image: ·1 Create a new image for your cursor. 2 Open the image you want to copy in the Graphics editor. 3 Choose Edit I Select All to select the entire image. 4 Choose Edit I Copy to copy the cursor image to the Clipboard. S Use File I Close to close the window. 6 Choose Cursor I New Image to create a new Cursor image. In the New Cursor Image dialog box, choose the color format of the new image. 7 Double-click the new CURSOR entry in the Cursor Project window. S Choose Edit I Paste to paste the cursor into the new image. It is displayed in the new color format. Programming a cursor with OWL To program a cursor with OWL, use the TWindow::SetCursor function. For example, the following application code assigns a cursor to the main window: GetMainWindow()->SetCursor(this, IDC_CURSOR1)i 236 c++ User's Guide IDC_CURSOR1 is the identifier for the cursor. Programming a cursor with the Windows API To program a cursor with the Windows API, use the LoadCursor and SetCursor functions. For example, the following code changes the active cursor: , HCURSOR hCursori hCursor = LoadCursor(hlnst, MAKEINTRESOURCE(IDD_CURSOR1»i SetCursor(hCursor)i IOO_CURSOR1 is the identifier for the cursor. Working with icons Icons are small bitmapped images, normally 16 x 16, 32 x 32, 48 x 48, or 64 x 64 pixels in size. Windows programs typically use customized icons to represent minimized windows. To design icons, use the Resource Workshop Graphics editor. Working with icons involves four basic steps: Start the Graphics editor. 2 Create or edit an icon. 3 Test the icon. 4 Save the icon. Creating a new icon You can add a new icon to a resource project file, or create the icon in a standalone file. To add a new icon to a new or existing .RC file: 1 Open the resource project you want to add the icon to, or create a new one by choosing File I New I Resource Project. The New Resource Project dialog box is displayed. Base your project on the .RC file type. 2 Choose Resource I New to create a new resource for that project. Resource Workshop displays the New Resource dialog box. 3 In the Resource Type list, select ICON. 4 Click Options to specify attributes for the icon resource. 5 Click OK to create the new icon. Resource Workshop opens the Graphics editor where you customize the new icon resource. C hap t e r 1 1, ere at i n 9 bit map s, cur s 0 r s, and i con S 237 Creating a new icon in a standalone·file To create a standalone icon file with the extension .CUR: Open a resource project or create a new one. 2 Choose Resource I New. Resource Workshop displays the New Resource dialog box. 3 In the Resource Type list box, select ICON. 4 Click Options to display the New Icon Resource Options dialog box. 5 In the Storage Format section, uncheck the Source Form checkbox. 6 In the Icon Filename (.CUR) field, enter the path and name of thejcon file. Click OK. 7 Click OK again to create the new icon. Resource Workshop opens the Graphics editor where you customize the new icon resource. The standalone icon file is linked to the current to a resource project file. If you choose File I New I Resource Project. and select ICON in the New Resource Project dialog box, you automatically create a standalone icon file. Resource Workshop immediately starts the Graphics editor. You can then link the .CUR file to any resource project with the Add to Project command. Editing an existing icon To edit an existing icon: 1 Open an existing resource project. 2 Double-click the icon resource you want to edit, or select it and choose Resource I Edit. After the icon is opened in the Graphics Editor, you can customize it. Before you begin working on your icon, you may want to zoom it. You can change the icon's transparent and inverted areas and its attributes. You can also delete icon resources and images. In addition to creating and modifying icons directly with the Graphics editor, you can also change the icon's resource script. It is unlikely that you'll want to do this because the script is almost entirely a series of hexadecimal values. Design issues Before you start, you should have an idea of what the icon represents to the user. The icon should be simple enough to fit into a 64 x 64, 48 x 48,32 x 32, or 16 x 16 pixel area. Think about where the user is most likely to display your icon. Background colors and patterns can affect the icon's transparent and inverted areas. 238 C++ Use r 's G u ide Drop shading Drop shading is a technique you can use to make your icon look three dimensional. For example, to make a black box look three dimensional, draw a gray border on the right side and bottom of the box. Adding an image to an icon resource You may want to put different color formats of the same icon in one icon resource project. These color variations on the same icon are called images. The reason the icon resource supports different color formats is that Windows picks a color format based on the ability of the display hardware to support the format. Windows picks a 16-color format for the standard Windows VGA driver. Windows 3.x does not fully support the 256-color version of an icon, even if your display hardware supports it. Your program must supply its own support for 256 colors. However, Windows 95 does and typically uses 256 colors for 48 x 48 or large icons. To add a new image with different color formats to an existing icon resource: 1 Open a resource project. 2 Double-click the ICON entry you want to edit or select it and choose Resource I Edit. 3 Choose Icon I New Image. 4 Resource Workshop displays the New Icon Image dialog box, where you choose the size and color format of the new image. 5 Choose the same size as the existing image and a new color format and click OK. 6 Double-click the new icon, or select it and choose Images I Edit Image. You see the Graphics editor where you customize the icon as needed. Typically, what you do next is open one of the existing icon images and copy it into the new (still blank) image. You might also have to customize the image if the colors are translated in a way that changes the form of the icon. Changing the attributes of an icon You can change an icon's attributes---color or size-with the Icon I Size and Attributes command. This command displays the Icon Image Attributes dialog box, where you change an icon's size and color format. Copying an icon image to a new color format You might want to have different color formats of the same image for different displays. To create another version, without starting over, you can copy and paste the image. C hap t e r 1 1, ere a tin 9 bit map s, cur S 0 r s, and i con s 239 To copy and paste the image: 1 Create a new image for your icon. 2 Open the image you want to copy in the Graphics editor. 3 Choose Edit I Select All to select the entire image. 4 Choose Edit I Copy to copy the icon image to the Clipboard. S Use File I Close to close the window. 6 Choose Icon I New Image to create a new icon image. In the New Icon Image dialog box, choose the size .and color format of the new image. 7 Double-click the new ICON entry in the Icon Project window. S Choose Edit I Paste to paste the icon into the new image. It is displayed in the new color format. Deleting an icon resource or image You can delete an icon resource or an icon image. Deleting an icon resource deletes all the images in that resource. Deleting an icon image removes that single image in the icon resource. Deleting an icon resource To delete an icon resource, select it in the Resource Project window then: Press the Del key or right-click and choose Remove from Project to completely delete it. 2 Choose Edit I Cut to cut the resource into the Windows Clipboard so you can paste it elsewhere. Deleting an icon image To remove an image from an icon resource: 1 Open the icon resource in the Resource Project window by double-clicking it or selecting it and choosing Resource I Edit. 2 In the Icon Project window select the image entry you want to delete, then: 3 Press the Del key or right-click and choose Remove from Project to completely delete it. 4 Choose Edit I Cut to cut the resource into the Windows Clipboard so you can paste it elsewhere. 240 C++ Use r 's G u ide Testing an icon The easiest way to test an icon is to use the Icon I Test Icon command. You can also bind the icon resource to an. executable file and then run the file to see what the icon looks like. Two primary reasons for testing an icon are: 1 To see how a color icon looks in black and white when you move it around. 2 To see how transparent and inverted areas look against various backgrounds. The first test is easy to perform: just move the icon around. The second test takes a little more work. Here's how: 1 Make sure the icon is visible and is in a spot where the application workspace is its background. 2 Change tasks using Windows NT or Windows 95. 3 Use the Control Panel to change the color of the active window's workspace. 4 Leave the Control Panel Settings window open so you can change the colors again. 5 Change tasks back to Resource Workshop and check the icon against the new background color. At this point, you should be able to see both Resource Workshop and the Color dialog box (NT) or Display Properties (Windows 95) at the same time. You can select another color for the workspace background and check the icon again. When you change the color of the application workspace, the operating system changes the color in the application window, where you can check the icon against the new oo~ . Programming an icon with ObjectWindows To program an icon with ObjectWindows, use the TFrameWindow::SetIcon function. For example, the following code assigns an icon to the main window: GetMainWindow()->SetIeon(this, IDC_ICON1)i IDC_ICONI is the identifier for the icon. Programming an icon with the Windows API To program an icon with the Windows API, use the LoadIcon function. For example, this code loads an icon resource into a variable: HICON hIeoni hIeon = LoadIeon(hInst, MAKEINTRESOURCE(IDD_ICON1))i IDD_ICONI is the identifer for the icon. Chapter 11, Creating bitmaps, cursors, and icons 241 242 C++ Use r 's G u ide Using the Graphics editor You use the Graphics editor to create and edit any bitmapped resource, including bitmaps, cursors, and icons. Although most of the Graphics editor's features are the same for the bitmapped resource types, there are some features that are unique to each resource type. For example, the name of the Graphics editor menu is the same as the resource type: Icon for .an icon resource, Bitmap for a bitmap resource, and Cursor for a cursor resource. The Graphics editor features whose functionality is generally the same for all types of bitmapped resources are the Color palette, the status line and bar, the Tool palette, and the window panes. This chapter covers the following topics: • • • • • • • • • • • • • • Using the Color palette Selecting a pen style Selecting a brush shape Selecting a paint pattern Drawing and painting Adding text Selecting an area Erasing an area Aligning an area Moving or resizing an area Copying an area Removing an area Zooming in or out Moving a graphic around in the drawing area C hap t e r 1 2, Us in 9 the G rap hie sed ito r 243 Using the Color palette Bitmapped images drawn with the Graphics editor are created on a grid of pixels. You create the imageby setting each pixel to a foreground or background color. Strictly speaking, there's no difference between the foreground and background color. There is, however, a difference in how you choose foreground and background colors and in how they are created when you edit the bitmapped image. The Graphics editor's Color palette makes it easy to choose foreground and background colors. You can work with a Color palette even if your image is black and white. You use the Color palette to choose: • A foreground color • A background color • Transparent and inverted areas (for icons and cursors only) You can move the palette anywhere you want it. You can also hide it and show it by: • Right-clicking and choosing the Show IColor Palette command. • Clicking the palette's Close box. Selecting a foreground color The foreground color is the color you select and draw with the left mouse button. It is typically one of the colors you use to create the features of your resource, such as lines, boxes, shading, and so on. The current foreground color is indicated on the Tool palette. To select a foreground color: 1 Select the color you want onthe Color palette (using the left mouse button). 2 The color is displayed at the bottom of the Tool palette. 3 Select a tool that draws or paints. 4 Click or drag with the left mouse button to draw or paint with the foreground color. The Eraser tool operates in the opposite fashion from the drawing tools. Dragging it with the left mouse button produces the background color, and dragging it with the right mouse button produces the foreground color. Selecting a background color The background color is the color you select and draw with the right mouse button and is usually the color that appears to underlie your drawing. It is also the color that's left behind when you select an area and delete or move it. The background color is indicated on the Tool pallette. 244 C++ Use r 's G u ide To select a background color, Right-click the color you want in the Color palette. ' • The color is displayed on the Tool Palette next to the foreground color 2 Select a tool that draws or paints. 3 Click or drag with the right mouse button to draw or paint with the background color. The Eraser tool operates in the opposite fashion from the drawing tools. Dragging it with the left mouse button produces the background color, and dragging it with the right mouse button produces the foreground color. Transparent and inverted areas Transparent and inverted color areas are unique to icon and cursor resources. • A transparent area allows the desktop color behind the icon or cursor to show through. • An inverted area reverses the desktop color at run time. The designated transparent and inverted colors do not appear in your icon or cursor at run time. Instead, they are replaced by the desktop color or its inverse. The colors that you set as Transparent and Inverted should be colors that you will not use in your icon or cursor. The default transparent color is the current desktop color set in th~ Windows Control Panel's color palette. If the desktop uses a dithered color, the default transparent color is the nearest solid color that Resource Workshop can provide. (If you have a 256-color device, this restriction does not apply; the default transparent color will always match the desktop color.) You can change the transparent color to something other than the desktop color, but it will always revert to the desktop color each time you start Resource Workshop. Nevertheless, regions that you designate as transparent-using the default color or a color you assign-remain transparent and take on the current transparent color. Note You can change colors so that you have transparent and non-transparent regions that use the same color. To change the colors the Graphics editor displays for transparent and inverted areas, 1 Double-click the button for Transparent or Inverted in the Color palette. 2 Select either Transparent or Inverted as the foreground or background color. e If you're working with icons, right-click and choose Edit Foreground Color or Edit Background Color. e If you're working with cursors, right-click and choose Set Transparent Color. Resource Workshop displays the Color dialog box, where you can change the color. C hap t e r 1 2, Usin 9 the G rap hie sed ito r 245 Hiding and showing the Color palette If you want to hide the Color palette you can close it by clicking the Close button in the upper-right comer of the palette. You can also right-click and uncheck the Show IColor Palette command. Or you can select Show IColor Palette from the Bitmap, Cursor, or Icon menus. Choosing the number of colors for a resource When you create a bitmap, cursor, or icon, you choose how many colors you want in your resource. For bitmaps, this dialog box is the New Bitmap Resource Options dialog box. For cursors, this dialog box is the New Cursor Resource Options dialog box. For icons, it is the New Icon Resource Options dialog box. To display these dialog boxes, press the Options button while in the New Resource Project or New Resource dialog boxes. While you are editing a bitmap, cursor, or icon, you can change the number of colors in the image using the Size and Attributes command. Depending on the type of resource you edit, you find this command on the Bitmap, Cursor, or Icon menu. You can include up to 256 colors in your bitmap, cursor, or icon. The number of colors you can use (and see in the Color palette) depends on the type of display driver you're using with Windows. The standard Windows VGA driver supports a fixed set of only 16 colors. Customizing colors When you are editing a color image you can modify the Color palette to include any colors supported by your display driver. It does not make sense to do this if the Color palette already includes all the colors supported by your computer. But if your display driver is capable of displaying 256 colors and you're working with a 16-color image, you can include any of the 256 colors in the 16-color Color palette. When you're editing a cursor or icon, you can change the color used to display transparent or inverted areas of the image. Modifying the Color palette To edit a color, double-click it. Resource Workshop displays the Edit Color dialog box, where you can specify a new color. 246 C++ Use r 's G u ide Note You can't change the first or last color in the palette. By default, the first and last entries are always black and white, respectively. Selecting a pen style The pen style affects the width of a line or shape border and whether a line or shape is solid, dashed, or dotted. The pen style applies to the following tools: • Line • Ellipse • Pen • Rectangle • Rounded Rectangle To select a pen style, 1 Choose the Pen Style tool on the Tool Palette. You can also select the Pen Style command from the Bitmap, Cursor, or Icon menu. • The Set Pen Style dialog box is displayed. 2 Choose the line style you want. 3 Choose OK. The new pen style displays in the Tool palette. You can select one of the tools mentioned above and draw with the new pen style. Selecting a brush shape You can select a brush shape for the Paintbrush or Airbrush tool. To select a brush shape, 1 Select the Paintbrush Shape or Airbrush Shape tool on the Tool palette. You can also select the Paintbrush Shape or Airbrush Shape command from the Bitmap, Cursor, or Icon menu. • If you choose the Paintbrush Shape tool, you see the Brush Shape dialog box. • If you choose the Airbrush Shape tool, you see the Airbrush Shape dialog box. 2 Select a brush shape. 3 ChQose OK. The new shape displays in the Tool palette. You can select one of the tools mentioned above and draw with the new brush shape style. C hap t e r 1 2, U sin 9 the G rap hie sed ito r 247 Selecting a paint pattern The paint pattern affects the interior of a filled shape and the painting styles of the brush tools. The paint patJern applies to the following tools: • Airbrush • Filled Ellipse • Filled Rectangle • Filled Rounded Rectangle • Paintbrush To select a paint pattern, 1 Choose the Pattern tool on the Tool palette. You can also choose Pattern from the Bitmap, Cursor, or Icon menu. • The Set Pattern Type dialog box is displayed. 2 Select a paint pattern. 3 Choose OK. The new pattern displays on the Tool palette. You can select one of the tools mentioned above and draw with the new paint pattern. Drawing and painting You can draw and paint with the Pen, Paintbrush, and Airbrush tools. . The size of the area covered by these tools is proportionate to the size of the drawing area. You can zoom out to paint a larger area, and zoom in to paint a smaller area. To draw or paint, 1 Choose the Pen, Paintbrush, or Airbrush tool on the Tool palette. 2 In the drawing area, move the cursor to where you want to start drawing, and then click and hold down the left mouse button (for foreground color) or the right mouse button (for background color). 3 Drag the cursor around the drawing area. 4 When you are done, release the mouse button. Drawing a line To draw a line, 1 Choose the Line tool on the Tool palette. 2 In the drawing area, move the cursor to where you want to the line to start, and click and hold down the left mouse button (for foreground color) or the right mouse button (for background color). 248 C++ Use r 's Gu ide 3 Move the cursor to where you want the line 'to end, and release the mouse button. 4 To draw a line at a 0-, 45-, or 90-degree angle, hold down the Shift key while you are drawing. Drawing a shape You can draw a filled or unfilled rectangle, rounded rectangle, or ellipse. To draw a shape, Choose one of the following tools on the Tool palette: • • .. ... Rectangle Rounded Rectangle Filled Rectangle Filled Rounded Rectangle • Ellipse • Filled Ellipse 2 In the drawing area, move the cursor to where you want a comer of the shape to be, and hold down the left button (for the foreground color) or the right mouse button (for the background color). 3 Move the cursor to the opposite comer of the shape, and release the mouse button. The interior of a filled shape depends on the current paint pattern, and the shape border depends on the current pen style. To draw a shape without a border, select Null for the pen style. Filling an area with color You can fill any area that is bounded by one or more different colors. To fill an area with color, 1 Choose the Paint Can tool from the Tool Palette. 2 In the drawing area, move the crosshairs into the area that you want to fill, and hold down the left mouse button (for the foreground color) or the right mouse button (for the background color). Adding text To add text to a graphic, 1 Choose the Text tool on the Tool palette. 2 In the drawing area, click where you want to add text. C hap t e r 1 2, U sin 9 the G rap hie sed ito r 249 3 Type the text. To change the font and alignment of the text, 1 Choose Bitmap, Cursor, or Icon IText Attributes. The Font dialog box is displayed. 2 Choose the font name, size, style, and text alignment. 3 Choose OK. To change the color of text, • Choose a new color from the Color palette. After you click to make another selection, you cannot change the attributes of the text you have just typed. Erasing an area To erase an area, 1 Select the Eraser tool on the Tool palette. 2 Drag the eraser over the area you want erased. To erase the entire drawing area, double-click the Eraser tool on the Tool palette. An erased area is colored the selected background color. This means that you can: • Erase an area by drawing or painting using the background color. For example, you can use the Line tool to erase a line if the selected color for the line is the background color. • Use the Eraser tool to paint an area with the background color while you hold down the left mouse button, and paint an area with the foreground color while you hold down the right mouse button. Selecting an area You can align, copy, move, and remove any area that you select. To select a rectangular area, Choose the Pick Rectangle tool on the Tool palette. 2 In the drawing area, move the cursor to a comer of the area you want to select and hold down the mouse button. 3 Move the cursor to the opposite comer of the area you want to select and release the mouse button. To select a non-rectangular area, 1 Choose the Scissors tool on the Tool palette. 250 c++ User's Guide 2 In the drawing area, move the cursor to a boundary of the area you want to select and hold down the mouse button. 3 Draw a closed shape around the area you want to select and release the mouse button. You can now align, copy, move, or delete the selected area. Aligning an area You can align an area with the top, bottom, sides, or center of a graphic. To align an area, Choose the area with the Pick Rectangle or Scissors tooL 2 Choose Bitmap, Cursor, or Icon IAlign. The Align Selection dialog box is displayed. 3 Select a horizontal alignment option. 4 Select a vertical alignment option. S Choose OK. Any area that is left open is filled with the current background color. Moving or resizing an area To move an area, 1 Choose the area with the Pick Rectangle or Scissors tooL 2 Drag the area to a new location. To resize an area, Choose the area with the Pick Rectangle or Scissors tooL 2 Choose Bitmap, Cursor, or Icon ISize. The Stretch Selection dialog box is displayed. 3 To move the area, specify new pixel coordinates for the Top and Left sides. 4 To resize the area, specify a new height and width. S Choose OK. Any area left open is filled with the current background color. Copying an area To copy an area, 1 Choose the area with the Pick Rectangle or Scissors tooL 2 Choose Edit ICopy to place a copy of the area in the Windows Clipboard. C hap t e r 1 2, U sin 9 the G rap hie sed ito r 251 3 Choose Edit IPaste to insert the area into the image. 4 A copy of the selected area appears in the upper-left comer of the drawing area. It remains selected. 5 Drag the selected area to where ever you want to place it. You can also use this method to copy an area: 1 Select the area. 2 Choose Edit ICopy. 3 Select an area where you want the copied image to appear. 4 Choose Edit IPaste. 5 The copied image fits within the selected area as best it can and remains selected. You can move the selected area if you want. Any area left open is filled with the current background color. Removing an area To remove or delete an area, 1 Choose the area with the Pick Rectangle or Scissors tool. 2 Choose Edit ICut. 3 You can then paste the removed area somewhere else using the Edit IPaste command. Any area left open is filled with the current background color. You can also use Edit IClear to delete an area. The area is not copied to the Clipboard for pasting. Zooming in or out To zoom in on a graphic, • Double-click the Zoom tool on the Tool palette. You can also right-click and choose Zoom In, or press Control+Z. To zoom in on a particular area of a graphic, 1 Select the Zoom tool. 2 In the drawing area, move the cursor to a comer of the area and hold down the mouse button. 3 Drag the cursor to the opposite comer of the area and release the mouse button. 252 C++ Use r 's G u ide To zoom out from a graphic, • Hold down the shift key and double-click the Zoom tool on the Tool palette. You can also press Ctrl+O or right-click and choose Zoom Out. To view the actual size of a graphic, • Press Ctrl+A or right-click and choose Actual Size. To help you control images on a pixel-by-pixel basis, you can display a grid on any zoomed image by choosing Bitmap, Cursor, or Icon IEditor Options. Check the Grid on Zoomed Windows check box. Each square of the grid represents a single pixel. If you zoom an image to a size that is too large to fit in the pane, and the image is displayed at its true size in the other window pane, Resource Workshop places a dotted rectangle over the unzoomed image. This dotted rectangle indicates the portion of the image currently displayed in the zoomed window pane. Moving a graphic around in the drawing area If a graphic is too large to display in the drawing area, you can move it around to see other parts of it. To move a graphic in the drawing area, 1 Hold down the Ctrl key. • The cursor becomes the Hand tool. 2 Drag the graphic to a new position. You can also move a graphic around with the scroll bars on the right and bottom sides of the drawing area. Tool palette When you open a resource in the Graphics editor, the Tool palette is displayed in the edit window. You use the Tool palette to choose the Graphics editor tool you want to work witp. or to change settings for the various tools. You can move the Tool palette around, dock it, and you can hide it or show it. Here are tools on the Tool palette: Pen Airbrush Line Rounded Rectangle Ellipse Eye Dropper Ellipse Chapter 12, Using the Graphics editor 253 These four buttons, displayed at the bottom of the Tool palette, allow you to customize settings: . Pen Brush Shape There are also color setting buttons for the foreground color and background color. The current settings are displayed on these buttons. In addition, there is a Hand tool that you can use to move a zoomed image. It is not displayed in the Tool palette. Hiding and showing the Tool palette To hide or show the Tool palette, 1 Right-click and choose Show ITool Palette. 2 Toggle the Show ITool Palette command. This command is located on the menu bar selection that corresponds to the type of resource you are working with (Bitmap, Cursor, or Icon). The check mark next to the' command indicates that it is displayed. No check mark indicates that it is hidden. Pick Rectangle tool You use the Pick Rectangle tool to select a rectangular area of your image for copying, moving, or deleting. To select an area, click the left mouse button and drag the mouse until the flashing outline surrounds the area you want. Release the mouse button. Clicking either mouse button outside the outline turns the area selection off. When you select an area, you can use the Edit menu commands to cut, copy, clear, duplicate, or paste into the selected area. You can also use the mouse to move (click) or duplicate the area (shift-click). In addition, you can align or resize the selected area. Scissors tool The Scissors tool performs basically the same function as the Pick Rectangle Tool: it selects an area of an image. However, with the scissors you can select and move areas of any shape, not just rectangles. To select an area, click the left mouse button and drag the scissors until the flashing outline surrounds the area you want, then release the mouse button. 254 c++ User's Guide When you select an area, you can use the Edit menu commands to cut, copy, clear, duplicate, or paste into the selected area. You can also use the mouse to move (click) or duplicate the area (shift-click). In addition, you can align or resize the selected area. Zoom tool You use the Zoom tool to zoom the entire image, or you can outline an area of an image that you'd like to zoom, and have Resource Workshop zoom that area. Double-click the Zoom tool to zoom in on the entire image. The image is zoomed based on the center of the image. Images are zoomed one magnification increment per zoom action, until the maximum or minimum magnification is reached. To zoom out, press Shift and double-click the Zoom tool. To zoom in on a selected area, 1 Select the Zoom tool. 2 Click and drag to select the area you want to zoom in on. The magnification depends on the size of the area you select. The smaller the selected area, the greater the magnification. Eraser tool The Eraser tool works like a square paintbrush-you drag the tool over the area you want to erase. To erase an entire image, double-click the Eraser tool. Use the left mouse button to reveal the current background color. Use the right mouse button to reveal the current foreground color. Since you use the eraser to reveal colors, the buttons on the mouse are the opposite of other tools you use to paint. For example, when you use the Paintbrush tool, you use the left mouse button to paint the foreground color. But with the eraser, the left mouse button reveals the background color. Before you use the eraser, you may want to select the foreground and background colors you want to use in the Color palette. Pen tool Use the Pen tool to paint free-form lines and shapes using the current pen style. To sketch with the Pen tool, click a mouse button and drag the pen across your image. Release the mouse button when you finish sketching. • Use the left mouse button to sketch with the current foreground color. • Use the right mouse button to sketch with the current background color. Chapter 12, Using the Graphics editor 255 Before you use the Pen tool, you might want to select the pen style and the foreground and background colors. You can also use the Pen tool to fill individual pixels with a color. Left-click to use the foreground color or right-click to use the background color. You may want to zoom in on the image before making changes to make it easier to color individual pixels. Paintbrush tool Use the Paintbrush tool to paint free-form patterns using the current brush pattern and shape. To paint, click a mouse button and drag the paintbrush across your image. Release the mouse button when you finish painting. When you choose the Paintbrush tool, you see a cursor that represents the current brush shape. The area painted by the paintbrush is always proportionally the same relative to the size of the image frame. • Use the left mouse button to paint with the current foreground color. • Use the right mouse button to paint with the current background color. Before you use the paintbrush, you might want to select the foreground and background colors and the paintbrush shape and pattern. Airbrush tool The Airbrush tool paints free-form patterns similar to a real airbrush on your image using the current airbrush pattern and shape. To use the airbrush, you can either click a mouse button once and drag the airbrush, or you can click it repeatedly, as if you were repeatedly pressing the nozzle of a spray can. If you drag it slowly, it paints a thick pattern. If you drag it quickly, it paints a scattered, thinner pattern. When you choose the Airbrush tool, you see a cursor that represents the Airbrush tool. The area painted by the airbrush is always proportionally the same relative to the size of the image frame. • Use the left mouse button to paint with the current foreground color. • Use the right mouse button to paint with the current background color. Before you use the airbrush, you might want to select the foreground and background colors and specify the airbrush shape and pattern. Paint Can tool Use the Paint Can tool to fill an area of your image with the currently selected color. It fills in any area of your image that is a single colo~. 256 c++ User's Guide • If you use this tool on an area that is not entirely surrounded by other colors, the color leaks out into other parts of the image that are the same color as the original area. • If you hold down the Shift key when you use the Paint Can, you replace all instances of the color you click on, contiguous ot not. To use the Paint Can tool, point the paint can's cross hairs in the portion of the image you want to fill, then click a mouse button. • Use the left mouse button to sketch with the current foreground color. • Use the right mouse button to sketch with the current background color. Before you use the paint can, you might want to specify the foreground and background colors. Line tool Use the Line tool to paint straight lines. Press the mouse button and drag the Line tool across your image. Release the mouse button when you've finished drawing the line. If you want the lines you paint to be limited to 45-degree increments, hold down Shift as you draw the line. With Shift down, you can paint only a horizontal or vertical line or a line on a 45-degree angle. • Use the left mouse button to sketch with the current foreground color. • Use the right mouse button to sketch with the current background color. Before you paint a line, you might want to specify the pen style and choose the foreground and background colors. Text tool To add text to your image, choose the Text tool and click where you want the text to begin. A flashing cursor appears and you can begin typing text. Before you use the Text tool, you might want to specify how and where you want the text displayed: Use the Bitmap, Cursor, or Icon IText Attributes command to display the Font dialog box, where you specify the typeface, size, style of the text, and how text is aligned. Text is always displayed in the current foreground color. Before you type text, you might want to specify the foreground color by clicking the left mouse button on the color you want in the Color palette. C hap t e r 1 2, U sin 9 the G rap hie sed ito r 257 Empty frame tools You use one of these tools to paint an empty frame in your image: • Ellipse • Rectangle • Rounded Rectangle To paint an empty frame, 1 Choose the tool you want. 2 Point the tool's cross hair where you want to start a comer of the frame. 3 Click a mouse button and drag the frame tool until the frame outline surrounds the area you want. 4 Release the mouse button. Use the left mouse button to sketch with the current foreground color. Use the right mouse button to sketch with the current background color. Before you paint a frame, you might want to specify the pen style, as the frame is affected by the pen style and width. You may also want to choose the foreground and background colors before painting the frame. Ellipse tool Use the Ellipse tool to paint an ellipse-shaped empty frame in your image. Rectangle tool Use the Rectangle tool to paint a rectangular empty frame in your image. Rounded Rectangle tool Use the Rounded Rectangle tool to paint an empty frame shaped like a rounded rectangle in your image. Filled-in frame tools Use one of these tools to paint filled-in frames in your image: • Filled Ellipse • Filled Rectangle • Filled Rounded Rectangle 258 c++ User's Guide These tools paint a frame using the current pen style. The frame is filled using the current pattern and color. Specify a null pen style in the Set Pen Style and Width dialog box if you don't want Resource Workshop to put an outline around the filled-in pattern. To paint a filled-in frame, 1 Choose the tool you want. 2 Point the tool's cross hairs where you want to start a comer of the frame. 3 Click a mouse button and drag the frame tool until the frame outline surrounds the area you want. 4 Release the mouse button. Use the left mouse button to sketch with the current foreground color. Use the right mouse button to sketch with the current background color. Before you paint a filled-in frame, you might want to specify the pen style and pattern and choose the foreground and background colors. Filled Rectangle tool Use the Filled Rectangle tool to paint a rectangular filled-in frame in your image. Filled Rounded Rectangle tool Use the Filled Rounded Rectangle tool to paint a filled-in frame, in the shape of a rounded rectangle, in your image. Filled Ellipse tool Use the Filled Ellipse tool to paint an ellipse-shaped filled-in frame in your image. Eye Dropper tool Use the Eye Dropper tool to copy a color from the current image. This is useful when you have a color in an image that isn't displayed in your color palette. To select a color for use with any tool, 1 Select the Eye Dropper from the Tool palette. 2 Click to copy the color as a foreground color, or right-click to copy the color as a background color. 3 Select the tool you wish to use with the new color. C hap t e r 1 2, Usin 9 the G rap hie sed ito r 259 Arc tool Use the Arc tool to create a Bezier arc, curve, or closed loop usihg the current pen style and color. To create an arc, 1 Select the Arc tool from the Tool Palette. 2 Click and drag to draw a line of the appropriate length. 3 Click the lihe you just created and drag it to create the arc you want. The poiht you select on the lihe determihes the shape of the arc. To create a symmetrical arc, click the center of the lihe. 4 Without movihg the cursor, click agaih to "set" the arc. To create a curve, 1 Select the Arc tool from the Tool Palette. 2 Click and drag to draw a line of the appropriate length. 3 Click the line you just created and drag it to create the arc you want. The poiht you select on the line determihes the shape of the arc. 4 Click another part of the line and drag it to create another arc ih the lihe. You can click many poihts on the line to create the desired curve. To create a closed loop, 1 Select the Arc tool from the Tool Palette. 2 Click where you want the closed end of the loop to be. This end is stationary and will not move as you create the loop. 3 Click where you want the top of the loop to be. This creates a line. This end may move as you create the loop. 4 Click the line and drag it to adjust the arc. The arc is mirrored, resulting ih a closed loop. To constraih the lihes to 45-degree angles, press Shift as you draw the lihe. You will only be able to draw horizontal, vertical or 45-degree lihes. • Use the left mouse button to draw with the current foreground color. • Use the right mouse button to draw with the current background color. Hand tool Unlike other tools, the Hand tool isn't ihcluded ih the Tool palette. But you can change any tool (except the Text tool) ihto a hand by holdihg down CtrL The Hand tool is a grabbihg tooL You just click the hand on the image and drag it ih the direction you want it to move. 260 C++ Use r '5 G U ide The Hand tool is automatically displayed when you select an area using the Pick Rectangle or Scissors tool. Sometimes when you display a zoomed image, not all of it fits in the display. You can use the Hand tool to move the image around to see other parts of it. Pattern style tool The Pattern style tool shows the current pattern style. Some of the tools in the Tool palette use this style when they paint a pattern on your image. These tools are: • Airbrush • Filled Ellipse • Filled Rectangle • Filled Rounded Rectangle • Paintbrush Click the Pattern tool to display the Set Pattern Type dialog box, where you choose the pattern that is painted when you use these tools. Pen style tool The Pen style tool shows the current pen style and width. Some of the tools in the Tool palette use this style when they draw a line on your image. These tools are: • Line • Ellipse • Pen • Arc • Rectangle • Rounded Rectangle Click the Pen style tool to display the Set Pen Style and Width dialog box, where you choose the pen style and width for these tools. The pen style is drawn relative to the size of the image. Airbrush shape tool The Airbrush shape shows the current shape used fQr the Airbrush tool. Click the Airbrush shape tool to display the Airbrush Tip Shape dialog box, where you choose the airbrush tip shape. C hap t e r 1 2, Us i n 9 the G rap hie 5 e d ito r 261 Paintbrush shape tool The Brush shape tool shows the current shape of the Paintbrush tool. Click the Brush shape tool to display the Brush Tip Shape dialog box, where you choose the brush shape. 262 C++ Use r 's G u ide Working with resources Resources are data that define the visible portions of your Windows program. Resources provide a consistent user interface that makes it easy for users to switch from one Windows program to another. In general, a Windows application's resources are separate from the program code, letting you make significant changes to the interface without even opening the file that contains your program code. This also lets different applications share the same set of resources, so that you do not have to reinvent all your favorite resources. Instead, you can use them over and over. When you display resources in the Resource Project window, you see them listed by type, with the names of the resource listed under their type. To create a new resource, you can do one of the following: • Double-click the resource type in the Resource Project window. The Options dialog box for that type displays. Click OK to create the new resource. Resource Workshop automatically starts the appropriate editor, if one is available. If an editor is not available (for example, for a user-defined resource), Resource Workshop starts the Text editor. • Select Resource INew and choose the type of resource you want to create. Resource Workshop automatically starts the appropriate editor, if one is available. If an editor is not available, Resource Workshop starts the Text editor. To load a resource, you can do one of the following: • Double-click the resource name in the Resource Project window. Resource Workshop automatically starts the appropriate editor, if one is available. If an editor is not available (for example, for a user-defined resource), Resource Workshop starts the Text editor. • Select the resource name in the Resource Project window and choose either Resource IEdit or Resource IEdit as Text. Resource IEdit loads a resource editor, if C hap t e r 1 3, W0 r kin 9 wit h res 0 U r c e s 263 one is available for the selected resource type. Resource IEdit as Text always starts the Text editor. . . Resource file types A file you create and edit with Resource Workshop can be in either binary or text format. Resource Workshop generates standard Windows file formats, which means you can use Resource Workshop files with programs that generate binary code from resource script files. Here are the types of resource files you can create with Resource Workshop: • • • • • • • • • • • 16-bit device driver (.DRV) Bitmap (.BMP) Control Panel applets (.CPL) Cursor (.CUR) Dialog (.DLG) Executable (.EXE) Dynamic link library (.DLL) Icon (.ICO) Resource script (.RC) Resource (.RES) VBX control libraries (.VBX) Executable and dynamic-link library files An executable (.EXE) or dynamic-link library (.DLL) file is the ultimate destination for all resources you define with Resource Workshop. It is the file that users execute to. run your program. In general, you compile the resource script file (.RC file) into the resource file (.RES file), then use your compiler to bind the .RES file to the executable or .DLL file. If you want to change the resources in a compiled binary file (an executable file, a .DLL file, or a .RES file), Resource Workshop decompiles the file and lets you make the changes, then saves the resources back to the original file. Working with binary files Resource Workshop lets you open executable (.EXE), dynamic-link library (.DLL), and resource (.RES) files as resource projects so you can customize their resources. When you load one of these files, Resource Workshop decompiles the resources in the file and shows them to you as though they were part of a regular .RC file. When you finish, Resource Workshop compiles the resources again into binary code and stores them in the original file. Because the resources you work with in this type of resource project are never stored as resource scripts, you cannot assign any Jdentifier~ to the resource IDs. However, you can save the resource project as an .RC file. Then the resources can be saved as resource scripts, and you can assign identifiers to them. 264 e+t User's Guide Note Once you save the resource project as an .RC file, Resource Workshop will not save the resources back to the original file. Opening and saving .EXE, .Dll, and .RES files To open an .EXE, .DLL, or .RES file and save it as a resource script file, 1 Choose File I Open and choose Resource Project in the Viewer field. 2 Select the .EXE, .RES, or .DLL file from the Open a File dialog box. Click OK. 3 Choose File I Save File As. In the Save File As dialog box, select Resource Script (.RC) from the List Files of Type box. In the Filename box, enter the name of the new .RC file. 4 Press OK to save the file. Using a resource editor You can edit any resource in a resource project by double-clicking the resource in the Resource Project window, or by selecting it and choosing Resource I Edit. Here are the available editors: • For a dialog resource, Resource Workshop loads the Dialog editor. • For a menu resource, Resource Workshop loads the Menu editor. • For an icon, bitmap, or cursor resource, Resource Workshop loads the Graphics editor. • For all other resources, Resource Workshop loads the Text editor. Renaming a resource To rename a resource in your resource project, Select the resource in the Resource Project window. 2 Choose Resource I Resource Attributes. Resource Workshop displays the Resource Attributes dialog box, where you rename your resource. 3 Enter the new resource name in the Name box. If you want to create a new identifier, or change the one you already have, enter the, new value in the Identifier Value box. 4 Choose OK. C hap t e r 1 3, W0 r kin 9 wit h res 0 U r c e s 265 Deleting a resource To delete a resource from a resource project, select it in the Resource Project window, and then do one of the following: • To delete the resource, press the Del key or right-click and choose Remove from Project. • To reuse the resource, right-click and choose Cut to remove the resource and place it in the Windows Clipboard so you can paste it elsewhere. Specifying resource memory options Resource Workshop makes it easy to specify how each resource in your resource project should be managed in memory. It is better to leave the memory settings at their defaults unless you are an experienced Windows programmer-you might not be able to foresee the implications of changing the way a resource is handled in memory. To specify memory options, 1 Select the name of the resource in the Resource Project window. 2 Choose Resource IResource Attributes to open the Resource Attributes dialog box. 3 Check one or more of the Memory Options check boxes. Moving a resource You can move resources from one file in a resource project to another file in the resource project by using the Resource IResource Attributes command. Both files must be part of the current resource project. Select a resource in the resource project file by either editing it or highlighting it in the Resource Project window. 2 Choose Resource IResource Attributes to open the Resource Attributes dialog box. The resource name and the file it currently resides in are displayed in the Resource Attributes dialog box. 3 Click the File drop-down list to choose the file you want to move the resource to. Click OK. 16·bit Vs. 32·bit resources By default, new resource projects created with File INew IResource Project are created as 32-bit resources. This makes two resource types available that are not available for 16-bit resources: • MENUEX • DIALOGEX 266 C++ Use r 's G u ide When resource script files are compiled, they are compiled based on the current IDE project settings. Resource script files originally targeted for 32-bit platforms can easily be recompiled for a 16-bit program without changing the script file as long as they do not contain a MENUEX or DIALOGEX resource type. Compiled resources (.RES) files are only compatible with the platform they originally targeted. For example, you cannot link a 16-bit compiled resource to a 32-bit compiled executable. If you want to change the target, you have to reload the .Re file with the IDE project and retarget the platform. Saving a resource It is a good idea to save your work often. Resource Workshop provides you with a variety of save commands so you can choose exactly what you want to save and how to save it. You can: • Rename the current resource file using File I Save As. • Save the entire resource project and all of the resources it contains. • Save the resource in a separate file by: til . Saving the resource in a resource script file. o Saving a bitmapped resource as a separate file. Resource Workshop saves the resource project file and any files it references. Saving a resource in a resource script file To save an individual resource as a resource script file, 1 If the resource is not already open, select the resource nam.e in the Resource Project window. 2 Choose Resource I Save Resource As. This command displays the Save Resource As dialog box. 3 Select Resource Script (.RC) as the resource type. 4 Enter the file name of the new resource script. If you want to replace the resource in the current project with a reference to this new file, check the Replace Resource With Reference To This File option. If this box is cleared, the current resource project remains unchanged, and the new file is created. By default, this box is cleared for non-bitmapped resources. 5 Click OK. Usually, you save a resource with a resource project. You would probably only save it in its own file if you create a separate resource project that contains just related types of. resources (such as menus and accelerators). You can then link this resource file to a resource project that uses the same resources. C hap t e r 1 3, W0 r kin 9 wit h res 0 U r c e s 267 Saving a bitmapped resource as a file You can save a bitmapped resource as a f~e. You will probably do this step only if you want to put the bitmapped resource in binary format in a separate file for the first time. To save a bitmapped resource as a file, 1 If the resource is not already open, select the bitmapped resource in the Resource Project window. 2 Choose Resource ISave Resource As. This command displays the Save Resource As dialog box. 3 Select the appropriate resource type. 4 Enter the file name of the resource. If you want to replace the bitmapped resource in the current project with a reference to this new file, leave the Replace Resource With Reference To This File option checked. To leave the current resource project unchanged, clear this option. By default, this option is checked for bitmapped resources. 5 Click OK. Editing a resource as text In addition to creating and modifying a resource directly with a resource editor, you can work directly with its resource script. To work with the resource script for a resource, select the resource from the Resource Project window. Then choose Resource IEdit As Text. Resource Workshop brings up the source script for the resource in the Text editor. Here is an example of the resource script for a menu: POPUP "&Edit" MENUITEM "&Undo\tCtr1+Z", CM_EDITUNDO MENUITEM "&Cut\tCtr1+X", CM_EDITCUT MENUITEM "&Copy\tCtr1+C", CM_EDITCOPY MENUITEM "&Paste\tCtr1+V", CM_EDITPASTE The only readily comprehensible parts of a script for a bitmapped resource are the first and second lines (the resource name and BEGIN) and the last line (END). ABi tmap BITMAP BEGIN '42 4D 66 00 00 00 00 00 00 00 3E 00 00 00 28 00' '00 00 14 00 00 00 OA 00 00 00 01 00 01 00 00 00' '00 00 28 00 00 '00 00 00 00 00 00 00 00 00 00 00' 268 C++ Use r '5 GU ide '00 '00 '20 'EO 00 00 00 00 02 EF EF FC 00 FF FF 00 00 EO EO 00 00 00 00 00 00 FF FF FF 00 EO 00' 00 EC 08 20 00 EF FF EO 00 EC 41' 00 E1 01 20 00 F5 FF EO 00 F9 FF' 00' END Everything between the second line and the last line is hexadecimal code. If you like, you can edit this code to see the effect on the bitmap, but do so at your own risk. Note Do not spend any time inserting comments in your resource script or formatting the text, because the Resource Workshop incremental compiler does its own formatting and di~cards all comments. C hap t e r 1 3, W0 r kin 9 wit h res 0 U r c e s 269 270 C++ Use r 's G u ide Working with dialog boxes Dialog boxes give the user a way to interact with your application. A dialog box is usually a pop-up window that lets the user specify information (files to open, colors to display, text to search for, and so on). When a dialog box is displayed in an application, it is shown as a window. The dialog box usually contains a number of controls, such as buttons, text boxes, and scroll bars. Controls usually let the user specify information, but can also be used to display static text and graphics in a dialog box. From the perspective of the programmer, the dialog box is the parent window and each control is a child window acting as an input or output device. To create a dialog box, you fill an empty dialog box with the controls you want. Resource Workshop's Dialog editor makes it easy to create and edit dialog boxes. Working with dialog boxes involves four steps: • Open an existing resource project or create a new one. • Create a new dialog box or edit an existing one. • Test the dialog box. • Save the dialog box. Using DLGINIT resources A DLGINIT resource is created automatically when a dialog box contains VBX controls. It holds information needed to initialize the controls. Creating or editing a DLGINIT resourCe explicitly by hand is rarely necessary. There is no available editor to create an explicit DLGINIT resource. C hap t e r 14, W0 r kin 9 wit h d i a log box e s 271 Creating a new dialog box To create a new dialog box: Choose File INew IResource Project to start a new resource project or File IOpen to load an existing resource project. 2 Choose Resource INew. Resource Workshop displays the New Resource dialog box. 3 In the Resource Type list box, select DIALOG or DIALOGEX. Choose DIALOGEX to specify ExStyle information for dialogs whose target is Windows 95 or NT. 4 Choose the Options button to specify the dialog box name and type, and to set other options for the new dialog, including the dialog template. 5 Select OK in the Options dialog to accept the options values. Select OK again in the New Resource dialog to create the new dialog. You are now in the Dialog editor where you can customize your dialog box. Creating a new dialog box in a resource script file To create a new dialog box as an independent resource script file: In the Resource Project window, right-click to display the SpeedMenu. Choose Add to Project. The Add File to Project dialog box appears. 2 In the List Files of Type box, choose Resource Script (*.dlg). 3 Enter a new name in the File Name box. 4 Choose OK. 5 Choose Yes when Resource Workshop asks you if you want to create the file. You have created an empty dialog file. To create a new dialog box and add it to the empty .DLG file: 1 Choose Resource INew to display the New Resource dialog box. 2 For the resource type, choose DIALOG or DIALOGEX. Choose DIALOGEX to specify ExStyle information for dialogs whose target is Windows 95 or NT. 3 Click the Options button. 4 In the New Resource to be Placed In box, choose the name of the dialog script file you just created. Select other options as required. 5 Click OK twice to create the new dialog. Editing an existing dialog box To edit a dialog box that already exists in a project file: 272 C++ Use r' s G u ide 1 Use File IOpen to open the project that contains the dialog box you want to edit. 2 Double-click the dialog resource name you want to edit, or select it and choose Resource IEdit. You are now in the Dialog editor. Adding a caption to a dialog box To add a caption to a new diak>g box: Right-click in an empty area of the dialog box and choose Properties to display the Property Inspector. 2 If not already selected, select the General page. 3 In the Caption box, type the caption you want to appear at the top of your dialog box. 4 Choose OK.· Including a menu in a dialog box Because it is really a window, a dialog box could include a menu. For example, some applications use a dialog box for the main window, in which case the dialog box would need a menu. To include a menu in your dialog box: Define the menu as a separate resource and add it to the project. Remember the menu resource name. 2 Open the dialog box you want to add the menu to. 3 Right-click in an empty area of the dialog box and choose Properties to open the Property Inspector. 4 Click the Window page. Enter the menu resource name in the Menu field. The Dialog editor will not display the menu until you put the Dialog editor into text mode. Choosing a window type, frame style, and dialog box style You choose a window type, frame style, and dialog box style in the Property Inspector. To open the Property Inspector, right-click in an empty area of the dialog and choose Properties. Choose a window type for your dialog box by selecting the Window· page. Choose oile of the Window Type options. C hap t e r 1 4, W0 r kin 9 wit h d i a log box e s 273 2 Choose a frame type for your dialog box by selecting the Frame page. Choose one of the Frame Type options. The frame type determines the appearance of the dialog box frame and whether the dialog box displays a title bar at the top. 3 Choose frame styles for your dialog box by selecting the Frame page. Choose one of the Frame Attributes options. The attributes determine what the dialog box looks like and how the user works with it. For 32-bit applications using DIALOGEX, use the Extended page to determine how the dialog box is positioned, its alignment, reading order, and its behavior. Specifying dialog box fonts To choose how text is displayed in your dialog box: Right-click in an empty area of the dialog box and choose Properties to display the Property Inspector. 2 Choose the Fonts page. 3 Select a typeface, size, and style for text in your dialog box. The characters displayed at the bottom of the Font page show the current typeface, size, and styles you've selected. 4 Choose OK. Note Changing the font for a dialog box will cause the size and position of the dialog box and any contained controls to change. This is because the coordinate system for dialog boxes (dialog units) is based on the average character width of the font. As the average character width changes, the coordinate system changes. Assigning a custom class to a dialog box If you're an experienced Windows programmer, you might want to assign a custom class to your dialog box. Then you can process dialog box messages with your own Windows procedures instead of using the standard Windows windowing procedure. Another reason for assigning a custom class is to make the dialog box a Borland-style dialog box. To assign a custom class to a dialog box: Right-click in an empty area of the dialog box and choose Properties to display the Property Inspector. 2 Click the Window page. Enter the class name in the Class box. If you are creating a Borland-style dialog box, enter bordlg or BorDlg_Gray. 3 Choose OK to save the changes and close the Property Inspector. 274 C++ Use r 's G u ide Setting the position of a dialog box To set the size of the dialog: Right-click in an empty area of the dialog box and choose Properties to display the Property Inspector. 2 Modify the Width and Height values on the General page. 3 Click OK to save the changes. To set the initial location of a dialog: Right-click in an empty area of the dialog box and choose Properties to display the Property Inspector. 2 Modify the Top and Left values on the General page. 3 Click OK to save the changes. Note When the dialog box has a title bar (the default), you can drag it with the mouse to position the dialog box. When the dialog box has a resizable border (the default), you can size it with the mouse. Testing a dialog box Choose Dialog ITest Dialog to test your dialog box. To verify that your controls are in the order you want them, press Tab and the arrow. Enter text to see how text is scrolled in an edit text control. To leave test mode and return to edit mode, do any of the following: • Click the dialog box's OK or Cancel button. • Choose Dialog ITest Dialog again. • Press Enter. • Press the system close button on the text dialog. Note Some controls, such as the Tab, ListView, and TreeView common controls, will not display in test mode as they do in design mode or as they will appear in your program. This is because they are dependent on your program to display the correct information. Programming a dialog box with OWL To program a dialog box with OWL, use the TDialog class. For example, this shows how to create and display a modal dialog box: TDialog dialogl(GetApplication()->GetMainWindow(), IDD_DIALOG1); dialogl.Execute(); C hap t e r 1 4, W0 r kin 9 wit h d i a log box e s 275 dialogl is the name of the dialog box class, and IDD_IDENTIFIERI is the identifier for the dialog box resource. ' Programming a dialog box with the Windows API To program a dialog box with the Windows API, use the DialogBox function. For example, the following code shows how to create and display a dialog box: HINSTANCE hInst; HWND hwndParent; DLGPROC dlgProc; dlgProc = (DLGPROC) MakeProc Ins tance (ResModeDlgProc, hInst); DialogBox(hInst, MAKEINTRESOURCE(IDD_RESDEMODIALOG), hwndParent, dlgProc); FreeProcInstance((FARPROC) dlgProc); where: ResModeDlgProc The dialog procedure function that handles messages from controls hlnst The HINSTANCE handler of the Windows module (.EXE or .DLL) which controls the dialog resource IDD_RESDEMODIALOG Replaced with the resource ID of the dialog hwndParent The parent window of the dialog Working with controls Once you have defined a dialog box, you can create and manipulate its controls. In the Dialog editor, the Dialog menu, Dialog local menu, the Control palette, and the Tool palette make it easy to work with controls. Adding controls to a dialog box To add a new control to a dialog box: 1 Click the page and control you want in the Control palette. 2 Your cursor changes to a cross hair when you move the cursor over the dialog box you are designing. 3 To place the control with the default size, click in the dialog box where you want to place the top left comer of the control. 4 To place the control and size it at the same time, click in the dialog where you want to place the top left comer of the control. Drag the mouse to the lower right until the control is the desired size. 276 C++ Use r 's G u ide If you select a control from one of the palette pages and change your mind about placing it, choose the Selector tool on any page of the Control palette. Your cursor returns to the arrow shape and you can choose another control or work with existing ones. You can also use the Dialog menu to add controls to your dialog box: 1 Choose Dialog I Insert New. 2 Choose the control you want, then click OK. 3 Click the spot in the dialog box where you want to add the control. To add multiple copies of the same control, hold the Shift key down while clicking in the dialog. When you are finished with the control type, click the Selector tool. Working with custom controls In addition to standarc;l controls, common controls, and Borland controls, you can add custom controls to a dialog box. A custom control is any other window class that you want to add to your dialog box, including Visual Basic controls. Custom controls are stored in .DLL or Visual Basic custom control (.VBX) files. Before you can use custom controls, you must install them. . To install custom controls: 1 Choose Options I Environment I Control Libraries. 2 Click Add. 3 In the File Open dialog box, select the name of the .DLL file you want to open. 4 If you are installing VBX controls, choose the Windows system directory and the name of the .VBX file you want to open. (.VBX files are automatically installed in this directory. ) «I The file name and list of the controls in that file are displayed in the Installed Controls list. S Click Add to a.of the Control palette. For information on adding the control to the dialog box, see Adding controls to a dialog box. To remove custom controls: 1 Choose Options I Environment I Control Libraries. 2 Choose the name of the control library you want to remove. 3 Click Remove, then OK. The library and its controls are no longer accessible from Resource Workshop. Note When you use VBX controls in a dialog box, a DLGINIT resource is produced. In addition, the Property Inspector displayed for a VBX control is always modeless, so the changes take effect immediately. It is always in list format. C hap t e r 1 4, W0 r kin 9 wit h d i a log box e s 277 Duplicating a control To place multiple, identical copies of a control in rows and columns: 1 Select the control you want to duplicate. 2 Right-click the control and choose Duplicate. The Duplicate Control dialog box is displayed. 3 Enter the number of rows and columns into which you want to arrange the duplicated controls. For example, if you are placing push buttons, and want one row of three buttons across, enter 1 in Rowand 3 in Column. 4 Enter the spacing you want between rows and columns in the Spacing fields. It is recommended that you enter 6 for row spacing and 8 for column spacing. Units are in dialog units. 5 Click OK. Your control is now duplicated. The caption is the same as the original, but the ID is automatically incremented. Moving and resizing a single control To move a control with the mouse: 1 Select the control. 2 Hold the left mouse button down and drag the control to a new location. To resize a control with the mouse: Select the control. 2 Move the mouse cursor to one of the black nibs at the control's edge or comer. When it turns into a double arrow, hold the left mouse button down and drag to the desired size. To move a control with the keyboard: 1 Press Tab until the control you want is selected. 2 Press the Up arrow key to move the control up; press the Down arrow key to move it down. Press the Right arrow key to move the control to the right; press the Left arrow key to move it to the left. 3 Press Enter when the control is in a satisfactory location. To size a control with the keyboard: Press Tab until the control you want is selected. 2 Choose Dialog I Size or right-click and choose Size. The Size dialog box is displayed. 3 Choose the Width option and enter the control's width. 278 C++ Use r 's G u ide 4 Choose the Height option and enter the control's height. S Press OK to change the control's size. Its top left comer stays in the same place. You can also use arrow keys to size a control: Ctrl + left arrow Ctrl + right arrow Ctrl + up arrow Crtl + down arrow Decreases width one dialog unit Increases width one dialog unit Decreases height one dialog unit Increases height one unit You can also move and resize a control with the General page of the Property Inspector. Select the control, double-click, and change the appropriate Top, Left, Width, and Height values. If you change your mind about moving or resizing a control, select Edit IUndo. Selecting multiple controls To select multiple controls: 1 Choose the Selector tool. 2 Place the cursor where you want the selection frame to start. It must be outside of any controls. 3 Click the left mouse button and hold it down. 4 Drag your mouse so that the selection frame surrounds or intersects all the controls you want to select. S Release the mouse button. Note You can also select multiple controls by pressing the Shift key while clicking on controls. The selection becomes cumulative. Clicking a second time while holding the Shift key will unselect the control, while keeping other selections. Depending on the setting of the Selection Rectangle Must Surround Controls option in Options IEnvironment IResource Editors IDialog, the selection rectangle must either entirely surround the controls, or just intersect them. You can select all controls in a dialog box by right-clicking and choosing Select All. Aligning multiple controls To display and adjust the alignment grid: 1 Choose Dialog IShow IGrid to display the alignment grid. 2 To adjust the grid's granularity, choose Dialog IGrid Spacing. In the Grid Spacing dialog box enter the desired width and height of each grid cell. C hap t e r 1 4, W0 r kin 9 wit h d i a log box e s 279 Note You may have already set grid spacing defaults with Options IEnvironment I Resource Editors IDialog. . 3 If you want the controls to snap to" the grid, select the Snap to Grid option in the Grid Attributes section of Options IEnvironment IResource Editors IDialog. You can also toggle Dialog ISnap to Grid. U To align multiple controls: 1 Select the controls you want to align. 2 Choose Dialog IAlign IControls or right-click one of the selected controls and choose Align. In the Alignment dialog box, choose how you want to align the controls horizontally and vertically. Controls can be aligned to the left, center, or right. They can also be spaced equally or centered in the window. 3 When controls are selected, you can use the arrow keys to fine-tune their positions on the grid. The arrow keys move the selected controls one dialog unit. To align multiple controls into an array: 1 Select the controls you want to align. 2 Choose Dialog IAlign IArray or right-click one of the selected controls and choose Array. In the Array dialog box, choose the format of the array by specifying the number of rows and columns. Order the controls from left to right or top to bottom. To evenly space multiple controls: . Select the controls you want to arrange. 2 To space the selected controls horizontally equidistant from each other in the dialog box, choose Dialog ISpace IHorizontally EquaL 3 To space the selected controls vertically equidistant from each other in the dialog box, choose Dialog ISpace IVertically EquaL You can also use the Tool palette to align and space controls. To undo alignment options, choose Edit IUndo or press Alt+Backspace. You may have to choose Undo more than once. Resizing multiple controls To resize multiple controls: 1 Select the controls you want to resize. 2 Choose Dialog ISize. The Size Controls dialog box is displayed. You use this dialog box to resize controls. 3 Choose the Width option and enter the width for all controls. 4 Choose the Height option and enter the height for all controls. The size of all selected controls change. Their top left comers stay in the same place. 280 C++ Us e r 's Gu ide Note You can undo any sizing options by choosing Edit IUndo or by pressing Alt+Backspace. You may have to choose Undo more than once. You can also move and resize controls with the General page of the Property Inspector. Select the controls, double-click one of them, and change the appropriate Top, Left, Width, and Height values. Reordering controls You can specify the order in which users access the controls in your dialog box. The order is especially important when you have defined groups of related controls. To specify the order of controls: 1 Choose Dialog ISet Creation Order or Set Creation Order from the SpeedMenu. A special mode is invoked. 2 Each control is numbered to show its current place in the overall order. Initially, this is the order in which you created the controls. 3 Click the items you want to assign new order numbers to, beginning with 1. The Dialog editor displays a blue box around all the controls you have already picked. Once you have clicked a control to assign it an order number, you cannot pick any previously selected controls again. If you make a mistake and want to go back to the original order, just click on all the controls in the order in which you assigned them. You can also press Escape to cancel. When you finish assigning new order numbers, press Enter to return to design mode. You can also right-click and choose End Mode to exit and save changes, or Cancel Mode to exit without saving changes. Grouping controls You can group controls to let the user move among them using the arrow keys. For example, if you add three radio buttons, you may want them to function as a group. To group controls: 1 If necessary, move the controls so that they are together. 2 Choose Dialog ISet Group Flags or Set Group Flags from the SpeedMenu. 3 For each group you want to define, click the first member so it is surrounded by a blue box. You do not have to identify the last member of a group. By clicking the first member of each group, you also identify the last member of the previous group. To ungroup controls: 1 Choose Dialog ISet Group Flags or Set Group Flags from the SpeedMenu. 2 Click the control that is surrounded by a blue outline. This turns off the group flag .. Chapter 14, Working with dialog boxes 281 You mark only the first control in each group with the Group attribute. Controls are included in the group according to the order in which they are added to the dialog box. For example, if you add seven controls to your dialog box and then turn on the Group property of the first and fifth controls, the first four controls are included in the first group, and the remaining controls are included in the second group. When you finish grouping controls, press Enter to return to design mode. You can also right-click and choose End Mode to exit and save changes, or Cancel Mode to exit without saving changes. Specifying which controls are tab stops When you add a control that can accept user input to a dialog box, it is automatically defined as a tab stop. You can change this so that only some controls are tab stops, and users can use Tab to move only to the controls you want. To set a tab stop: 1 Choose Dialog ISet Tabstops or Set Tabstops from the SpeedMenu. A special mode is invoked. Any controls currently set as tab stops are outlined with a blue box. 2 To set a tab stop, click any control that is not already outlined in blue. 3 To remove a tab stop, click any control that is already a tab stop (outlined in blue). 4 When you finish changing tab stops, press the Enterkey. You can also tum on the Tab Stop property using the General page in the Property Inspector. When you finish assigning tab stops, press Enter to return to design mode. You can also right-click and choose End Mode to exit and save changes, or Cancel Mode to exit without saving changes. Editing control properties Once you have added a control to your dialog box, you can easily modify it by rightclicking it and choosing Properties. The Property Inspector is displayed, with options that can modify the appearance and behavior of your control. The property settings vary according to the type of control you are working with. Note You can also double-click a control to display the Property Inspector. 282C + + Use r 's G u ide Using the Dialog editor You use the Dialog editor to create and edit dialog boxes. The Dialog editor displays: • The dialog you are designing • The Control palette that contains pages for standard Windows controls, Windows common controls, BWCC controls, Visual Database controls, and custom controls, including VBX controls • The Tool palette that contains tools such as alignment tools • The Property Inspector that lets you set properties for controls and dialog boxes Using the Property Inspector You use the Property Inspector to view and set properties for controls and dialogs. The Property Inspector can be modal or modeless. The Dialog editor uses a WYSIWYG method of displaying properties when it can. The modal Property Inspector The modal Property Inspector only displays property pages. Changes you make in the modal Property Inspector do not take effect until you click the OK or Apply button, or select another property page tab. You can also cancel changes to the current page by clicking Cancel. The modal Property Inspector lets you set properties for: • One control • A group of selected controls with properties in common • The dialog box Chapter 15, Using the Dialog editor 283 The modeless Property Inspector The modeless Property Inspector displays different view of properties: • Property pages • The sorted property list box • The unsorted property list box • The generic, or summary, property page Changes you make in the modeless Property Inspector take effect immediately. There are no buttons to click to apply or cancel changes. The modeless Property Inspector lets you switch between properties for different controls or dialog boxes. To switch between objects, use the drop-down list at the top of the Inspector. The sorted list displays properties in sorted alphabetically; the unsorted list displays properties in the order they are displayed on the Property Page. To set properties in the sorted or unsorted list, 1 Click the property you want to change. 2 Enter a value or choose it from the drop down list. • If an ellipse is displayed in the right column, click it to display a dialog box where you set multiple properties. Note If a VBX control is among the selected controls, the Property Inspector is always modeless (changes take effect immediately) and is in list format only. Displaying the Property Inspector To display the modal Property Inspector, do one of the following: • Right-click the control and choose Properties. • Right-click in an empty area of the dialog box and choose Properties. • Double-click the control you want to set properties for. • Double-click in an empty area of the dialog box. • Select multiple controls, right-click one of them, and choose Properties. • Select multiple controls and double-click one of them. To display the modeless Property Inspector: • Choose Dialog IShow IProperty Inspector. Grice the Property Inspector is displayed, right-click the Inspector to choose the view you want. 284 c++ User's Guide About the Control palette The Control palette consists of the following pages: • The Standard page contains tools that let you place standard Windows controls. • The Common page contains tools that let you place common Windows controls. • The BWCC page contains tools that let you place Borland-style controls. • The Custom page contains tools that let you place any custom controls you may have installed, including VBX controls. • The Data Access page contains tools that let you place the Visual Database Tools Data Access controls. • The Data Aware page contains tools that let you place the Visual Database Tools Data Access controls. Moving the Control palette To move the Control palette, click and drag the title bar of the palette to a new location. Hiding and showing the Control palette To hide and show the Control palette: • Choose Dialog IShow IControl Palette. • Right-click outside the dialog box you are designing, and choose Control Palette. To place a control • Click the page of the Control palette you want. • Select a control tool with your mouse by clicking it. • To place the control with the default size, click the mouse button on the dialog. • To place the control and size it at the same time, click and drag the mouse in the dialog to the desired size. Chapter 15, Using the Dialog editor 285 Standard page of the Control palette The Standard page of the Control palette contains tools for placing standard Windows controls in your dialog box. Click one of the following tools for more information: Selector Radio Button Static Text List Box Horizontal Scroll Bar Group Box Vertical Static Line Static Rectangle Selector tool You use the Selector tool to select one or more controls in your dialog box. To select a single control, click the Selector inside the controL To select more than one control, click and drag your mouse around the controls you want to select. Note You can also select multiple controls by pressing the Shift key while clicking on controls. The selection becomes cumulative. Clicking a second time while holding the Shift key will unselect the control, while keeping other selections. When you use the Selector tool, your pointer is the shape of an arrow. Choose the Selector tool to exit another mode and return your pointer to the arrow shape. The Selector tool is available on all pages of the Control palette. Push Button tool The Push Button tool puts a push button control in your dialog box. A push button control sends a message to its parent when a user selects it. The push button is a rectangle with rounded comers. It can contain text, an icon, or a bitmap. Windows defines a set of control ID values and names for the standard push buttons used to exit dialog boxes. To use these buttons, you need to enter the predefined value or name in the General page of the Property Inspector. • Enter the ID name (IDOK, etc.) in the ID box. • Enter the text you want to display on the button in the Caption box. 286 c++ User's Guide The predefined ID values are: Note 1 IDOK OK 2 IDCANCEL Cancel Abort 3 IDABORT 4 IDRETRY Retry 5 IDIGNORE Ignore 6 IDYES Yes 7 IDNO No The ID name must be entered in uppercase letters. Radio Button tool The Radio Button tool puts a radio button control in your dialog box. A radio button control is a circular button with text, an icon, or a bitmap. The control sends a message to its parent when the user selects it. Radio buttons are used in groups to represent related but mutually exclusive options. Check Box tool The Check Box tool puts a check box control in your dialog box. A check box control is a small button that sends a message to its parent when a user selects it. When a check box is selected, an X appears on the button. When a check box is not selected, the X disappears. Check boxes are often used to represent Boolean (ani off) states for individual options. Check boxes can also have a third state, represented by a light gray shading. This state is usually interpreted as "indeterminate." Static Text tool The Static Text tool puts a static text control in your dialog box. A static text control is text in a rectangle. The text is displayed as: • Left-aligned, without word wrap • Left-aligned, with word wrap • Centered • Right-aligned • Simple Chapter 1 5 ,U sin 9 the Dialog editor 287 Text Edit tool The Text Edit tool puts an edit control in your dialog box. An edit control allows a user to: • Enter text • Edit text • Move the insertion point • Delete text • Move text An edit control receives focus when the user clicks it or presses the Tab key to move to it. Once selected, the edit control displays text and a flashing cursor to indicate the insertion point. The edit control can send a message to its parent when the user selects it. List Box tool The List Box tool puts a list box control in your dialog box. The list box control displays a list of items. The user can browse the list and choose one or more items. List box items can be represented by text strings, bitmaps, or both. Combo Box tool The Combo Box tool puts a combo box control in your dialog box. A combo box control is a combination of a list box control and a static text or edit control. • The list box control can drop down; it does not have to display all the time. • The static text control forces an item (if one exists) to be displayed in the list box portion of the combo box control. • The edit control allows the user to enter a selection. The list box will then higlight the first item that matches the selection. Then, the user can select the highlighted item. Horizontal Scroll Bar tool The Horizontal Scroll Bar tool puts a horizontal scroll bar control in your dialog box. A horizontal scroll bar control consists of a horizontal rectangle with a direction arrow at both ends. A horizontal scroll bar control lets the user scroll the contents of the window to the left or right. The control sends a message to its parent when a user selects it. 288 c++ User's Guide Vertical Scroll Bar tool The Vertical Scroll Bar tool puts a vertical scroll bar control in your dialog box. A vertical scroll bar control consists of a vertical rectangle with a direction arrow at both ends. A vertical scroll bar control lets the user scroll the contents of the window to the up or down. The control sends a message to its parent when a user selects it. Group Box tool The Group Box tool puts a group box control in your dialog box. A group box control is rectangular box around a group of controls. It is used to visually group controls together. You can include a caption in the upper left comer of the group box. An application cannot.send messages to a group box. Static Frame tool The Static Frame tool puts a static frame control in your dialog box. A static frame is an empty border that can be black, gray, or white. It can also appear etched. A Static Frame control is used for visual effect. Static Rectangle tool The Static Rectangle tool puts a static rectangle control in your dialog box. A static rectangle control is a rectangle that can be black, gray, or white. A static rectangle control is used for visual effect. Horizontal Static Line tool The horizontal static line tool puts a horizontal static line control in your dialog box. A horizontal static line control is used for visual effect. Note Static lines are only displayed when using Windows 95 or Windows NT with the shell. Vertical Static Line tool The vertical static line tool puts a vertical static line control in your dialog box. A vertical static line control is used for visual effect. Note Static lines are only displayed when using the Windows 95 or Windows NT with the shell. C hap t e r 1 5, Usin 9 the 0 i a log e d ito r 289 Static Picture tool The Static Picture tool puts a static picture control in your dialog box. A static picture control can display an icon, bitmap, or enhanced metafile. A static picture control is used for visual effect. The Caption property identifies the resource ID of the icon, bitmap, or enhanced metafile. The actual picture can be viewed by putting the Dialog editor into test mode with the Dialog I Test Dialog command. Common page of the Control palette The Common page of the Control palette contains tools for placing Windows common controls in your dialog box. Click one of the following tools for more information: Tab Control Animation Tree View Hot Key Up-Down Header Status Window Animation tool The Animation tool puts an animation control in your dialog box. An animation control is a window that displays an Audio Video Interleaved (AVI) clip, a series of bitmap frames. The clip is displayed without sound. Set the Caption property to the AVI filename of the clip. Note You can set up the AVI file to display when the animation control is created. However, you cannot play the clip in design mode. To play the clip, check the Auto Play property on the Animation page and put the Dialog editor into test mode (Dialog I Test Dialog). Tab Control tool The Tab Control tool puts a tab control, like a set of notebook dividers, in your dialog. Tabs contain identifying text. Tabs are used to define multiple pages in a dialog box. A user clicks a tab to switch between dialog box pages. Note 290 You cannot add the actual tabs using the Dialog editor because the tabs are not encoded in the .RC files. They can only be created through programming. You can use the C++ Use r 's Gu ide Sample Item Count property (one of the properties on the TabControl page) to test what the tabs would look like. Tree View tool The Tree View tool places a tree view control in your dialog. A tree view control displays a group of items in a hierarchy, with icons to expand and collapse the hierarchy. Each item consists of a label and an optional bitmapped image. List View tool The List View tool places a list view control in your dialog. A list view control displays a group of items. You can display the items in the group: • With their standard icons. Each item is represented by an icon and a text label. Items can be moved. • With their small icons. Each item is represented by a small icon and a text label to the right of the icon. Items can be moved. • As a list. Each item is represented by a small icon and a text label. Items are arranged in columns and cannot be moved. • As a report. Each item is represented by a small icons and text label, and additional information about each item. A header control is usually associated with a list view control. Hot Key tool The Hot Key tool places a hot key control in a dialog. A hot key control lets the user enter a combination of keystrokes to be used as a shortcut key. The hot key control displays the current choices and makes sure that the key combination selected is valid. Progress Bar tool The Progress Bar tool places a progress bar control in your dialog. A progress bar control, using a range and current position, shows an op'eration's percentage of completion. It can include text. You usually use a progress bar for an installation program. Up-Down tool The Up-Down tool places an up-down control in your dialog. An up-down control consists of an up and down arrow. The up-down control increments and decrements values in the companion control. C hap t e r 1 5, U sin 9 the D i a log e d ito r 291 Usually, you use an up-down control in conjunction with a companion control, also referred to as a buddy window. Track Bar tool The Track Bar tool places a track bar control in your dialog box. A track bar control lets the user change a value within a set range. The track bar displays ticks that represent the current value. The user adjusts a slider to change the value. Header tool The Header tool places a header control in a window, usually in a list view window. Headers can contain a string, a bitmapped image, and an application-defined 32-bit value. If a header contains both a string and an image, the image is displayed above the string. If they overlap, the string overwrites the image. Headers are usually used for column headings. By default, headers appear as text on a gray background. Headers do not have input focus. Rich Text Edit tool The Rich Text Edit tool places a rich text edit control in your dialog box. A user can enter and edit text in this control. The user can assign character and paragraph formatting attributes (font, colors, etc.) to the text, and can include embedded OLE objects. Status Window tool The Status Window tool places a status window control in your dialog box. A status window control is a horizontal window at the bottom of a parent window. The application can display different kinds of status information in the control. The control can be divided into parts to display different kinds of information. Tool Bar tool The Tool Bar tool places a tool bar control in your dialog. A tool bar control contains one or more buttons, that are visual representations of commands. When a button is selected, it sends a command message to the parent window. 292 C++ Use r 's G u ide BWCC page of the Control palette The BWCC page of the Control palette contains tools for placing Borland-style controls in your dialog box. Click one of the following tools for more information: Push Button Note Check Box Horizontal Line Static Text When you use one of more BWCC controls, you must link the BWCC library to your program or load it as a DLL. BWCC Push Button tool The BWCC Push Button tool puts a Borland-style push button control in your dialog box. A Borland-style push button control can contain symbols with high visual impact, as well as an owner draw option. A Borland push button is larger than most standard Windows push buttons. Its class is BarBtn. These are the values for the predefined Borland-style bitmap buttons: lOOK 1· IDCANCEL 2 IDABORT 3 IDRETRY ·4 IDIGNORE IDYES IDNO IDHELP 5 6 7 998 To add your own bitmap to the button, see"Adding a bitmap to a BWCC push button." Adding a bitmap to a BWCC push button To add your own bitmap to a BWCC push button: 1 Use the BWCC Push Button tool to add the generic BWCC button to your dialog box. Note its control ID. C hap t e r 1 5, U sin 9 the 0 i a log e d ito r 293 2 Switch to the Graphics editor and create a bitmap image. 3 In the Graphics editor, choose Resource I Resource Attributes to display the Resource Attributes dialog box. Then, do either of the following: • In the Resource Name box, enter an integer value that equals the control ID of the button plus the appropriate offset from the following table. 41 Rename the bitmap and assign it an identifier whose value equals the control ID of the button plus the appropriate offset from the following table. standard pressed keyboard focus id + 1000 id + 3000 id + 5000 id + 2000 id +4000 id + 6000 4 Close the Graphics editor. S Return to the Dialog editor. The bitmap displays on the BWCC button. BWCC Check Box tool The BWCC Check Box tool puts a Borland-style check box control in your dialog box. A Borland-style check box control is raised and displays a check mark, rather than an "X." Its class is BorCheck. A BWCC check box can also have a third state, represented by a light gray shading. This state is usually interpreted as "indeterminate." BWCC Group Box tool The BWCC Group Box tool puts a Borland-style group box control in your dialog box. A Borland-style group box control is a shaded rectangular box. The box groups other controls visually. It can appear recessed into the dialog box or raised above its surface. Its class is BorShade. BWCC Horizontal Line tool The BWCC Horizontal Line tool puts a Borland-style horizontal line control in your dialog box. The horizontal line control gives the impression of being etched into the surface of the dialog box. Its class is BorShade. You can convert lines to bumps, which appear to be raised above the surface of the dialog box. . 294 C++ Use r 's G u ide BWCC Radio Button tool The BWCC Radio Button tool puts a Borland-style radio button control in your dialog box. The radio button control is diamond-shaped and appears raised from the surface of the dialog box. When the user clicks the button, a black diamond appears in its center and the button shading reverses, giving the impression that it has been pushed down. Its class is BorRadio. BWCC Vertical Line tool The BWCC Vertical Line tool puts a Borland-style vertical line control in your dialog box. The vertical line control gives the impression of being etched into the surface of the dialog box. Its class is BorShade. You can convert lines to bumps, which appear to be raised above the surface of the dialog box. BWCC Static Text tool The BWCC Static Text tool places a Borland-style static text control in your dialog box. The static text control is a fixed text string in your dialog box. You use the string principally for labeling parts of the dialog box. Its class is BorStatic. Custom page of the Control palette The Custom page of the Control palette contains all installed custom controls, including VBX controls. For information on installing custom controls, see Working with custom controls. Data Access page of the Control palette The Data Access page of the Control palette contains the installed Visual Database Tools Data Access components. Data Aware page of the Control palette The Data Aware page of the Control palette contains the installed Visual Database Tools Data Aware components. C hap t e r 1 5, U sin 9 the D i a log e d ito r 295 Tool palette The Tool palette provides access to some of the most common Dialog editor tools, such as the alignment and spacing tools. Here are the tools you can choose from: Left Sides Horizontal Center Horizontal Center in Dialog Space Horizontally Equal Right Sides Vertical Center Vertical Center in Dialog Space Vertically Equal Tops Bottoms You can also use the Alignment dialog box to align controls and the Dialog ISpace command to space controls. Left Sides tool The Left Sides tool aligns selected controls so their left sides are aligned along the left side of the selection frame. The control that is leftmost determines the left edge of the selection frame. Horizontal Centers tool The Horizontal Centers tool aligns controls so their horizontal centers are in the center of the selection frame. The leftmost and rightmost controls determine the size and location of the selection frame. Right Sides tool The Right Sides tool aligns controls so their right sides are aligned along the right side of the selection frame. The control that is rightmost determines the right side of the selection frame. 296 C++ Use r 's Gu ide Horizontal Center in Dialog tool The Horizontal Center in Dialog tool moves the selection frame horizontally so it is centered in the dialog box. The relative position of the individual controls within the selection frame is unchanged. Tops tool The Tops tool aligns controls so their tops are aligned along the top of the selection frame. The topmost control determines where the top of the selection frame is located. Vertical Centers tool The Vertical Centers tool aligns controls so their vertical centers are in the center of the selection frame. Bottoms tool The Bottoms tool aligns controls so their bottoms are aligned along the bottom of the selection frame. The bottom most control determines where the bottom of the selectiop frame is located. Vertical Centers in Dialog tool The Vertical Center in Dialog tool moves the selection frame vertically so it is centered in the dialog box. The relative position of the individual controls within the selection frame is unchanged. Space Horizontally Equal tool The Space Horizontally Equal tool moves the selected controls so that they are horizontally equidistant from one another. Space Vertically Equal tool The Space Vertically Equal tool moves the selected controls so that they are vertically equidistant from one another. C hap t e r 1 5, Usin 9 the 0 i a log e d ito r 297 298 C++ Use r '5 G U ide About menus Menus are lists of commands the user chooses from. Most Windows applications have a menu bar across the top of the screen that contains the names of the application's menus. Each menu contains a set of commands. Terminology These terms describe the elements of a menu resource: pop-up command, pop-up menu, menu item, and menu separator. • Pop-up commands cause menus to be displayed. Pop-up commands can appear in the menu bar and can also appear inside pop-up menus, where they cause another menu (called a cascading menu) to be displayed. • Pop-up menus are the rectangular boxes containing lists of commands from which a user can choose. They come in two forms: Drop-down menus are displayed from the menu bar or from within a menu. They are tied to a pop-up command and are always displayed from that command's name. SpeedMenus (also referred to as floating menus or contextual popup menus) can appear anywhere in the application window. @ @ • Menu items are the commands that appear in the menus, such as Open, Save, or Print. • Menu separators are the lines that divide the menu items into logical groups. Separators do not do anything other than make the menu easier to read and use. Working with menus The Menu editor makes it easy to create and edit menus. Working with menus involves four basic steps: C hap t e r 16, Abo u t men u s 299 1 Create a new menu or edit an existing menu. The Menu Editor opens automatically. 2 Make changes to the menu. 3 Test the menu. 4 Save the menu. Using the menu editor You use the Menu editor to create and edit menus. It provides different views of the menu you are editing: • The Edit window shows the structure of the menu you are editing. It also has a test mode where you can view the menu as it will appear in your application. • The Property Inspector is where you customize the currently selected item in the menu. Edit window The Edit window shows you the structure of the men,:! you are editing. It looks very similar to a real menu. You can modify item text, add or remove items, and move items. To change other properties of the menu, use the Property Inspector. You can also view the menu in Test Mode. Test Mode allows you to view the menu as it will appear in your applicaiton. You can navigate the menu items as you would in your application. Creating a new menu To create a new menu, 1 Open the resource project you want to add the menu to, or create a new one by choosing File INew IResource Project. The New Resource Project dialog box is displayed. Base your project on the .RC file type. 2 Choose Resource INew to create a new resource for that project. Resource Workshop displays the New Resource dialog box. 3 In the Resource Type list, select MENU (or MENUEX for 32-bit projects). 4 Click Options to specify a type of menu other than the default. S Click OK to place the new menu in the current resource project file. Resource Workshop displays the Menu editor with a simple application menu you can begin customizing. Editing an existing menu To edit an existing menu, open the resource project in which the menu is stored and do one of the following: 300 c++ User's Guide • Double-click the menu resource name in the Resource Project window. • Highlight the menu resource name and choose Resource IEdit. Resource Workshop displays the Menu editor with the menu you have chosen already loaded. • Once a menu is loaded into the Menu editor, you are ready to add new menu commands, pop-up menus, or separators. You can also move, copy, or delete any part of the menu. You can customize your menus by adding accelerators and help messages for menu items using the Menu editor Property Inspector. Moving and copying menu statements You can drag and drop single menu items or entire menus. You can also use Cut, Copy, and Paste on the Menu SpeedMenu to move and copy the items in the menu's Edit window. To move a item, click and drag it into the desired location. (You can also use Shift+ drag.) If you move a pop-up menu, the entire menu is moved. A blue line with inverted arrows indicates where the top of the box will be placed. If you highlight some or all of the text, cut, copy, and paste actions effect only the highlighted text. To copy a item, use Control+ left mouse to click and drag it. You can also highlight it, right-click, and choose Copy. A copy is placed in the Windows Clipboard. To insert the cut or copied item into your menu, select the item immediately after the point at which you want the item to appear, right-click, and Paste. Undoing errors The Menu editor lets you undo and redo changes. Choose Edit IUndo or Edit IRedo. Adding menu items and separators You customize a menu by adding new menu items to it. You can customize your menu by adding new menu items, pop-up menus, and menu separators. Items are always added before the selected item. To add items to the end, select the empty area at the end and insert the new item. To add a new menu item, pop-up, or separator to a menu, Decide where you want the new menu item, pop-up, or separator to appear. Click the item in the menu's Edit window above where you want the statement added. 2 Select the new item you want to insert before the selected item. .. To insert a new menu item, right-click and choose New Menuitem or choose Menu INew Menuitem. C hap t e r 16, Abo u t men u s 301 • To insert a pop-up menu, right-click and choose New Popup or choose Menu I New Popup • To insert a new menu separator, right-click and choose New Separator or choose Menu INew Separator. You can now edit the text string, menu ID, help message, and accelerators, if any. Editing a menu item A newly added menu item has the generic designation "Item." To make it useful, you need to edit it. You can edit the text that displays in the menu directly, or with the Property Inspector. With the Property Inspector, you can also change the menu's numeric ID and put a check mark next to the menu if it is a toggle. Deleting a menu item To delete a menu item, click the item you want to delete, then: 1 Right-click and choose Cut to delete the statement and copy it to the Windows Clipboard. 2 Choose Edit IClear to remove it completely. Note that if you delete a POPUP statement, you delete the pop-up command it defines and all the items contained in the pop-up menu. Creating a pop-up menu A pop-up menu is one that can be displayed anywhere in the application's workspace. It is not tied to the menu bar. Pop-up menus display when the right mouse button is . clicked. The menu items displayed correspond to the selected object in the application. Each pop-up menu must be saved as a separate menu resource within the resource project file. To create a pop-up menu, 1 Choose Resource INew. Resource Workshop displays the New Resource dialog box. 2 In the Resource Type list, select MENU (or MENUEX for 32-bit projects). When you view the menu in the Test Menu pane, it will still appear tied to the menu bar, but as long as your code uses the TrackPopupMenu function correctly, the menu will float at run time. 3 Click the Options button to display the New Resource Options dialog box. Choose a popup menu style. 4 Click OK to create the new pop-up menu. The menu displays as it will appear on the screen at runtime. 5 Add any additional menu items you want. 302 c++ User's Guide 6 Edit the menu items using the Property Inspector if needed. . 7 Save your project. Adding accelerator text to menus To let users know what accelerators they can use, you can add accelerator text to your menu items. For example, if your application includes a Ctrl+X accelerator that duplicates the Cut command on the Edit menu, you can add the text "Ctrl+X" next to that command. • Use the tab character (\ t) to separate the menu title from the accelerator text. For example, Cut\tCtrl+X means that the accelerator Ctrl+X is assigned to the menu command Cut. • Use the right-align character (\a) to right-align accelerator text. Note Pop-up commands do not have accelerator keys. When you add accelerator text to menu items, you use the Text and the ID input boxes on the General page of the Menu editor Property Inspector. The items on the General page specify the text that is displayed as part of a menu item. Use the Accelerator page of the menu editor Property Inspector to create the actual accelerator. Adding accelerator resources to menus The items on the Accelerator page of the Menu editor Property Inspector create an association between a MENU resource and an ACCELERATOR resource. An ACCELERATOR resource is considered associated" with a MENU resource if they have the same resource name (either string or numeric value). An individual accelerator is associated with a menuitem if both have the same ID. /I Testing a menu The Menu editor gives you immediate testing capability. The test menu is updated as you make changes to your menu, so you can test changes whenever you want. To view the menu in Test Mode, select Menu I Test Menu. You can navigate the menu structure as you would while running your application. Testing for duplicate menu items The Menu editor also has a built-in debugging tool that you carl use to test for duplicate menu item IDs. Choose Menu I Check Duplicates to search for duplicate values. If the Menu editor finds duplicates, it displays a dialog box with the message "Duplicate command value found." Chapter 16, About menus 303 When you close this message box, the Menu editor selects the item with the duplicate value. Determine whether the menu ID is an identifier or a numeric value by looking at the ID input box on the General page of the Menu editor Property Inspector. • If the menu ID is a number, enter a new number that does not conflict with the other menu IDs. • If the menu ID is a conflicting identifier, change the identifier text so that it does not conflict, or choose Resource I Identifiers to display the Identifiers dialog box where you can change the identifier. Programming menus and accelerators with OWL To program menus and accelerators with OWL, use the TMenu class and the LoadAccelerators function. For example, this 'code shows how to associate a menu and accelerators with the main window: GetMainWindow()->AssignMenu(IDM_MENU1)i GETMAINWINDOW()->ATTR.ACCELTABLE = IDA_ACCELERATORSli IDM_MENUI and IDD_ACCELERATORSI are the identifiers for the menu and accelerator table, respectively. Programming menus and accelerators with the Windows API To program and menus and accelerators with the Windows API, use the LoadMenu and LoadAccelerators functions. For example, this code shows how to associate a menu and accelerators with the main window: HMENU hMenu i hMenu = LoadMenu(hlnst, MAKEINTRESOURCE(IDD_MENU1))i LoadAccelerators(hlnst, MAKEINTRESOURCE(IDD(ACCELERATORS1)))i IDM_MENUI and IDD_ACCELERATORSI are the identifiers for the menu and accelerator table, respectively. 304 c++ User's Guide Working with identifiers Windows requires that every resource and user defined resource type be associated with a unique name or a unique integer (called a resource ID). By default, Resource Workshop assigns a name to each new resource. The default name is not very descriptive, and referring to a resource by name alone decreases the efficiency of the application at run-time. To overcome these shortcomings, you can rename the resource and assign it an identifier (a C #define). Identifiers An identifier consists of two parts: a text literal (the identifier name) and a value (typically an integer). Identifiers must be unique within a resource type. Only the first 31 characters are significant; Resource Workshop ignores any characters past the 31st character. Assigning an integer value to an identifier speeds up calls to the resource at run time, but you will not be able to use the short integer value directly as a parameter. You must either typecast the integer into a long pointer to char or use a macro to do the typecasting for you. • If you write your program in C or C++, use the MAKEINTRESOURCE macro. • If you are using ObjectWindows, see the class TResld. If you are working with a .RES file, an executable file, or a DLL file, Resource Workshop decompiles all resource IDs in the files into integer values. You cannot add identifiers to this type of file, but you can save the file as an .RC file and assign identifiers to its resources. Chapter 17, Working with identifiers 305 Identifier files When you create a new project, the first thing you should do is specify a file in which to store your identifiers. Store identifiers in one or more resource header (.RH) files that use #defines to assign values to identifier names. Creating an identifier file To add an identifer after you create a new project, 1 Right-click and choose Add to Project. You see the Add to Project dialog box. 2 Click the down-arrow in List Files of Type. Choose: C/C++ header (*.h, *.rh) 3 Enter a name for the identifier file in the File Name box. 4 Click OK. Resource Workshop creates the identifier file. Adding identifiers You can add an identifier to your identifier file before you create the resource it will be associated with. To add an identifier, 1 Choose Resource I Identifiers to display the Identifiers dialog box. 2 Right-click and choose Insert. The New I Change Identifiers dialog box is displayed. 3 In the Name box, enter the identifier name. 4 "In the Value box, enter the identifier's value. 5 In the File box, enter the name of the file in which the identifier is to be stored. 6 Click the OK button. Note The new name now appears in the Name lis~ in the Identifers dialog box. The Usage columns says (unused). Editing identifiers To change an identifier name or value, 1 Choose Resource I Identifiers to display the Identifiers dialog box. 2 Double-click the name or value you want to change. The New I Change Identifiers dialog box is displayed. 3 Change the name in the Name box. 4 Change the value in the Value box. 5 Click OK. 306 c++ User's Guide The new identifier value will be written to the header file the next time you choose File I Save. Moving identifiers from one file to another To change the file an identifier is placed in, 1 Choose Resource I Identifiers to display the Identifiers dialog box. 2 Double-click the name or value of the identifier you want to change. The New /Change Identifiers dialog box is displayed. 3 Enter a new filename in the File box. 4 Click OK. Deleting identifiers If an identifier is not used in your project, you should delete it from the header file. There are three reasons you might have an unused identifier: • You assign an identifier to a resource and then delete the resource. • You add an identifier to the project and then never use it. • You rename a resource that already has an integer identifier value. To delete an identifier: 1 Choose Resource I Identifiers to display the Identifiers dialog box. 2 Select the identifier you want to delete. You can delete an identifier that is still in use. • If the selected identifier is not associated with a resource (either because the resource was deleted or the identifier was never used), the Used By box says (unused) . • If, however, the identifier is still associated with a resource, the Used By box automatically highlights the type and name of the associated resource. 3 Press the Delete key. • If the identifier is unused, it is deleted immediately. No warning dialog box is displayed. • If the identifier is still in use, Resource Workshop displays a warning dialog box that says udefine is used. Delete anyway?" To delete the identifier, click the Yes button. If you do not want to delete the identifier, click the No button. The next time you choose File I Save, Resource Workshop updates the identifier file, removing the deleted identifier. C hap t e r 1 7, W0 r kin 9 wit hid e n t i fie r s 307 Listing identifiers To list the identifiers in your project" 1 Choose Resource I Identifiers to display the Identifiers dialog box. 2 Choose the name of the file for which you want to view identifiers. 3 The name, value, and usage of all identifiers in that file are displayed. Managing identifiers Resource Workshop can automatically create and delete identifiers for you. To turn on automatic identifier management, choose Options I Environment I Resource Editors. Check the Generate Identifiers Automatically option (one of the Resource Editor SpeedSettings). Note If you are using AppExpert from the Borland C++ IDE, Generate Identifiers Automatically will be checked and unselectable; you will not be able to tum this option off because AppExpert relies on the automatic identifiers syntax. I With automatic identifiers on, every time you create a resource item that uses an identifier (menu items, for example), Resource Workshop creates a unique identifier for that item and places it in the header file for that resource (.RH or .H). Also, if you delete any items, the identifier is deleted. Resource Workshop uses an identifier prefix, which you can change. The list of default prefixes can be viewed by choosing Options I Environment I Resource Editors I Identifiers. This options page also allows you to change the default prefix. 308 C++ Use r 's G u ide Using the Text editor The text version of a resource is also called source code or script.You can edit the text version of any resource. To edit the text version of a resource, 1 Click the resource in the Resource Project window. 2 Choose Resource IEdit As Text. Resource Workshop opens the Text editor and displays the script for the resource. Saving your changes To save your changes to a script, 1 Close the Text editor window. 2 Choose Yes in response to the prompt "Resource has changed. Compile?" Resource Workshop compiles your resource script and saves the changes. If it encounters a syntax error, you are returned to the Text editor so you can correct the error. Compiling a text version of a resource After editing a text version of a resource, you must compile the resource in order to save it. To compile and save a resource script in the Text editor, right-click and choose Compile. If you do not compile the resource, Resource Workshop prompts you to compile it when you exit the Text editor. . Chapter 18, Using the Text editor 309 Creating resources with the Text editor Resource Workshop always edits some kinds of resources as scripts. These resources are referred to as scripted resources: Accelerator DLGINIT RCDATA User-Defined Resources StringTable VERSIONINFO Note DLGINIT resources are created whenever dialogs contain VBX controls. This resource type should never be modified. You can also define bitmapped and dialog template resources with scripts, but you will usually find it easier to use the visual editors in Resource Workshop, especially for creating those resources. You will probably edit bitmap or dialog template scripts only to make changes to existing resources. Writing resource scripts A resource script is a text file that consists of three kinds of items: • Resource definition statements • Resource compiler directives • Comments The majority of a resource script is made up of resource definition statements. Each resource in the resource script is defined by a definition statement, which has the following general syntax: keyword resource_id [options] BEGIN items END In this syntax: keyword resource_id options items is one of the resource keywords. is either a numeric constant or an identifier. is optional information specific to the type of resource being defined. is one or more items within the resource, such as menu items in a menu resource or strings in a string table. Comments A comment can be placed in the script surrounded by a C-style comment string (1* ... */). Do not place a comment within a resource definition block, as the resource compiler will strip it out. 310 C++ Use r 's Gu ide Here as an example of a valid coment: /* This is a valid comment */ keyword resource_id [options] BEGIN END Here is an invalid comment: keyword resource_id [options] /* Do not put comments here */ BEGIN /* And don't put them here */ END Note A comment is valid only if it was added before the resource project was opened by , Resource Workshop. Comments added to the text of a resource, edited with the Resource IEdit As Text command, will be stripped out by the resource compiler. C hap t e r 18, Us i n 9 the T ext e d ito r 311 312 C++ Use r' s G u ide Working with user-defined resources In addition to defining standard resource types, you can also define your own resource types. After you create a new resource type, you can add any number of user-defined resources of this type to your project. User-defined resources contain data that do not fit into one of the standard resource types. For example, if you want to create a character string resource that is longer than the STRINGTABLE limit of 255 characters, you can define your own resource type and store your character strings there. You can also include metafiles in your project as user-defined resources. A metafile is a type of bitmap (in source form, it is a collection of Graphics Device Interface (GDI) calls) that's not only easier to scale and more device-independent than the standard bitmap resource, but also often takes up less storage space than a bitmap resource. When you define a new resource, you can store data as part of the resource definition in a project file or as a separate file. You can also use the RCDATA resource type to add data to your application. Working with user-defined resources involves five basic tasks: • • • • • Create a resource type. Add a user-defined resource to your project. Edit it, if necessary. Test it. Save it. Creating a resource type Before you can add user-defined resource data to your project, you must first create a type for it. Here1s how: 1 Open an existing project or create a new one. 2 Choose Resource I New. You see the New Resource dialog box. Chapter 19, Working with user-defined resources 313 3 Choose . 4 Click the Options button. S In the Resource Type name box, enter a unique name for the resource type you are creating. For example, if you are creating a resource to contain a large block of text, you could name your new resource type TEXT. 6 If your project is an .RC file, you may want to create an identifier for the new resource type. 7 Enter a value for the identifier. This value is the ID that Windows and your program· will associate with this identifier type. If you use a resource ID, it must be greater than 255, because Windows reserves the values 1 through 255 for standard resources. 8 Click OK to create the new resource type. From now on, whenever you create a new resource, you see that resource type listed in the New Resource dialog box with all the standard resource types. To give the resource a name, click the Options button. You can also click OK to use the default name. Adding a user-defined resource After you have created a resource type, you can add a resource of that type to your project. To add a use-defined resource, 1 Open a resource project or create a new one. 2 Choose Resource I New. You see the New Resource dialog box. 3 In the Resource Type list, select your user-defined resource. 4 Click OK to place the resource in the current project file or click the Options button to add it to another resource project file. S Resource Workshop opens the Text editor with a blank definition for your userdefined resource. Using the RCDATA resource type You can use the predefined RCDATA resource type to add a data resource to your application. It works the same way as a user-defined resource type. The primary difference between the two is addressability: you might prefer to have many different types of user-defined resources rather than just one type, RCDATA. To add an RCDATA resource to your project, 1 Choose Resource I New. You see the New Resource dialog box. 2 Select RCDATA and click the Options button. You can also change the name in the source script. 3 Press OK. You see a blank RCDATA definition in the Text editor. 4 Add resource data. 314 C++ User's Guide Editing a user-defined resource When you edit a user-defined resource, you work with its resource script. To edit a user-defined resource, Open a resource project. You can either create a resource type or open an existing one. 2 Select the user-defined resource type to which you want to add a resource. 3 Open the Text editor by: • Double-clicking the name of the resource you want to edit. 1& Selecting the resource name and choosing Resource IEdit or Resource IEdit as Text. Once you have brought the resource script up in the script editor, you can add or change data. To add data to your resource, do one of the following: • Use the Text editor to enter data between the BEGIN and END statements. • Store the data in a separate file and add the file name to the end of the user-defined resource statement. Delete the BEGIN and END statements. After you make any changes, you must recompile the resource to save your changes. If you exit without recompiling, you lose all your changes. Embedding resource data in a project file You can add data to your resource by storing data in a separate file. The disadvantage to this approach is that if something happens to the file, the data is lost. Another option is to embed the external data into the project file script. Here's how: Right-click and choose Add To Project. 2 Choose User Resource Data in the File Type list. 3 Enter the file name in the File Name input box. (The file must use a non-standard file extension. ) The Custom Resource dialog box is displayed. 4 Double-click the resource type. The resource appears in the Resource Project window. If you select the new resource and choose Resource IEdit, you see that the resource data is in hexadecimal format. For that reason, you should keep the external data file available in case you want to edit the resource script later. Entering data in the resource script Use the Text editor to change data that is between the BEGIN and END statements. Do not use this editor to do much formatting, since Resource Workshop rearranges the text when it compiles or decompiles the resource. C hap t e r 19, W0 r kin 9 wit h use r -de fin e d res 0 u r c e s 315 Here are some guidelines: • The data can include any mix of numeric values and strings. • You can use hexadecimal, octal, or decimal notation to represent numeric values. Use either Ox (a zero followed by the letter x) or $ (a dollar sign) as the leading characters for hexadecimal notation. This notation supports only 16-bit values. If you want to use an odd number of hexadecimal values, use a hexstring. A hexstring is a string of hexadecimal values enclosed in single quotation marks. The compiler ignores any spaces you insert to make the hex codes more readable. • If you include text strings in your resource, enclose the strings in quotation marks, like this: "string". Strings are not automatically null-terminated. To terminate a string with a null character, type \ 0 (backslash zero) at the end of the string. Testing a user-defined resource You cannot test user-defined resources within Resource Workshop. You need to use Resource Workshop to compile the project file that contains the resource and bind it to your executable file. You can then run your program and test the resource. 316 c++ User's Guide Borland C++ tools and utilities Part III covers the additional tools and utilities provided with Borland C++. These tools include compilers, linkers, a resource compiler, a librarian, a project builder (called MAKE), and other utilities. Although most of these tools are documented in this Part, some tools and utilities are documented in the online Help. While programming, you can use either the IDE or the command-line tools. Although both sets of tools produce the same results, you might choose to use the command-line tools because you prefer to use your own programming editor (such as Brief). Here's This part is organized into the following chapters: • Chapter 20, UUsing MAKE," describes the Borland C++ make utilities MAKE.EXE and MAKEREXE. These are tools that help you manage projects by building only the files that have changed since the last build. • Chapter 21, UUsing resource tools," describes the Borland C++ resource tools that compile and link application resources. • Chapter 22, UUsing WinSight," explains how to use the WinSight utility to track Windows system messages in your application. • Chapter 23, UUsing WinSpector," explains how to use the WinSpector utility to track fatal system errors. Par till, B 0 r I and C++ too I 5 and uti lit i e s 317 Running the command-line tools The command-line compiler uses DPMI (DOS Protected Mode Interface) to run in protected mode on 386, i486, and Pentium machines with at least 640K conventional RAM and at least 4MB extended memory. Although the compilers run in protected mode, they generate applications that run in real mode. Protected-mode tools have the advantage that they can access more memory than real-mode tools. This helps to compile large projects at faster speeds, without the cost of extensive disk-swapping. Memory and MAKESWAP.EXE If you get Out of Memory errors from DOS when running the 32-bit command-line tools, create a swap file with the MAKESWAP utility. You describe the size of the file to create in kilobytes. MAKESWAP supports the following syntax: MAKESWAP 12M This command creates a 12MB swap file called EDPMI.SWP in the current directory, which the command-line tools use when they need additional memory. To set up a swap file, use the DPMIMEM environment variable at the DOS prompt, or add this line to your AUTOEXEC.BAT file: set DPMI32=SWAPFILE EDPMI.SWP Note MAKESWAP applies to DOS only, not to DOS text boxes opened under Windows. See the online file INSTALL.TXT for information on running these tools from DOS boxes. The run-time manager and tools The Borland C++ protected-mode applications (such as BCC and BCC32) use the runtime manager tools, RTM.EXE and 32RTM.EXE. The tools that use the run-time ' manager first load the run-time manager, do their work, and then unload the run-time manager. If you're accessing 32-bit command-line tools that use the run-time manager many times over a short period (perhaps from a makefile), you could speed up the process by loading the run-time manager once, then calling the tools. To load the runtime manager, type 32RTM at the command line. To unload the run-time manager, type 32RTM -u. By default, the run-time manager consumes all available memory when it loads. It then allocates memory to its clients when they request it through the memory manager API routines. When running in a DOS box under Windows 3.x, the amount of memory that RTM reserves is also limited by the XMS Memory KB I;..imit setting in the corresponding PIF file. Your PIF file setting for the DOS box should set XMS Memory KB Limit to at least 1024. TlUs value sets the limit on the amount of memory that RTM takes for the 16-bit DOS extended-memory application. 318 c++ User's Guide Using MAKE MAKE.EXE is a command-line project-manager utility that helps you quickly compile only those files in a project that have changed since the last compilation. (MAKER is a real-mode version of MAKE.) If you work in the IDE, you should use the IDE's Project Manager (see Chapter 2, "Managing projects"). This chapter covers the following topics: • MAKE basics • Using explicit and implicit rules • Using MAKE directives • Makefile contents • Using MAKE macros MAKE basics MAKE uses rules from a text file (MAKEFILE or MAKEFILE.MAK by default) to determine which files to build and how to build them. For example, you can get MAKE to compile an .EXE file if the date/time stamps for the .CPP files that contain the code for the .EXE are more recent than the .EXE itself. MAKE is very useful when you build a program from more than one file because MAKE will recompile only the files that you modified since the last compile. Two types of rules (explicit and implicit) tell MAKE what files depend on each other. MAKE then compares the date/time stamp of the files in a rule and determines if it should execute a command (the commands usually tell MAKE which tiles to recompile or link, but the commands can be nearly any operating system command). The general syntax for MAKE is MAKE [options ... ] [targets[s]] where options are MAKE options that control how MAKE works, and targets are the names of the files in a makefile that you want MAKE to build. Options are separated from MAKE by a single space. Options and targets are also separated by spaces. Targets may contain wildcard characters such as * and ? Chapter 20, Using MAKE 319 To get command-line help for MAKE, type MAKE -? or MAKE -h. If you type MAKE at the command prompt, MAKE performs the following default tasks: MAKE looks in the current directory for a file called BUILTINS.MAK (this file contains rules MAKE always follows unless you use the -r option). If it can't find the file in the current directory, it looks in the directory where MAKE.EXE is stored. After loading BUlLTINS.MAK, MAKE looks for a file called MAKEFILE or MAKEFILE.MAK. If MAKE can't find any of these files, it gives you an error message. 1 When MAKE finds a makefile, it tries to build only the first target file in the makefile (although the first target can force other targets to be built). MAKE checks the time and date of the dependent files for the first target. If the dependent files are more recent than the target file, MAKE executes the target commands, which update the target. See the section called ausing makefiles" for more information on instructions in makefiles. 2 If a dependent file for the first target appears as a target elsewhere in the makefile, MAKE checks its dependencies and builds it before building the first target. This chain reaction is called linked dependency. ' 3 If the MAKE build process fails, MAKE deletes the target file it was building. To get MAKE to keep a target when a build fails, see the .precious directive on page 335. You can stop MAKE by using Ctrl+Break or Ctr/+C. To place MAKE instructions in a file other than MAKEFILE, see the section titled "MAKE options." BUILTINS.MAK BUILTINS.MAK contains standard rules and macros that MAKE uses before it uses a makefile (you can use the -r option to tell MAKE to ignore BUILTINS.MAK). Use BUILTINS.MAK for instructions or macros you want executed each time you use MAKE. Here's the default text of BUILTINS.MAK: # # Borland C++ - (C) Copyright 1993 by Borland International # # default is to target 16BIT # pass -DWIN32 to make to target 32BIT ! if ! $d (WIN32) cc = bee RC = bree AS = tasm !else CC = bee32 RC = bree32 AS = tasm32 !endif .asm.obj: 320 C++ Use r 's G u ide $(AS) .c.exe: $(CC) .c.obj: $(CC) .cpp.exe: $(CC) .cpp.obj: $(CC) .rc.res: $(RC) $ (AFLAGS) $&.asm $ (CFLAGS) $&.c $ (CFLAGS) Ic $&.c $ (CFLAGS) $&.cpp $ (CPPFLAGS) Ic $&.cpp $ (RFLAGS) Ir $& . SUFFIXES: .exe .obj .asm .c .res .rc !if !$d(BCEXAMPLEDIR) BCEXAMPLEDIR = $(MAKEDIR)\ .. \EXAMPLES !endif Using TOUCH.EXE Sometimes you'll want to force a target file to be recompiled or rebuilt even though you haven't changed it. One way to do this is to use the TOUCH utility. TOUCH changes the date and time of one or more files to the current date and time, making it "newer" than the files that depend on it. You can force MAKE to rebuild a target file by touching one of the files that target depends on. To touch a file (or files), type the following at the command prompt: touch filename [filename ... J TOUCH updates the file's creation date and time. It accepts file names that contain the wildcard characters * and ? Note Before you use TOUCH, make sure your system's internal clock is set correctly. If it isn't, TOUCH and MAKE won't work properly. MAKE options Command-line options control MAKE behavior. Options are case-sensitive. Type options with either a preceding - or /. For example, to use a file called PROJECTA.MAK as the makefile, type MAKE - fPROJECTA. MAK (a space after -£ is optional). Many of the command-line options have equivalent directives that are used in the makefile (see page 331 for more inforr~l.ation on directives). Table 20.1 -a -B MAKE options Checks dependencies of include files and nested include files associated with .OBJ files and updates the .OBJ if the .h file changed. See also -c. Builds all targets regardless of file dates. C hap t e r 2 0, U sin 9 MA K E 321 Table 20.1 MAKE options (continued) -c Caches autodependency information, which can improve MAKE's speed. Use with -a; don't use if MAKE changes include files (such as using TOUCH from a makefile or creating header or include files during the MAKE process). Defines macro as a single character, causing an expression !ifdef macro written in the makefile to return true. -Omacro [-O]macro=[string] Defines macro as string. If string contains any spaces or tabs, enclose string in quotation marks. The -0 is optional. -ddirectory Used with -8 to specify the drive and directory MAKER uses when it swaps out of ' memory. MAKE ignores this option. -e Ignores a macro if its name is the same as an environment variable (MAKE uses the environment variable instead of the macro). Uses filename or filename.MAK instead of MAKEFILE (space after -f is optional). -ffilename -hor-? Displays MAKE options and shows defaults with a trailing plus sign. Searches for include files in the current directory first, then in directory. Ignores the exit status of all programs run from MAKE and continues the build process. -Idirectory -i -K Keeps temporary files that MAKE creates (MAKE usually deletes them). See also KEEP on page 323. Displays the date and time stamp of each file as MAKE processes it. -m -N Executes MAKE like Microsoft's NMAKE (see the section following this table for more information). Prints the commands but doesn't actually perform them, which is helpful for debugging a makefile. Displays all macro definitions and implicit rules before executing the makefile. Returns aif the target is up-to-date and nOI\Zero if it is not (for use with batch files). Ignores any rules defined in BUILTINS.MAK. -n -p -q -r -8 Swaps MAKER out of memory while commands are executed, reducing memory overhead and allowing compilation of large modules. MAKE ignores this option. Suppresses onscreen command display. Undefines previous definitions of macro. Writes the current specified non-string options to MAKE.EXE making them defaults. -s -Umacro -w Setting options on as defaults The -W option lets you set some MAKE options on as defaults so that each time you use MAKE, those options are used. To set MAKE options, type make -option [-] [-option] [-] ...-w For example, you could type MAKE -m -w to always view file dates and times. Type to tum off the default option. When MAKE asks you to write changes to MAKE.EXE, type Y. MAKE -m- -W / 322 C++ Use r '5 G U ide Caution! The -W option doesn't work when the DOS SHARE program is running. The message Fatal: unable to open file MAKE. EXE is displayed. The -W option doesn't work with the following MAKE options: -Dmacro -ddirectory -ffilename -Idirectory -Dmacro=string -Usymbol -? or-h Compatibility with Microsoft's NMAKE Use the -N option if you want to use makefiles that were originally created for Microsoft's NMAKE. The following changes occur when you use -N: • MAKE interprets the « operator like the && operator: temporary files are used as response files, then deleted. To keep a file, either use the -K command-line option or use KEEP in the makefile. MAKE usually deletes temporary files it creates. «FileName. Ext text ? «KEEP If you don't want to keep a temporary file, type NOKEEP or type only the temporary (optional) file name. If you don't type a file name, MAKE creates a name for you. If you use NOKEEP with a temporary file, then use the -K option with MAKE, MAKE deletes the temporary file. ' • The $d macro is treated differently. Use !ifdef or !ifndef instead. • Macros that return paths won't return the last \. For example, if $ ( Take the input for use by command from file rather than from standard input. Send the output from command to file. » « Create a temporary, inline file and use its contents as standard input to command. && Create a temporary file and insert its name in the makefile. delimiter Any character other than # and used with « and && as a starting and ending delimiter for a temporary file. Any characters on the same line and immediately following the starting delimiter are ignored. The closing delimiter must be written on a line by itself. Append the output from command to file. Debugging with temporary files Temporary files can help you debug a command set by placing the actual commands MAKE executes into the temporary file. Temporary file names start at MAKEOOOO.@@@, where the 0000 increments for each temporary file you keep. You must place delimiters after && and at the end of what you want sent to the temporary file (! is a good delimiter). The following example shows && instructing MAKE to create a file of the input to TLINK. prog.exe: A.obj B.obj TLINK Ie &&! cOs.obj $** prog.exe prog.map maths.lib cs.lib The response file created by && contains these instructions: cOs.obj a.obj b.obj prog.exe prog.map maths.lib cs.lib Using MAKE macros A MAKE macro is a variable that gets expanded into a string whenever the macro is called in a makefile. For example, to d,efine a macro called LIBNAME that represents the 328 C++ Use r 's G u ide string "mylib.lib," type LIBNAME = mylib.lib. When MAKE encounters the macro $ (LIBNAME), it uses the stringmylib .lib. Macros let you create template makefiles that you can change to suit different projects. If MAKE finds an undefined macro in a makefile, it looks for an operating-~ystem environment variable of that name (usually defined with SET) and uses its definition as the expansion text. For example, if you wrote $ (PATH) in a makefile and never defined PATH, MAKE would use the text you defined for PATH in your AUTOEXEC.BAT. (See your operating system manuals for information on defining environment variables.) Defining macros The general syntax for defining a macro in a makefile is MacroName expansion_text. • MacroName is case-sensitive. MACR01 is different from Macrol. • MacroName is limited to 512 characters. • expansion_text is limited to 4096 characters. Expansion characters may be alphanumeric, punctuation, or whitespace. Each macro must be on a separate line in a makefile. Macros are usually put at the top of the makefile. If MAKE finds more than one definition for a macroName, the new definition replaces the old one. Macros can also be defined using the command-line option -D (see page 322). More than one macro can be defined by separating them with spaces. The following examples show macros defined at the command line: make -Dsoureedir=e:projeeta make eommand="bee -e" make eommand=bee option=-e The following differences in syntax exist between macros entered on the command line and macros written in a makefile. Table 20.4 Command line vs. makefile macros Spaces allowed before and after = Yes Space allowed before macroName No No Yes Using a macro To use a macro in a makefile, type $ (MacroName) where MacroName is the name of a defined macro. You can use braces {} and parentheses 0 to enclose the MacroName. MAKE expands macros at various times depending on where they appear in the makefile: • Nested macros are expanded when the outer macro is invoked. • Macros in rules and directives are expanded when MAKE first looks at the makefile. • Macros in commands are expanded when the command is executed. C hap t e r 2 0, U sin 9 MA K E 329 String substitutions in macros MAKE lets you temporarily substitute characters in a previously defined macro. For example, if you defined a macro called SOURCE as SOURCE = fl.cpp f2. cpp f3. cpp, you could substitute the characters .obj for the characters .cpp by using $ (SOURCE: . cpp= . obj ) . The substitution doesn't redefine the macro. Rules for macro substitution: • Syntax: $ (MacroName:original_text=new_text). • No whitespace before or after the colon. • Characters in originaCtext must exactly match the characters in the macro definition; this text is case-sensitive. MAKE now lets you use macros within substitution macros. For example, MYEXT=.C SOURCE=fl.cpp f2.cpp f3.cpp $(SOURCE:.cpp=$(MYEXT)) #Changes fl.cpp to fl.C, etc. Default MAKE macros MAKE contains several default macros you can use in your makefiles. Table 20.5 lists the macro definition and what it expands to in explicit and implicit rules. Table 20.5 $* $< $: $. $& $@ $** $? Table 20.6 Default macros path \ dependent file path \ dependent file+ext path for dependents dependentfile+ext dependent file path\targetfile+ext path \ dependent file+ext path \ dependent file+ext target file path \ target file+ext all dependents file+ext old dependents C: \PROJECTA \MYTARGET C:\PROJECTA \MYTARGET.oBJ C:\PROJECTA MYSOURCE.C MYSOURCE C: \PROJECTA \MYSOURCE.C FILEl.CPP FILE2.CPP FILE3.CPP FILE1.CPP Other default macros __MSooS__ __MAKE__ MAKE MAKEFLAGS MAKEDIR 330 path \ target file path\targetfile+ext path for target target file + ext c++ User's Guide 1 Ox0370 make options directory If running under DOS. MAKE's hex version number. MAKE's executable file name. The options typed at the command line. Directory where MAKE.EXE is located. Modifying default macros When the default macros listed in Table 20.5 don't give you the exact string you want, macro modifiers let you extract parts of the string to suit your purpose. To modify a default macro, use this syntax: $(MacroName [modifier]) Table 20.7 lists macro modifiers and provides examples of their use. Table 20.7 D F B R File-name macro modifiers Drive and directory Base and extension Base only Drive, directory, and base $«D) $«F) $«B) $«R) C:\PROJECTA \ MYSOURCE.C MYSOURCE C: \PROJECTA \MYSOURCE Using MAKE directives MAKE directives resemble directives in languages such as C and Pascal, and perform various control functions, such as displaying commands onscreen before executing them. MAKE directives begin either with an exclamation point or a period. Table 20.8 lists MAKE directives and their corresponding command-line options (directives override command-line options). Each directive is described in more detail following the table. Table 20.8 MAKE directives .autodepend .cacheautodepend !elif !else !endif !error !if !ifdef -a -c !ifndef .ignore !include !message .noautodepend .nocacheautodepend -i -a-c- Turns on autodependency checking . Turns on autodependency caching. Acts like a Celse if. Acts like a C else. Ends an !if, !ifdef, or !ifndef statement. Stops MAKE and prints an error message. Begins a conditional statement. Acts like a C #ifdef, testing whether a given macro has been defined. Acts like a C #ifndef, testing whether a given macro is undefined. MAKE ignores the return value of a command. Acts like a C #include, specifying a file to include in the makefile. Prints a message to stdout while MAKE runs the makefile. Turns off autodependency checking. Turns off autodependency caching. C hap t e r 20, Us i n 9 M A K E 331 Table 20.8 MAKE directives (continued) .noIgnore .nosilent .noswap -i-s- -s- .path.ext. ;precious .silent .suffixes -s .swap -s !undef Turns off .Ignore. Displays commands before MAKE executes them. Tells MAKE not to swap itself out of memory before executing a command. Tells MAKE to search for files with the extension .ext in path directories. Saves the target or targets even if the build fails. MAKE executes commands without printing them first. Determines the implicit rule for ambiguous dependencies. Tells MAKE to swap itself out of memory before executing a command. Clears the definition of a macro. After this, the macro is undefined . .autodepend Autodependencies occur in .OB} files that have corresponding .CPP, .C, or .ASM files. With .autodepend on, MAKE compares the dates and times of all the files used to build the .OB}. If the dates and times of the files used to build the .OB} are different from the date/time stamp of the .OB} file, the .OB} file is recompiled. You can use .autodepend or -a in place of linked dependencies (see page 320 for information on linked dependencies ). !error This is the syntax of the !error directive: !error message MAKE stops processing and prints the following string when it encounters this directive: Fatal makefile exit code: Error directive: message Embed !error in conditional statements to abort processing and print an error message, as shown in the following example: ! if ! $d(MYMACRO) #if MYMACRO isn't defined !error MYMACRO isn't defined !endif If MYMACRO in the example isn't defined, MAKE prints the following message: Fatal makefile 4: Error directive: MYMACRO isn't defined Summing up error-checking controls Four different controls tum off error checking: • The .ignore directive turns off error checking for a selected portion of the makefile. 332 C++ Use r 's G u ide • The -i command-line option turns off error checking for the entire makefile. • The -num command operator, which is entered as part of a rule, turns off error checking for the related command if the exit code exceeds the specified number. • The - command operator turns off error checking for the related command regardless of the exit code. !if and other conditional directives The !if directive works like C if statements. As shown here, the syntax of !if and the other conditional directives resembles compiler conditionals: !if condition !if condition !if condition !ifdef macro !endif !else ! elif condition !endif !endif !endif The following expressions are equivalent: !ifdef macro and !if $d(macro) i fndef macro and ! i f ! $d (macro) These rules apply to conditional directives: • • • • • One !else directive is allowed between !if, !ifdef, or !ifndef and !endif directives. Multiple !elif directives are allowed between !if, !ifdef, or !ifndef, !else and !endif. You can't split rules across condItional directives. You can nest conditional directives. !if, !ifdef, and !ifndef must have matching !endif directives within the same file. The following information can be included between !if and !endif directives: • Macro definition • Explicit rule • Implicit rule • !include directive • !error directive • !undef directive Condition in if statements represents a conditional expression consisting of decimal, octal, or hexadecimal constants and the operators shown in Table 20.9. Table 20.9 + * / % && Conditional operators Negation Bit complement Addition Subtraction Multiplication Division Remainder Logical AND ?: » « & /\ >= Conditional expression Logical NOT Right shift Left shift Bitwise AND Bitwise OR BitwiseXOR Greater than or equal* Chapter 20, Using MAKE 333 Table 20.9 Conditional operators (continued) II Logical OR Greater than > Less than < *Operator also works with string expressions. <= != Less than or equal* Equality* Inequality* MAKE evaluates a conditional expression as either a simple 32-bit signed integer or as a character string. !include This directive is like the #include preprocessor directive for the C or c++ language-it lets you include the text of another file in the makefile: !include filename You can enclose filename in quotation marks ("") or angle brackets (<» and nest directives to unlimited depth, but writing duplicate !include directives in a makefile isn't permitted-you'll get the error message cycle in the include file. Rules, commands, or directives must be complete within a single source file; you can't start a command in an !include file, then finish it in the makefile. MAKE searches for !include files in the current directory unless you've specified another directory with the -I option. !message The !message directive lets you send messages to the screen from a makefile. You can use these messages to help debug a makefile that isn't working the way you'd like it to. For example, if you're having trouble with a macro definition, you could put this line in your makefile: !message The macro is defined here as: $ (MacroName) When MAKE interprets this line, it will print onscreen The macro is defined here as: . CPP, if the macro expands to .CPP at that line. Using a series of !message directives, you can debug your makefiles . .path.ext The .path.ext directive tells MAKE where to look for files with a certain extension. The following example tells MAKE to look for files with the .c extension in C:SOURCE or C:CFILES and to look for files with the .obj extension in C:OBJS . . path.c = C:CSOURCE;C:CFILES .path.obj = C:OBJS 334 c++ User's Guide .precious If a MAKE build fails, MAKE deletes the target file. The .precious directive prevents the file deletion, which is desired for certain kinds of targets such as libraries. When a build fails to add a module to a library, you don't w~t the library to b~ deleted. The syntax for .precious is .precious: target [target] ... [target] .suffixes The .suffixes directive tells MAKE the order (by file extensions) for building implicit rules. The syntax of the .suffixes directive is .suffixes: .ext [.ext] [.ext] ... [.ext] .ext represents the dependent file extension in implicit rules. For example, you could include the line . suf fixes: . asm . c . cpp to tell MAKE to interpret implicit rules beginning with the ones dependent on .ASM files, then .C files, then .CPP files, regardless of what order they appear in the makefile. The following example shows a makefile containing a .suffixes directive that tells MAKE to look for a source file (MYPROG.EXE) first with an .ASM extension, next with a .C extension, and finally with a .CPP extension. If MAKE finds MYPROG.ASM, it builds MYPROG.OBJ from the assembler file by calling TASM. MAKE then calls TLINK; otherwise, MAKE searches for MYPROG.C to build the .OBJ file, and so on. . suffixes: .asm .c .cpp myprog.exe: myprog.obj tlink myprog.obj .cpp.obj: bcc -P $< .asm.obj: tasm /mx $< .c.obj: bcc -P- $< !undef The syntax of the !undef directive is !undef MacroName !undef (undefine) clears the given macro, causing an !ifdef MacroName test to faiL Chapter 20, Using MAKE 335 Using macros in directives The macro $d is used with the !if conditional directive to perform some processing if a specific macro is defined. The $d is followed by a macro name, enclosed in parentheses or braces, as shown in the following example. !if $d(DEBUG) bee -v fl.epp f2.epp !else bee -v- fl.epp f2.epp !endif #If DEBUG is defined, #eompile with debug informationi #otherwise (else) #don't include debug information. Null macros An undefined macro causes an !ifdef MacroName test to return false; a null macro returns true. A null macro is a macro defined with either spaces to the right of the equal sign (=) or no characters to the right of the equal sign. For example, the following line defines a null macro in a makefile: NULLMACRO = Either of the following lines can define a null macro on the MAKE command line: NULLMACRO="" -DNULLMACRO 336 c++ User's Guide Using command~line resource tools There are several Borland command-line resource tools: • Resource compiler 'BRCC32.EXE is the Borland resource compiler. It compiles resource script files (.RC files) and produces the binary .RES file. • Resource linkers RLINK.EXE and RLINK32.DLL are the Borland resource linkers that bind resources, in .RES file form, to an .EXE file, and mark the resulting .EXE file as a Windows executable. RLINK32.DLL is accessed through TLINK32.EXE. RLINK.EXE is for 16-bit resources only. • Resource shells BRC32.EXE is a shell through which BRCC32 and RLINK or RLINK32 (through TLINK32) can be started in a single step. Note BRC and BRCC are no longer compliers.These files are shells that call BRC32 or BRCC32 with 16-bit options. All resources are compiled with BRCC32. The command line options are supported for downward compatability. Resource compiler (BRCC32) BRCC32 is the c'ommand-line version of the Resource Workshop resource compiler. It accepts a resource script file (.RC) as input and produces a resource object file (.RES) as output. BRCC32 is used for both 16-bit and 32-bit resources. Syntax BRCC32 [options] .RC C hap t e r 2 1, U sin 9 com man d - lin ere sou r c e too I s 337 Command-line options BRCC32 accepts these options: @responsefile Takes instructions from the specified command file. -d [= ] Defines a preprocessor symbol. - fo Renames the output .RES file. (By default, BRCC32 creates the output .RES file with the same name as the input .RC file.) -i Adds one or more directories (separated by semicolons) to the include search path. -r This switch is ignored. It is included for compatibility with other resource compilers. -v Prints progress messages (verbose). Deletes the current include path. -x or -h -16 Displays help. Builds a 16-bit resource. -32 Builds a 32-bit resource. -? BRCC32 predefines common resource-related Windows constants such as WS_VISIBLE and BS_PUSHBUTTON. Also, two special compiler-related symbols are defined: RC_INVOKED and WORKSHOP_INVOKED. These symbols can be used in the source text in conjunction with conditional preprocessor statements to control compilation. For example, the following construct can greatly speed up compilation: #ifndef WORKSHOP_INVOKED #include "windows.h" #endif Downward compatability The following syntax and options are supported for downward compatabliity. Syntax BRCC [options] .RC Command-line options BRCC accept these options: 338 -31 Builds Windows 3.1-compatible .RES files. -w32 Builds Win32-compatible .RES files. c++ User's Guide Resource compiler examples The following example adds two directories to the include path and produces a .RES file with the same name as the input .RC file. brcc32 -i ; .RC This example produces an output .RES file with a name different from the input .RC file name: brcc32 -fo .RES .RC This example builds a 16-bit .RES file: brcc32 -16 -fo .RES .RC Resource linkers (RLINK and RLINK32) RLINK (and RLINK32) co~bines a .RES file with an .EXE file to produce a new Windows executable. RLINK accepts as input one or more object files (.RES) and a single Windows executable file. RLINK links the resources by fixing up string tables and message tables and then binding these linked resources to the executable. RLINK32 is called by TLINK32, and is used for 32-bit resources. Syntax rlink [options] .RES .EXE Command-line options RLINK accepts these options: @ Takes instructions from the specified command file. -d Removes resources from the .EXE file (default if no .RES file is specified). - fe - f i -k Renames the output .EXE file. Specifies additional input files. Does not reorder segments for fastload. (This option only applies to 16-bit resources.) -v Prints progress messages (verbose listing). -vx Lists resources but does not bind to EXE file. -7 or -h Displays help. Makes the .EXE .file with Windows version provided (v3.1 is the default). Version options are listed in the following table. -vd.d C hap t e r 2 1, U sin 9 com man d - lin ere sou r c e too I s 339 3.1 16 Gives white background with a non 3-D look for Windows 3.1x, Windows 32s, or WinNT3.1. 4.0 16 Gives gray 3-D look for Windows 95 and WinNT 3.51. 3.1 32 Gives white background with a non 3-D look for Windows 32s or WinNT 3.1. 4.0 32 Gives gray 3-D look for Windows 95 and WinNT 3.51. Resource linker examples The following example binds the resources in the .RES file into the .EXE file: rlink .RES .EXE This example links the resources in the two .RES files and binds them to the .EXE file: rlink -fi .RES .RES .EXE This example combines the program code in the input .EXE file with the resources in the input .RES file and produces an output .EXE file with a new name: rlink -fe .EXE .RES .EXE This example takes input from an .RLK command file. It then links the resources in three .RES files and binds them to the .EXE file: rlink @ .RLK The command file «filename>.RLK) contains: -fi .RES -fi .RES .RES .EXE Resource shell (BRC32) The Borland resource compiler (BRC32) is a resource compiler shelL It invokes BRCC32 and RLINK or RLINK32, depending on the command-line syntax. Syntax brc32 [options] .RC [ .EXE] 340 c++ User's Guide Command-line options BRC32 accepts these options: -d =string Defines a symbol you can test with the #IFDEF preprocessor directive. - fo Renames the .RES file. - fe Renames the .EXE file. -i Adds one or more directories (separated by semicolons) to the include search path. -r Creates a .RES file only. The compiled .RES file is not added to the .EXE. -v Prints progress messages (verbose listing). -x Directs the compiler to ignore the INCLUDE environment variable when it searches for include or resource files. -16 Builds 16-bit .RES files. -32 Builds 32-bit .RES files. -vd.d Makes the .EXE file with Windows version provided (v3.1 is the default for 16-bit resources; -v4.0 is the default for 32-bit resources). Version options are listed in the following table. 3.1 16 Gives white background with a non 3-D look for Windows 3.1x, Windows 32s, or WinNT 3.1. 4.0 16 Gives gray 3-D look for Windows 95 and WinNT 3.51. 3.1 32 Gives white background with a non 3-D look for Windows 32s or WinNT3.1. 4.0 32 Gives gray 3-D look for Windows 95 and WinNT 3.51. The following switches are invalid when the -r switch is specified: -k Disables the contiguous preload of segments and resources in the .EXE file. Segments are kept in the order in which they appear in the DEF file. (This option only applies to 16-bit resources.) -t Creates an application that runs only in protected mode (Windows Standard or 386 Enhanced mode). C hap t e r 2 1, Usin 9 com man d - lin ere sou r c e too I S 341 Downward compatability The following sytax and options are supported for downward compatability. Syntax brc [switches] .RC [ .EXE] Command-line options BRC accept these options: -31 Builds Windows 3.1-compatible .RES files. -w32 Builds Win32-compatible .RES files. Resource shell examples The following statement compiles the .RC file, creates a .RES file, and adds the .RES file to the executable file: brc32 .RC [ .EXE] BRC32 automatically seeks an .EXE file with the same name as the .RC file. You need to specify the .EXE file only if its name is different from that of the .RC file. The following statement creates a .RES file, but not an .EXE file. If you name an .EXE file in the command line, BRC ignores it: brc32 -r .RC The following statement adds an existing .RES file to an executable file. The .EXE file name is required only if it differs from the .RES file name: brc32 .RES [ .EXE] This example uses BRC32 to build a 16-bit Windows 3.1 compatible .RES file: brc32 -16 -v3.1 -fo .RES .RC 342 c++ User's Guide WinSight WinSight is a debugging tool that gives you information about windows, window classes, and window messages. You can use it to study a Windows application, to see how windows and window classes are created and used, and to see what messages the windows receive. You can configure WinSight to trace and display messages by • • • • Window Message type Window class A combination of these WinSight is a passive observer: it intercepts and displays information about messages, but it doesn't prevent messages from getting to applications. To start WinSight, double-click the WinSight icon located in the Borland C++ program group. The WinSight window appears in its default configuration; it displays the Window Tree view that lists all the windows currently active on the desktop. WinSight saves your configuration, so if you open all three views and exit WinSight, the next time you start it, all three views will display. WinSight has three views: Class List, Window Tree, and Message Trace. You can display these views from left to right or top to bottom by choosing View ISplit Horizontal or View ISplit Vertical. You can control the messages traced by WinSight (see page 347) and you can control when messages start and stop tracing as described in the following sections. Starting and stopping screen updates To turn on tracing, choose Start! from the menu (Start! then becomes Stop! on the menu). Normally, all three views are kept current as classes are registered, windows are created and destroyed, and messages are received. However, you can use Messages ITrace Off Chapter 22, WinSight 343 · to suspend tracing of messages only (Class List and Window Tree will continue to update). Use Stop! and Start! to • Study a particular situation. • Control (minimize) the machine time WinSight uses when it updates itself constantly. Turning off message tracing To tum off tracing of message types, choose Messages ITrace Off. The Message Trace view remains visible, and tracing resumes when you choose Messages ISelected Classes, Selected Windows, or All Windows (provided tracing is on). The following sections describe how to use the three views to get the information you need to debug an ~pplication. Choose Spy IExit to leave WinSight. Choosing a view WinSight has three views that can appear within its main window: Class List, Window Tree, and Message Trace. You can choose to look at any or all of the views. WinSight automatically tiles the views within the main window. You can hide or display views at any time, using the View menu. Information and selections are not lost when a view is hidden. • The Class List view shows all the currently registered window classes. • The Window Tree view displays the hierarchy of all the windows on the desktop. Window Tree displays by default when you start WinSight. • The Message Trace view displays information about messages received by selected windows or window classes. To get more detail about an item in Window Tree or Class List, • Select a window or a class, then choose Spy IOpen Detail. • Double-click the window or class. The Detail window displays the class name, executable module, and other information about the class or window. Class List view A class is the name with which the window class was registered with Windows. Sometimes, instead of choosing specific windows to trace, you might want to look at messages for entire classes of windows. WinSight lets you do this with the Class List view. 344 c++ User's Guide Using the Class List view The Class List view shows all the currently registered window classes. To get details about a class, double-click it or select it and press Enter. The diamonds next to the classes tum black momentarily whenever the window receives any messages. This gives you an overview of which windows are currently receiving messages. If a hidden child window receives a message, the diamond for the parent changes color. Use the following format: Class (Module) Function Styles Class is the name of the class. Some predefined Windows classes have numeric names. For example, the Popup menu class uses the number 32768 as its name. These predefined classes are shown with both the number and a name, such as #32768:PopupMenu. The actual class name is only the number (using the MAKEINTRESOURCE format, which is also used for resource IDs). Module is the name of the executable module (.EXE or .DLL) that registered the class. Function is the address of the class window function. Styles is a list of the cs_ styles for the class. The names are the same as the cs_ definitions in WinTypes, except the cs_ is removed and the name is in m.ixed case (uppercase and lowercase). Spying on classes To trace messages for one or more classes, select the classes in Class List (Shift+Click or Ctr/+Click), then choose Messages I Selected Classes. If the Message Trace view is hidden, it becomes visible when you choose Messages I Selected Classes. Note that tracing messages to a class lets you see all messages to windows of that class, including creation messages, which would otherwise not be accessible. To change which classes are traced, change the selection in the Class List. Choose Messages I Trace Off to tum off all message tracing to the Message view. Window Tree view The Window Tree view displays a hierarchical outline of all existing windows on the desktop. This display lets you • • • • Determine what windows are present on the desktop. View the status of windows, including hidden windows. See which windows are receiving messages. Select windows for message tracing. The lines on the left of the Window Tree view show the tree structure. Each window is connected to its parent, siblings, and children with these lines. When a window receives a message, the diamond next to it (or its parent window if the tree is collapsed) turns black. Chapter 22, WinSight 345 The diamond next to each window shows whether the window has any children. If the diamond is blank, the window has no children. If the diamond contains a +, the window has children that are not displayed. To show the next level of children, click the diamond next to the window. To show all the levels of child windows (children of children, and so on), right-click the diamond. If the diamond contains a -, the children are displayed. To hide all of a window's child windows, click the diamond next to the window. . The format of the window details is as follows: Handle {Class} Module (Position) "Title" Handle is the window handle as returned by Create Window. Class is the window class name, as described in the Class List view. Module is the name of the executable module (.EXE or .DLL) that created the window. Module is the name of the module owning the data segment passed as the hlnstance parameter to Create Window. Position is "hidden" if the window is hidden. If the window is visible, Position is indicated by using screen coordinates (for parent windows) or coordinates in the parent's client area (for child windows). Position uses the following format: xBegin,yBegin - xEnd,yEnd Title is the window title or text, as returned by GetWindowText or a wm_GETTEXT message. If the title is the null string, the quotation marks are omitted. Finding a window WinSight has a special mode for locating windows. It can work in two ways: either identifying the line in the Window Tree that corresponds to a window you point at with the mouse, or highlighting a window you select in the Window Tree. Important All other applications are suspended while you're in Find Window mode. Enter Find Window mode by choosing Spy IFind Window. In this mode, whenever the mouse passes into the boundaries of a window, a thick border appears around that window, and the window is selected in the Window Tree view. Alternatively, once in Find Window mode, you can select windows in the Window Tree with the mouse or cursor keys, and WinSight will put a thick border around the selected window or windows. If you press Enter, you will see the Window Detail window for the selected window. Leaving Find Window mode Once you have located the window you want, you can leave Find Window mode by clicking the mouse button or by pressing the Esc key. This removes the border from the screen, leaving the current window's description selected in the Window Tree view. 346 c++ User's Guide Spying on windows To spy on one or more windows, select the windows (using the mouse and the Shift or Gtrl key), then choose Messages ISelected Windows. To change which windows are traced, change the selected window in Window Tree. To spy on all windows, regardless of what is selected in the Class List or the Window Tree, choose Messages IAll Windows. Message Trace becomes visible when you choose Messages ISelected Windows or Windows IAll Windows. Choose Messages ITrace Off to disable message tracing without hiding Message Trace. Choosing messages to trace Message Trace displays messages received by selected window classes or windows. Messages received via SendMessage are shown twice, once when they are sent and again when they return to show the return value. Dispatched messages are shown once only, since their return value is meaningless. The message display is indented to show how messages are nested within other messages. USing the Message Trace view By default, WinSight traces all messages and displays them in the Message Trace view. WinSight gives you several ways to narrow down the tracing of messages: • Choose Messages ISelected Classes or Messages ISelected Windows, then select the classes (in the Class List view) or windows (in the Window Tree view) by using the mouse and Shift or Gtrl. • Choose Message IAll Windows. • Choose Message IOptions, then select any or all of fourteen groups of messages. Check All Messages in the Options dialog box to return to tracing all messages. Other tracing options The Message Trace Options dialog box lets you change the format of the messages in Message Trace. It also lets you trace messages to a file, printer, or an auxiliary monitor or window. • Normally, the Message Trace view interprets each message's parameters and displays them in a readable format (Interpret Values is checked). Check Hex Values to view message parameters as hex values of wParam and lParam. • Information on traced messages usually displays in the Message Trace view. However, you can send messages to a file, printer, or auxiliary monitor by checking Log File in the Message Trace Options dialog box and doing one of the following: Type a file name to trace to a log file. If the file already exists, messages are appended to the file. @ C hap t e r 2 2, Win S i 9 h t 347 Type the name of the device (for example, type PRN) for the log file to send outpuf to the printer port. • Type AUX to output trace messages to an auxiliary monitor or window. To do this, you must have WINOX.5YS or OX.5YS installed as a device in your CONFIC.5YS file. To stop logging message traces to a file, printer, or auxiliary monitor, uncheck Log File. Use the following format: 48 Handle ["Title" or {Class}] Message Status Handle is the window handle receiving the message. Title is the window's title. If the title is the null string, the class name is displayed instead, in curly braces. Message is the message name as defined by Windows. They are displayed in WinSight in all uppercase letters. Known undocumented Windows messages are shown in lowercase. Unknown message numbers (user-defined) are shown as wm_User+OxXXXX if they are greater-than or equal to wm_User or as wm_OxXXXX if they are less than wm_User. Registered message numbers (from RegisterWindowsMessage) are shown with their registered name in single quotes. Status is one or more of the following: • Dispatched indicates the message was received via DispatchMessage. • Sent [from XXXX] indicates the message was received via SendMessage. If it was sent from another window, from xxxx gives that window's handle. If it was sent from the same window receiving it, this is shown with "from self." If it was sent from Windows itself, the "from" phrase is omitted. • Returns indicates the message was received via SendMessage and is now returning. • Additional messages might include a numeric return value or text message such as wm_GetText. For sent and dispatched messages, WinSight interprets the parameters and gives a readable display. For messages that have associated data structures (wm_Create, for example) it takes those structures and includes them in the display. Table 22.1 Mouse messages WM_HSCROLL WM_MBUITONUP WM_RBUITONDOWN WM_LBUITONDBLCLK WM_MOUSEACTNATE WM_RBUTTONUP WM_LBUITONDOWN WM_MOUSEFIRST WM_SETCURSOR WM_LBUITONUP WM_MOUSELAST WM_VSCROLL WM_MBUTIONDBLCLK WM_MOUSEMOVE WM_MBUTIONDOWN WM_RBUTTONDBLCLK Table 22.2 Window messages WM_ACTNATE WM_GETDLGCODE WM_QUERYNEWPALETTE WM_ACTNATEAPP WM_GETFONT WM_QUERYOPEN 348 c++ User's Guide Table 22.2 Window messages WM_GETMINMAXINFO WM_GETTEXT WM_GETTEXTLENGTH WM_ICONERASEBKGND WM_KILLFOCUS WM_MOVE WM_PAINT WIn_painticon WM_QUERYDRAGICON WM_QUERYENDSESSION WM_QUIT WM_SETFOCUS WM_SETFONT WM_SETREDRAW WM_SETIEXT WM_SHOWWINDOW WM_SIZE WM_WINDOWPOSCHANGED WM_WINDOWPOSCHANGING WM_KEYUP WM_MENUCHAR WM_MENUSELECT WM_PARENTNOTIFY WM_SYSCHAR WM_SYSDEADCHAR WM_SYSKEYDOWN WM_SYSKEYUP WM_TIMER WM_VKEYTOITEM WIn_yomichar WM_COMPACTING WM_PALETTEC~GED WM_DE~ODECHANGE WM_PALETTEISCHANGING WM_POWER WM_QUEUESYNCH WM_SPOOLERSTATUS WM_SYSCOLORCHANGE WM_SYSCOMMAND WM_TIMECHANGE WM_WININICHANGE WM_CANCELMODE WM_CHILDACTIVATE WM_CLOSE WM_CREATE WM_CTLCOLOR WM_DDE_FIRST WM_DESTROY WM_ENABLE WM_ENDSESSION WM_ERASEBKGND Table 22.3 Input messages WM_CHAR WM_CHARTOITEM WM_COMMAND WM_DEADCHAR WM_KEYDOWN WM_KEYLAST Table 22.4 System messages WM_ENTERIDLE WM_FONTCHANGE WIn_null Table 22.5 Pen messages WIN_USER WM_GLOBALRCCHANGE WM_HEDITCTL Table 22.6 WM_HOOKRCRESULT WM_PENWINFIRST WM_PENWINLAST Initialization messages C hap t e r 2 2, Win S i 9 h t 349 Table 22.7 Clipboard messages WM_ASKCBFORMATNAME WM_DES1ROYCLIPBOARD WM_CHANGECBCHAIN WM_DRAWCLIPBOARD WM_CLEAR WM_HSCROLLCLIPBOARD WM_RE~ERALLFORMATS WM_RE~ERFORMAT , WM_SIZECLIPBOARD WM_COPY WM_PAINTCLIPBOARD WM_UNDO WM_CUT WM_PASTE WM_VSCROLLCLIPBOARD WM_DDE_EXECUTE WM_DDE_INITIATE . WM_DDE_REQVEST WM_DDE_ADVISE WM_DDE_DATA" WM_DDE_POKE WM_DDE_UNADVISE WM_NCACTIVATE WM_NCLBUTIONDOWN WM_NCPAINT WM_NCCALCSIZE WM_NCLBUTIONUP WM_NCRBUTIONDBLCLK WM_NCCREATE WM_NCMBUTIO~BLCLK WM_NCRBUTIONDOWN WM_NCDES1ROY WM_NCMBUTIO~OWN WM_NCRBUTIONUP WM_NCIDITEST WM_NCMBUTIONUP WM_NCLBUTIO~BLCLK WM_NCMOUSEMOVE Table 22.8 DDE messages WM_DDE_ACK Table 22.9 WM_DDE_TERMINATE Nonclient messages Table 22.10 Control messages BM_GETCHECK CBN_SELCHANGE EN_VSCROLL BM_GETSTATE CBN_SELENDCANCEL LB_ADDSTRING BM_SETCHECK CBN_SETFOCUS LB_DELETESTRING BM_SETSTATE DM_GETDEFID LB_DIR BM_SETSTYLE DM_SETDEFID LB_FINDSTRING BN_CLICKED EM_CANUNDO LB_FINDSTRINGEXACT BN_DISABLE EM_EMPTYUNDOBUFFER LB_GETCARE~EX BN_DOUBLECLICKED EM_FMTLINES LB_GETCOUNT BN_HILITE EM_GETFIRSTVISIBLELINE LB_GETCURSEL BN_PAINT EM_GETHANDLE BN_UNHILITE EM_GETLINE CB_ADDS1RING EM_GETLINECOUNT LB_GETITEMHEIGHT LB_GETHORIZONTALEXTENT ! LB_GETITEMDATA CB_DELETESTRING EM_GETMODIFY LB_GETITEMRECT CB_DIR EM_GETPASSWORDCHAR LB_GETSEL CB_FINDS1RING EM_GETRECT LB_GETSELCOUNT CB_FINDS1RINGEXACT EM_GETSEL LB_GETSELITEMS 350 c++ User's Guide Table 22.10 Control messages CB_GETCOUNT CB_GETCURSEL CB_GETDROPPEDCONTROLRECT CB_GETDROPPED6TATE CB_GETEDITSEL CB_GETEXTENDEDlIT CB_GETITEMDATA CB_GETITEMHEIGHT CB_GETLBTEXT CB_GETLBTEXTLEN CB_INSERTSTRING CB_LIMITTEXT CB_MSGMAX CB_RESETCONTENT CB_SELECTSTRING CB_SETCURSEL CB_SETEDITSEL CB_SETITEMDATA CB_SETITEMHEIGHT CB_SHOWDROPDOWN CBN_CLOSEUP CBN_DBLCLK CBN_DROPDOWN CBN_EDITCHANGE CBN_EDITUPDATE CBN_ERRSPACE CBN_KILLFOCUS em-setthumb EM_GETWORDBREAKPROC EM_LIMITTEXT EM_LINEFROMCHAR EM_LINEINDEX EM_LINELENGTH EM_LINESCROLL EM_MSGMAX EM_REPLACESEL em_~croll EM_SETFONT EM_SETHANDLE EM_SETMODIFY EM_SETPASSWORDCHAR EM_SETRECT EM_SETRECTNP EM_SETSEL EM_SETTABSTOPS EM_SETWORDBREAK EM_UNDO EN_CHANGE EN_ERRSPACE EN_HSCROLL EN_KILLFOCUS EN_MAXTEXT EN_SETFOCUS EN_UPDATE LB_GETTEXT LB_GETTEXTLEN LB_GETTOPINDEX LB_INSERTSTRING LB_MSGMAX LB_RESETCONTENT LB_SELECTSTRING LB_SELITEMRANGE LB_SETCARETINDEX LB_SETCOLUMNWIDTH LB_SETCURSEL LB_SETHORIZONTALEXTENT LB_SETITEMDATA LB_SETITENniEIGHT LB_SETSEL LB_SETTABSTOPS LB_SETTOPINDEX LBN_DBLCLK LBN_ERRSPACE LBN_KILLFOCUS LBN_SELCANCEL LBN_SELCHANGE LBN_SETFOCUS STM_GETICON STM_SETICON Table 22.11 Multimedia messages MM~DLIB MMJOYIBUTTONDOWN MMJOYlBUTTONUP MMJOYIMOVE MMJOYIZMOVE MMJOY2BUTTONDOWN MMJOY2BUTTONUP MMJOY2MOVE MMJOY2ZMOVE MM_MCINOTIFY MM_MICROSOFT MM_MIDCMAPPER MM_MIM_CLOSE MM_MIM_DATA MM_MIM_ERROR MM_MIM_LONGDATA MM_MIM_LONGERROR MM_MIM_OPEN MM_MOM_CLOSE MM_MOM_DONE MM_MOM_OPEN MM_MPU40LMIDIIN MM_MPU40LMIDIOUT MM_PCJOYSTICK MM_SNDBLST_MIDIIN MM_SNDBLST_MIDIOUT MM_SNDBLST_SYNTH MM_SNDBLST_WAVEIN MM_SNDBLST_WAVEOUT MM_WAVE_MAPPER MM_WIM_CLOSE MM_WIM~DATA MM_WIM_OPEN MM_WOM_CLOSE MM_WOM_DONE MM_WOM_OPEN Chapter 22, WinSight 351 Table 22.12 Other messages and messages not documented by Microsoft WIn_alttabactive WIn_entersizemove WM_MDIRESTORE WIn_begindrag WIn_exitmenuloop WM_COALESCE_FIRST WIn_exitsizemove WM_MDISETMENU WM_MDmLE WM_COALESCE_LAST WIn_filesyschange WM_MEASVREITEM WM_COMMNOTIFY WIn~ethotkey WM_NEXTDLGCTL WM_COMPAREITEM WIn_isactiveicon WIn_nextmenu WIn_convertrequest WM_KEYFIRST WIn_querydropobject WIn_convertresult WIn_Ibtrackpoint WIn_queryparkicon WM_DELETEITEM WM_MDIACTIVATE WIn_sethotkey WIn_dragloop WM_MDICASCADE WIn_setvisible WIn_dragmove WM_MDICREATE wm_sizewait WIn_dragselect WM_DRAWITEM WM_MDIDESTROY WIn_syncpaint WM_MDIGETACTIVE WIn_synctask WM_DROPFILES WM_MDllCONARRANGE WM_SYSTEMERROR WIn_dropobject WM_MDIMAXIMIZE WIn_systimer wm_entermenuloop WM_MDINEXT WID_testing 352 C++ Use r' 5 Gu ide WinSpector WinSpector is a tool that helps you perform postmortem debugging (debugging after your program has ungracefully terminated) of Unrecoverable Application Errors (UAEs) and General Protection Faults (GPFs). When a UAE or GPF occurs, WinSpector writes a log file to your disk that shows you helpful information about the cause of the exception, including • • • • • The call stack that was active when an exception occurred Function and procedure names in the call stack CPU registers A disassembly of the machine instructions where the exception occurred Windows information about the program environment Before using WinSpector, be sure that TOOLHELP.DLL (from Windows 3.1 or later) is in your search path (TOOLHELP.DLL ships with Windows). TOOLHELP.DLL is a Windows DLL that lets utilities access low-level system information. WinSpector uses TOOLHELP.DLL to log exceptions and to obtain the system information it writes to the log file. Don't use other exception debugging tools, except for Turbo Debugger, while running with WinSpector. There are three ways to start WinSpector (it loads minimized): • Include it in the "load=" section of your WIN.INI file. • Include it in the Startup folder in Windows. • Double-click the WinSpector icon to run WinSpector after you load Windows. When an exception (UAE or GPF) occurs, WinSpector creates a report in a file called WINSPCTR.LOG (a text file) with information to help you determine what caused the error. WinSpector also creates a file called WINSPCTR.BIN, a binary file that the DFA utility translates into a text file called DFA.OUT (see page 17 for more information on DFA.EXE). After the exception, WinSpector displays a dialog box with a brief exception report. Click OK to remove the box and read the log file to find the cause of the exception. You can control the output to WINSPCTR.LOG as described in the following section. Chapter 23, WinSpector 353 Configuring WINSPCTR.LOG There are two ways you can set the WinSpector options that control the output to WINSPCTRLOG: • To use the WinSpector Preferences dialog box, start WinSpector, click the WinSpector icon and choose Preferences from the pop-up menu. • To edit commands in WINSPCTRINI, load the file into any text editor, edit or add commands, then save the file and restart WinSpector. The following paragraphs describe each option in the Preferences dialog box. WINSPCTRINI options are listed in bold. LogDir=[directory]: Directory is the location of WINSPCTR.LOG. Type the path where you want the file (C:WINDOWS is the default). LogViewer=[viewemame]: Viewer is the program WinSpector uses to display the log file. Type the path and file name of the viewer you want to use (NOTEPAD.EXE is the default). For example, type C :WIN31WRITE. EXE. If WinSpector can't find the editor, it displays the message Error: Unable to execute: [option], where option is the editor file name. Check to make sure the editor you indicated exists in the specified directory. CreateNewLog= 0 (append) or 1 (overwrite): Append New Reports and Overwrite Previous Reports lets you control whether WinSpector appends reports to the existing log file or overwrites the old log file when a new report is generated. ShowSystemlnfo= 0 (omit) or 1 (show): Check System Information to add the Task List, the Module List, and information about the USER and GDI heaps to the log file. LogToStdAux=O (on) or 1 (off): Check AUX Summary to view an abbreviated form of the information sent to the log file on the AUX device. To use this option, you need a terminal connected to AUX or a device driver, such as OX.sYS, that redirects the AUX device to a second monitor. PostMortemDump= 1 (show) or 0 (omit): Check PostMortem Dump to generate a WINSPCTRBIN file. Use DFA.EXE to translate the BIN file into a text file you can read. ShowStacklnfo= 1 (show) or 0 (omit): Check Stack Frame Data to add a verbose stack trace display to the log file. For each stack frame that doesn't exceed 256 bytes, WinSpector performs a hex dump, starting at the SS:BP for that frame. If there are more than 256 bytes between two successive stack frames, the memory display is omitted for that frame. You can use this data to get the values of the parameters that were passed to the function. It's usually easier to let DFA do the hard work of figuring out what your parameters are. However, for those cases where Turbo Debugger information is not available, you might find that a verbose trace supplies helpful information. ShowUserInfo= 1 (show) or 0 (omit): Check User Comments if you want to add information to the log file about what was happening when the exception occurred. With User Comments checked, WinSpector displays a dialog box immediately after the exception. The comments you type are appended to the log file. 354 c++ User's Guide WINSPCTR.LOG reference Each report in WINSPCTRLOG has several sections that help you determine what caused the exception in your program. The first line of a report in WINSPCTR.LOG gives the date and time when the exception occurred; for example, WinSpector failure report - 6/18/1992 11:04:25 The second line lists • • • • • What type of exception occurred ( lists frequent exceptions) The module name The logical address The physical address The currently active task at the time of the exception. A second line might look like this: Exception 13 at USER 002A:0429 (079F:0429) Table 23.1 o 12 13 (TASK=BAD) Exception types Division by zero Stack fault General protection fault (GPF) Occurs during a DIV or an IDIV interaction if the divisor is O. Usually occurs when there is not enough room on the stack to proceed. All protection errors that don't cause another exception cause an exception 13. Exception 13 errors include, but are not limited to, the following errors: • Invalid selector loaded into a segment register. • Segment limit exceeded. Although the selector is valid, the offset value is greater than the segment limit (for example, an array index out of bounds error in DS, ES, or other segments). • Execution is transferred to a nonexecutable segment, such as a bad function pointer. • Accessing DS, ES, FS, or GS registers containing a null selector. (This error can cause a oto appear in the segment register of the log file.) A log file lists both the physical and logical addresses where the exception occurred. These two types of addresses are important to Windows programs for the following reasons: • When a program is loaded, Windows allocates space for each logical segment and assigns each segment a unique selector. The selector and its offset are combined to form a physical address. • When a Windows .EXE file is linked, each segment is placed in a different section of the file, and a segment table is created. • A logical address, which is actually a segment's position in the Windows segment table, consists of a module name, a logical segment, and an offset. You can run Chapter 23, WinSpector 355 TDUMP on the file to find out segment size and other information, or you can generate a .MAP file that contains the same kind of information. If the stack pointer is too small at the time of exception, TOOLHELP.DLL automatically switches the stack and appends the message Stack Swi tched to the end of the second line of the log. Disassembly section The Disassembly section in WINSPCTR.LOG begins with the assembly language instruction that caused the exception that is followed by the next few instructions in the program, which provide a point of reference for finding the task that caused the exception. For example, given the following code, where ES is the segment register that contains a selector and BX is the offset into the segment, an exception 13 occurred because the value in BX was greater than the segment limit referenced by ES: 079F:0429 079F:042D 079F:042F 079F:0435 CMP JNE CMP MOV BYTE PTR ES: [BX],FF 043A WORD PTR [BP+06],03 DI, 0001 Stack Trace section The first line of the Stack Trace section in WINSPCTR.LOG identifies the function or procedure that was executing at the time of the exception. Stack Trace information includes the • Frame number. • Module name. • Name of the closest function before the address of the one that caused the exception, plus a number indicating how far away you were from that function. (This information is present only if a .5YM file is present.) • Logical and physical address for the stack frame. • Location where your program returns after the call. When WinSpector lists function names, it looks in the .SYM file for the closest symbol name that appears before the address in the call stack. Since some .SYM files do not contain information for all functions, the function name in the log file is the closest function in the .5YM file with an address preceding the frame address. If the offset field appears to be too high, function names might not be reliable. The following stack trace information shows some of the functions that were executing at the time BAD, a sample task, caused an exception: ·Stack Trace: o User CS:IP 002A:0429 (079F:0429) C':WIN31SYSTEMUSER. EXE 356 c++ User's Guide SS:BP 10FF:18CA 3 BAD function5(unsigned long, unsigned long, unsigned long) + 0014 CS:1P 0001:0184 (1107:0184) SS:BP 10FF:1952 C:B1NBAD.EXE Register section The Register section in WINSPCTR.LOG lists the values stored in the standard registers when the exception occurred, as the following example shows: Registers: 0037 EX 0000 CX 0008 DX 10EE 81 0037 0028 DI AX Limits and access rights are given for the CS, OS, ES, and SS registers. Message Queue section The Message Queue section in WINSPCTR.LOG gives the last message received in the middle of processing. This section also lists any messages that were waiting in the queue at the time of exception. For each message, WinSpector lists the following informatibn: • The Window handle that identifies the destination window • The Message 10 number that identifies the message • Two parameters that contain additional message information Note The Message Queue section might not list the last message the program received: Windows could bypass the message queue by using a SendMessage or similar function. The following Message Queue example shows one message received and one waiting in the queue: Message Queue: Last message received: hWnd: 0000 msg: 0001 Waiting in queue: hWnd: 0000 msg: 0001 wParam: 0002 lParam: 00000003 wParam: 0002 lParam: 00000003 Tasks section The Tasks section in WINSPCTR.LOG lists the programs running when the exception occurred, including the • • • • • Complete path to the executable file Module name Windows module handle Task handle Data segment value for the task (the instance handle) Some of the tasks running when the BAD application caused an exception include C:W1N318Y8TEMNWPOPUP.EXE Module: NWPOPUP hModule: 142F hTask: 141F h1nstance: 13F6 C hap t e r 2 3, Win S pee tor 357 C:BINWINSPCTR.EXE Module: WINSPCTR C:BINBAD.EXE Module: BAD hModule: 1397 hModule: 1467 hTask: 1387 hTask: 1127 hlnstance.: 135E hlnstance: 10FE Modules section The Modules section in WINSPCTR.LOG lists the modules that were running at the time of the exception, including the • • • • • • Path to the executable file Date stamp of the executable file File size Module name Module handle Reference count indicating how many times the module is in use Three of the modules running when the BAD application caused an exception include C:WIN31SYSTEMKRNL386.EXE Date: 03/02/1992 Module: KERNEL hModule: 010F reference C:WIN31SYSTEMSYSTEM.DRV Date: 03/01/1992 Module: SYSTEM hModule: 013F reference C:CBINWINSPCTR.EXE Module: WINSPCTR Size: 116132 count: 21 Size: 2304 count: 13 Date: 06/02/1992 Size: 46256 hModule: 1397 reference count: 1 USER and GDI heap section The USER and GDI (graphics device interface) heap information section in WINSPCTR.LOG shows what percentage of the USER and GDI heaps was available at the time of exception. For example, USER GDI Free Free 91% 83% Because Windows has only 64K of internal heap space for applications to share, it's often helpful to keep track of how the space is used. If you find that USER and GDI are taking up a lot of heap space, check to see if you have deallocated resources you are not using. The Help I About box for Program Manager lists the lower of these values as the amount of free System Resources. System Information section The System Information section in WINSPCTR.LOG shows the Windows version and mode you're running, including • • • • • 358 CPUtype Largest free block of contiguous linear memory in the system Total linear address space in pages Amount of free memory pages in the linear address space Number of pages in the system swap file c++ User's Guide 'The System Information section for a 486 system might look like this: System info: Running in enhanced mode under Windows 3.1 debug version CPU: 80486 Largest free memory block: 3457024 bytes Total linear memory space: 19696 K Free linear memory space 18212 K Swap file Pages: 0 (0 K) Processing WinSpector data DFA is a utility that takes a WINSPCTRBIN file· and Turbo Debugger information (either in the .EXE, .DLL or .TDS files) and translates the binary data into a useful form by generating a file that contains not only stack trace information similar to the log file but also function names, line numbers, and local and global variables. DFA post-processes Turbo Debugger information that WinSpector gathered at the time of the exception. If you check the PostMortem dump option (see page 12), WinSpector creates a WINSPCTRBIN file at the time of the exception. You can use DFA.EXE to translate the binary data in WINSPCTR.BIN into usable information stored in a text file called DFA.OUT. Because only one WINSPCTRBIN file is written per Windows session, make sure you run DFA promptly. For example, if you get three UAEs in succession, WinSpector will write three reports to the log file, but binary data will exist for only the first report. It's best to run DFA immediately after receiving the first UAE. You might then want to rename the DFA.OUT file and delete the WINSPCTRBIN and WINSPCTR.LOG files before continuing. DFAoutput DFA writes a file only if Turbo Debugger information exists for the file in the stack frame. 'The DFA output file (DFA.OUT) has a stack trace similar to the one in the WinSpector log file, except that it contains • • • • Function names Line numbers Local and global variables Data segments and their values (including the stack segment) Using DFA with WINSPCTR.LOG When DFA is used with the WINSPCTRLOG file alone, it gives minimal stack trace information, such as addresses. If Turbo Debugger information (contained in a .EXE, .DLL, or .IDS file) is present, source file names and line numbers are added to the report. C hap t er 2 3, Win S pee tor 359 Using DFA with WINSPCTR.BIN When used with the WINSPCTR.BIN file, DFA • Adds stack-based variables to the log, including local variables, parameters passed to the function, structures, and arrays. • Lists variable types, values, and addresses by function. If Turbo Debugger information is present, for each stack frame, DFA reports • In section one, the • • • • Source file Line number Local variables Parameters • In section two, the • Module name for the task with the fault • Filenames • Logical segments • The segments' selectors • Whether the segments are data or code segments • In section three, the • Global variables • Static variables • The va~'iables' values at the time of the exception The format is DFA [option] WINSPCTR.LOG [WINSPCTR.BIN] When WINSPCTR.LOG (required) is present, you get source file and line numbers. When WINSPCTR.BIN (optional) is present, you get additional variable information. Table 23.2 DFA options IOloutputfile1 ID Renames the output file from the DFA.OUT default Forces DFA to write a hex dump of the saved data segments Other WinSpector" tools WinSpector has three utilities you can use to enhance the information about an exception: • EXEMAP.EXE creates a .MAP file from a Windows .EXE file. The .MAP file is needed to create a .SYM file, which expands error reporting for the original .EXE. • TMAPSYM.EXE, used in conjunction with EXEMAP.EXE, creates a .5YM file from a .MAPfile. 360 c++ User's Guide • BUILDSYM.EXE uses EXEMAP.EXE and TMAPSYM.EXE to create a .5YM file from a Windows .EXE file. Using EXEMAP.EXE EXEMAP creates .MAP files for Windows executables. A .MAP file can be used to create a .SYM file, which can then be used by WinSpector to expand its error reporting. If you are using .DLLs or other programs for which you don't have the source code, this information can be especially useful. To create a .MAP file from an .EXE, type EXEMAP filename. EXE newname. MAP. If you don't type a new name, EXEMAP creates a .MAP file with the same name as the .EXE. Although the resulting .MAP file isn't as complete as one generated by the link phase of the compile process, it does include addresses for exported public functions. Using TMAPSYM.EXE TMAPSYM creates .5YM files from existing .MAPfiles (created either by the compiler or by the EXEMAP utility). The resulting .5YM files make available to WinSpector the public functions, variable names, and functions in the entry table of the executable. Constants and line-number information, however, are not included in a TMAPSYMgenerated.5YM file. To create a .SYM file from a .MAP file, type TMAPSYM .MAP extension). filename . MAP (you must type the Using BUILDSYM.EXE BUILDSYM creates .5YM files from .EXE files. It has the same output as using both EXEMAP and TMAPSYM, since it automatically runs them, but it deletes the .MAP files from your directory. BUILDSYM supports wildcards, so you can create .SYM files for part or all of a directory by entering a single command. To run BUILDSYM, both EXEMAP and TMAPSYM must be in the same directory as BUILDSYM or in your search path. BUILDSYM places the .5YM files it creates in the current directory. For WinSpector to find a .SYM file, the file must be in the same directory as the executable that caused the exception. BUILDSYM performs the following tasks: • Verifies that the files are Windows files, and if not, leaves them alone. • Calls EXEMAP to create .MAP files. • Verifies that .MAP files were created. • Calls TMAPSYM and passes the names of the new .MAP files so TMAPSYM can create.5YM files. • Deletes the .MAP files because they are no longer needed. To create a .SYM file from an .EXE, type BUILDSYM filename. EXE. C hap t e r 23, Win S pee tor 361 362 C++ Use r 's G u ide Turbo Profiler user's guide Borland's Turbo Profiler is the missing link in your software development cycle. Once . you have your code doing what you want, Turbo Profiler helps you do it faster and more efficiently. It is a performance analyzer and a resource monitor. Turbo Profiler is a performance analyzer, a software tool that measures your program's performance by finding • • • • • Where your program spends its time How many times a line executes What lines have been executed How many times a routine is called, and by which routines What files your program accesses most and for how long Turbo Profiler also monitors critical computer resources, such as • Processor time • Disk access • Keyboard input • Printer output • Interrupt activity By monitoring vital activities and providing detailed statistical reports on every part of your program's performance, Turbo Profiler enables you to fine-tune your programs. By opening up the inside of your program and exposing its most intricate operations-from execution times to statement counts, from interrupt calls to file access activities-Turbo Profiler helps you polish your code and speed up your programs. Turbo Profiler surpasses other profilers on the market both in power and ease of use by providing the following features: Part IV, Turbo Profiler user's guide 363 • Interactive profiling quickly reveals inefficient code in a program. • Lets you read and edit any text file during profiling sessions. • Profiles any size program that runs under DOS or Windows. • Handles programs written using Borland's C++ compilers and Turbo Assembler. • Provides an easy-to-use interface with multiple overlapping windows, mouse support, and context-sensitive help. • Reports execution time and execution count for routines and program lines. • Tracks which blocks of code have and haven't been executed. • Tracks complete call path history for all routines. Analyzes frequency of calls with complete call stack tracing. • Monitors DOS file activi~es from the Files window by file handle and time of open, close, read, or write. Uses an event list to log the number of bytes read or written. • Supports co~plete tracking of overlays. • Allows re~ote serial and network profiling. By picking up where code optimizers leave off, Turbo Profiler directs you immediately to slow code, pointing out where to open up bottlenecks and when to rework algorithms. The difference between optimizing and profiling An optimizer makes your program run a little faster by replacing time-consuming instructions with less-expensive ones. But optimizing can't fix inefficient code. Turbo Profiler helps you detect the least efficient part of your code and helps point to algorithms that can be modified or rewritten. Studies show that the largest performance improvements in programs come from changing algorithms and data structures, rather than from optimizing small segments of compiled code. Trying to find program bottlenecks without a profiler is like trying to find bugs without a debugger; Turbo Profiler reduces both the time and effort it takes to improve your program's performance. How this part is organized Part IV is divided into the following chapters: Chapter 24, A sample profiling session," is a tutorial that takes you through a simple profiling session. The tutorial-starts with a "let's see what's going on" profile, then takes you through interpreting the profile data collected, modifying and refining the program based on insight gained from the profile, and running additional profiles to gauge the effect of each successive modification. . 1/ 364 c++ User's Guide Chapter 25, "The Turbo Profiler environment," explains in detail each menu item and dialog box option in the Turbo Profiler environment. Chapter 26, "Profiling strategies," provides general guidelines and tips for conducting a fruitful profiling session. Chapter 27, "Inside the profiler," uses analogy to explain how Turbo Profiler gathers execution-time and execution-count data while your program runs. Chapter 28, "Turbo Profiler's command-line options," lists each Turbo Profiler command-line option and explains what the option accomplishes. Chapter 29, "Customizing Turbo Profiler," explains how to use TFINST to change the configuration defaults of TPROF and TPROFW. Chapter 30, "Remote profiling," describes how to profile with two systems; you run your program on one and Turbo Profiler on the other. Chapter 31, "Turbo Profiler for Windows," describes how to run Turbo Profiler for Windows and how to use its special features. Chapter 32, "Prompts and error messages," lists all prompts and error messages that can occur, with suggestions on how to respond to them. Part IV, Turbo Profiler user's guide 365 366 c++ User's Guide Asample profiling session Profiling is one of the least-understood yet most useful and vital areas of good software development. Surveys indicate that only a small fraction of professional programmers actually use profilers to improve their code. Other studies show that, most of the time, even the best programmers guess wrong about where the bottlenecks are in their programs. What is the advantage to using this widely overlooked tool? For one, profiling your program can increase its overall performance. Second, profiling can augment your ability to produce efficient code. The bottom line is that profiling, like debugging, can be a cog in the wheel of the program development cycle. We've based the examples in this chapter on John Bentley's "Programming Pearls" column (July 1987) in Communications of the ACM. In this chapter we show you an example of profiling put to good use, and how-in the long run-profiling can save you hours of hunting for that expensive line of code. You use Turbo Profiler to: • • • • See where your program spends its time. Create an annotated source listing and a profile statistics report. Save profile statistics, then start up again with saved statistics. Analyze profile statistics and source code in side-by-side windows. All the tutorial examples were run on a 486 machine with an SVGA video adapter. The examples in this chapter are based on finding and printing all prime numbers between 1 and 1,000. Recall that a number is prime if it is an integer and is divisible by only the integer 1 and itself; it must also be odd, since any even number is divisible by 2 and therefore is not prime (actually, 2 is the only even prime number). You can tell whether a particular number is prime by checking to see if it is divisible by other, smaller primes, or by any integer larger than the first two primes, 2 and 3. C hap t e r 24, A sam pie pro f iii n 9 s e s s ion 367 The object of profiling the example programs is to speed up the process of finding and printing the prime numbers. As you work through the examples, you'll learn how to use Turbo Profiler to test the efficiency of each example's structure. The first program you'll look at is PRIMED. Once you've profiled it and seen where to modify the code, all you need to do is load and profile PRIMEl. With the exception of PRIMEl, each of the programs covered in this chapter (PRIME2, PRIME3, PRIME4, and PRIMES) is a variation on its predecessor. About the sample programs The Turbo Profiler package comes complete with the sample programs used in this chapter. Both the source code and the executable code are provided; Turbo Profiler requires both to analyze a program. Each of the sample programs was compiled with full symbolic information, since the profiler also requires this information. To ensure that your own programs contain full symbolic information, you must compile them with the appropriate compiler options turned on, as shown in the following list: • Borland's line of c++ compilers: If you are compiling in the IDE, 1 Choose Options I Project. 2 Choose the Compiler I Debugging topic, then check Include Debug Information. :3 Choose the Linker I General topic, then check Include Debug Information. If you are compiling from the command line, use the -v command-line option. • Turbo Assembler: Use the Izi command-line option, then link the program with TLINK, using the Iv option. Profiling a program (PRIMEO) You profile and improve a program in four steps: 1 Set up the program before profiling it. 2 Collect data while the program runs. 3 Analyze the collected data. 4 Modify the program and recompile it. After modifying your program, repeat steps 1 through 3 to see if the modifications have improved your program's performance. PRIMED uses Euclid's method of testing for prime numbers, a straightforward integer test for a remainder after division. As each prime number is found, it is stored in the array primes, and each successive number is tested for "primeness" by being divided by each of the numbers already stored in primes. Leaving Turbo Profiler at any time is a simple, one-step procedure: just choose File I Quit or press Alt+X. 368 c++ User's Guide Load PRIMEO into Turbo Profiler by typing TPROF PRIMEO and pressing Enter. The profiler comes up with two windows open: the Module window (which displays PRIMEO's source code) and the Execution Profile window (which will display profile statistics after you run PRIMEO). Figure 24.1 Turbo Profiler with PRIMEO loaded For a more detailed description of the profiler's environment, see Chapter 25, "The Turbo Profiler environment." The Module and Execution Profile windows are concerned with steps 1 and 3 in the profiling process. You use the Module window to determine what parts of the program to profile. Once you run a program, the Execution Profile window displays the information you need to analyze your program's behavior. Setting up the profile options Before you begin to profile your program, you might want to specify the areas you want to profile. An area is a location in your program where you want to collect statistics: an area can be a single line, a construct such as a loop, or an entire routine. To analyze a small number of short routines (like prime and main in this program), you have to know how often each line executes and how much time each line takes. To get this information, every line in the program must be marked as an area. By default, Turbo Profiler marks every line in a small program. To verify that this is true, you can check the Module window to see that all executable lines are tagged with a marker symbol (=». 1 Press Alt+F10 to open the Module window SpeedMenu. 2 Choose Add Areas from the SpeedMenu. This menu lists area boundaries for you to choose from. 3 Choose Every Line in Module. This sets area markers for all lines in the module, then returns the cursor to the Module window. C hap t e r 2 4, A sam pie pro f iii n 9 s e s s ion 369 Collecting data Now you're ready for the second step in the profiling process. Press F9 to run PRIMEO under Turbo Profiler. The program prints the prime numbers between 1 and 1,000 on your screen. When the program finishes, look at the information in the Execution Profile window. These are your program statistics. Zoom the Execution Profile window: Press F5 or choose Zoom from the Window menu. The Execution Profile window should now look similar to this: Figure 24.2 Program statistics, PRIMED The upper pane of the Execution Profile window displays the program's total execution time, along with information about the data in the lower pane. The lower pane has four fields for each line: • • • • An area name The number of seconds spent in that area The percentage of total execution time spent in that area A magnitude bar displaying a proportional graph of the execution time spent in that area The line #PRlMEO#31 3.3038 sec 81% [====================================== tells you that the thirty-first line of code in module PRIMEO executed for about 3.3 seconds-which was 81 percent of the total execution time for all marked areas. The magnitude bar automatically shows line 31's time full-scale because line 31 is the most time-consuming of the marked areas. Actual time and percentage statistics will vary from system to system. Displaying statistics You can also display this program's collected data as execution counts. 370 C++ Use r 's G u ide Press Alt+F10 to bring up the SpeedMenu for the Execution Profile window. Figure 24.3 The Speed Menu Display ... Filter All ~ Module Remove 2 Choose Display on the SpeedMenu. 3 The Display Options dialog box lists six possible ways to display data in the Execution Profile window. Figure 24.4 The Display Options dialog box • Time (the default setting) shows the total time spent in each marked area. Counts displays the number of times program control entered each area. • Both shows time and counts data on the same screen. • Per Call displays the average amount of time per call. liB Longest shows the longest time spent in each area. Modules (used with passive analysis) displays the time spent in each program module. @ @ 4 Choose Counts under Display in this dialog box. (Click Counts with the mouse, or use the arrow keys to move to it and press Enter, or press C, the hot key for this option.) \ 5 Choose OK (or press Enter). The Execution Profile window now displays PRIMEO's statistics as execution counts instead of execution times, as shown in this figure: Figure 24.5 Counts display in the Execution Profile window This display of PRIMEO's statistics shows that line 22 is the most frequently called line in PRIMEO. C hap t e r 24, A sam pie pro f iii n 9 s e s s ion 371 You can also see counts and times together. Bring up the Display Options dialog box again (either press Alt+F10 and choose Display, or press Ctrl+D). Choose Both under Display, then choose OK or press Enter. (To choose Both, either click it, or press Down to get to it, then press Enter, or press B, the hot key for this option.) When the Execution Profile window displays time and counts together, the first entry for each area is execution counts, and the second is execution time. Printing modules and statistics In this section, you print two things: 1 A profile source listing of the code that's in the Module window, with time and counts data attached to each marked area. 2 The profile statistics displayed in the Execution Profile window. Time and counts profile listing Before you print the time-and-counts statistics to a file, you must first set the appropriate printing options: 1 Choose Print I Options. 2 In the Printing OptiOl1S dialog box, choose the File radio button (press Tab until the radio buttons become active, then press Down to tum the setting to File). 3 Tab to the Destination File input box and type PRIMEOSC.LST 4 Choose ASCII to use the standard ASCII character set (rather than the IBM extended character set). 5 Choose OK (or press Enter). The cursor returns to the active Execution Profile window. Now, to print the listing file, choose Print I Module. In the Pick a Module dialog box, press Down to highlight the module name PRIMEO, then press Enter (or choose OK). To inspect the file PRIMEOSC.LST, choose View I Text File, and at the File Name prompt, type PRIMEOSC.LST This is what you see if you're profiling the C program PRIMEO.C. The times in your file will probably vary from the ones shown here because of the differences in computer systems. Turbo Profiler Version 4.5 Program: D:TPROFPRIMEO.EXE Time 372 Counts C++ Use r' s G u ide Tue Aug 20 15:16:47 1995 File primeO.c /* Copyright (c) 1990, Borland International */ Program for generating prime numbers using Euclid's method */ /* int primes[1000]; #define MAXPRIMES 1000 0.0000 1 main() { int j; int lastprime, curprime; 0.0000 0.0000 0.0000 0.0000 1 1 1 1 0.0359 1 0.0354 1 0.0059 500 primes [0] primes [1] lastprime curprime 2; 3; 1; 3; printf ("prime %d = %d \n", 0, primes [0] ) ; printf ("prime %d = %d \n", 1, primes [1]); while(curprime < MAXPRIMES) { for(j = 0; j <= lastprime; j++) i f ( (curprime % primes [j ] ) 0) 0.0071 499 0.3069 15122 0.0038 333 curprime += 2; 0.0034 333 break; 0.0060 0.0037 0.0017 6.2655 0.0019 0.0018 if(j <= lastprime) continue; lastprime++; printf ("prime %d = %d \n", last prime, curprime); primes [lastprime] = curprime; curprime += 2; 499 333 166 166 166 166 } 0.0000 1 This profile source listing is useful because it's a permanent record that shows, for each area in your program, the execution time and execution counts. When you have finished examining the listing, press AIt+F3, or click the close box, to close the File window. Profile statistics report You can also print a replica. of the open Execution Profile window's contents to your printer or to a disk file. 1 Choose Print IOptions again. 2 Choose the Printer radio button. C hap t e r 24, A sam pie pro f iii n 9 s e s s ion 373 3 Choose Graphics to include extended ASCII characters in th~ print~d report. (If your printer does not support extended ASCII characters such as E and E, skip this step . and proceed to step 4.) 4 Press Enter (or choose OK). 5 Choose Print IStatistics. The resulting printout, like the profile source listing, is a permanent record of your progress as you go through the steps of profiling, modifying, recompiling, and reprofiling in your quest for the sleekest and most efficient code possible (and practical) for your program. Saving and restoring statistics Before you go on, here's how to save PRIMEO's profile statistics to a file, so you can quit Turbo Profiler at any time without losing the data. We also show you how to restore those statistics the next time you start Turbo Profiler. Choose Statistics ISave to save your program's profile statistics to a .TFS (Turbo Profiler Statistics) file. Because PRIMEO is in the Module window, the File Name input box lists PRIMEO.TFS as the default. Choose OK to create this file. All the statistical data from the current profile run of PRIMEO is now saved in the file PRIMEO. TFS in the current directory, so you can quit the profiler at any time without losing any of that information. To restore the statistics you saved for PRIMEO, open PRIMEO in Turbo Profiler and choose Statistics IRestore. The File Name input box lists *.TFS as the default. Press Enter to go to the Files list box, then highlight PRIMEO.TFS and choose OK to recover the data from this file. The File Name input box lists*.TFS as the default. Press Enter to go to the Files list box, then highli9ht PRIMEO.TFS and choose OK to recover the data from this file. Analyzing the statistics In this section you willieam how to analyze the statistics in the Execution Profile window so you can use what they reveal to streamline your program. First, though, take another look at the time and count statistics in the Execution Profile window. Unzoom the Execution Profile window (choose Zoom from the Window menu or press F5) and look at the statistics for lines 22 and 31 (the if and printf statements). , We cover modifications to the printf statement in program PRIMES. A time and count profile like this tells a lot about a program. For instance, you can see that line 22 in PRIMEO executes far more frequently than any other statement. It makes sense that line 22 executes 15,122 times, since it tests every number between 4 and 1,000 against every number in the array primes, until there is even division or the array is exhausted. That means a lot of numbers to be tested. You can also see that line 31, the printf statement, accounts for most of the program's total execution time. 374 c++ User's Guide Viewing both source code and statistics The data in the Execution Profile window shows that the test in line 22 is doing more work than it should. But you can't really get the entire picture until you look at execution time and count data and source code together. What you need to do is compare time and count data in the Execution Profile window and the corresponding source code in the Module window. Here's one way to display source code and profile statistics simultaneously: Resize and move the Execution Profile window s~ it occupies the right half of your screen: Choose Window ISize IMove, or press Ctrl+F5. 2 Follow the directions on the status line to: 1 Resize the window to full-screen height and half-screen width. 2 Move the resized window to the right. When you've done steps 1 and 2, press Enter. 3 Activate the Module window by pressing F6, then resize and move it so it occupies the left half of the screen. 4 Go back to the Execution Profile window (press F6 again). To resize a window with the mouse, drag the Resize box in the lower right comer; to move the window, drag the title bar or any double-line left or top border character (llor=). There is an automatic link between the Execution Profile window and the Module window, so that when you move through the source code, the execution profile display tracks the cursor's current line position. To see this tracking feature in action, Activate the Execution Profile window (press F6), and move the highlight bar to the first line. 2 Open the SpeedMenu (press Alt+F10) and choose Module (or just press Ctrl+M). The profiler positions the cursor on line 31 in the Module window. 3 Use the arrow keys to move through the source code to line 22. This line is the second-largest time consumer in PRIMEO. The top two statistics lines in the Execution Profile window now display the profile data for this if statement. 4 Move the cursor in the Module window to line 21 and note how the display in the Execution Profile window tracks with it. The top lines in the Execution Profile window are now the profile statistics for line 21. 5 Move the cursor to line 30 and note the display in the Execution Profile window. Having the two windows synchronized this way makes it easy to find the greatest resource hogs in your program. Once you get a better feel for interpreting the data onscreen, you won't need to rely as much on profile listings like the one on page 372. C hap t e r 2 4, A sam pie pro f iii n 9 s e s s ion 375 Saving the window configuration This is a good !ime to save your customized version of Turbo Profiler. If you don't save your customized window arrangement, the windows will revert to their default size and placement the next time you load a program into Turbo Profiler. 1 Choose Options I Save Options. This brings up the Save Configuration dialog box. 2 By default, the Options check box is already checked. This records settings (such as the Execution Profile window's display options) in the configuration file. 3 In the Save Configuration dialog box, tab to Layout and press Spacebar. This causes your side-by-side window layout to be saved in the configuration file. 4 By default, the configuration file to be saved is TFCONFIG.TF, listed in the Save To input box. Choose OK, or press Enter, to save your options to this file in the current directory. Wherever you start up Turbo Profiler, it looks for TFCONFIG.TF, the default configuration file. When the profiler finds that file, the options and layout you've set will come up automatically. Measuring an area's efficiency The ratio of execution time to execution counts is a good measure of aline's or routine's overall efficiency. To see this ratio for the areas in PRIMEO, change the display option in the Execution Profile window. Here's how: 1 From the Execution Profile window's SpeedMenu (press Alt+F10), choose Display. 2 Under Display in the dialog box, choose Per Call. 3 Choose OK (or press Enter). Now you can see that line 22 is much more efficient than line 31. It uses up a lot of execution time because it executes so many times, but each individual call averages much less than a millisecond. Line 31, on the other hand, averages nearly 20 milliseconds per call. Note The output from the profiler points the way to improving the execution time of PRIMEO and making it structurally simple. The task of improving the program can be divided into two strategies: 1 Reduce the amount of time spent in input/ output. 2 Rewrite the looping structure to be more streamlined and efficient. The input/ output problem can be partially resolved by reducing the printf statement from its present form printf ("prime %d = %d \n", last prime, curprime); to simply printf ("%d\n", curprime); Just this simple modification results in a considerable savings in the execution time. However, you can't reduce the number of times you call the output statement; for the given problem, there will always be 168 primes to print out. And apart from this minor 376 C++ Use r 's G u ide improvement, there is not a great deal you can do to speed up the execution of PRIMED. Its algorithm, which requires saving all the previous results in an array and then using them to divide, is thorough but virtually impossible to streamline. (It's also not very memory-efficient, because the array requires an allocation of memory equal to the number of primes being tested. Eventually this imposes a limit on the number of primes that could be tested without running out of memory.) Fortunately, there is a better way to test for prime numbers: You can change the algorithm itself. That's what happens in the next example program, PRIME1. Amodularized primes test (PRIME1) You're finished with PRIMED now, so load PRIME1 (the next version of the prime number program) into the Module window and look at the code: 1 Choose File IOpen. 2 By default, the File Name input box is activated and contains the file-name mask *.EXE. Press Enter. 3 In the Files list box, use the Up and Down keys to highlight PRIMEl.EXE. 4 Press Enter. Turbo Profiler loads PRIME1 into the Module window. 5 Zoom the Module window (press F5). Note the added prime (Prime) routine on line 4. You can see right away that two major changes have occurred: • The array primes is gone. This program does not test by dividing each number by all smaller primes; it simply uses a loop to divide by all the odd numbers up to but not including the suspected prime. Initially this algorithm results in more iterations, but we will see that it eventually can be refined into a more streamlined and readable program. • The prime number test itself has been placed in a separate routine that is called from the main program. Run PRIME1 in Turbo Profiler (press F9) and look at the statistics. Then choose Display from the Execution Profile window SpeedMenu to open the Display Options dialog box and tum on the Both radio button. Press Enter, then zoom the Execution Profile window (F5). The execution time has improved somewhat (this is due in part to the fact that PRIME1 prints out less information than PRIMEO).The main bottleneck is still the printf statement (now line 21). Notice in particular that the test for prime numbers (line 9 in PRIMED) now executes 78,022 times instead of 15,122. This may be surprising at first, but notice that it only increases execution time for this line by about 1 second; we have already seen that this statement is time-efficient. One obvious way to improve efficiency, now that we have isolated the test loop in a separate routine, is to cut down on the number of calls to the routine. There are ways of limiting the number of integers that have to be passed to the routine for testing; the more you can eliminate at the main program level, the fewer calls you have to make and C hap t e r 24, A sam pie pro f iii n 9 s e s s ion 377 the faster your program executes. That is the strategy we employ in the next sample programs. Modifying the program and reprofiling Earlier, we pointed out that instead of testing for all factors between 1 and n in the modulus statement, you can set the upper limit of the test to the square root of the number you're testing. That's what we've done in program PRIME2 (PRIME.2PA). Loading another program (PRIME2) Go ahead and load PRIME2, the next version of the sample program, into the Module window. In program PRIME2, we've added a root (Root) routine that calls a square root library routine and returns an integer result. You need to set areas for all lines in the module, so bring up the SpeedMenu in the Module window, choose Add Areas IEvery Line, then press Enter. Press F9 to start profiling. Once again, you'll see the primes between 1 and 1,000 print to the user screen. When the program finishes running, open the Display Options dialog box (choose Display from the Execution Profile SpeedMenu) and set Display to Both. Choose OK. Despite decreasing the number of calls to line 15 (from 78,022 to 5,288) and reducing the time spent in the same statement, there's still a substantial increase in overall execution time. The problem with PRIME2 is the expense of the new root routine. Line 7 inside the routine executes 5,456 times, consuming the most time of any routine. When the Execution Profile window shows both time and count information, certain patterns are worth looking for. In inefficient routines, the second line (time data) is much longer than the first line (count data), which means the ratio of time to counts is high. This is the case for line 27, the printf statement. When a routine's time:count ratio is high, the best thing to do is substitute another routine. However, the return statement in the root routine (line 7) presents a different problem. It accounts for the largest number of calls and the largest amount of time. Two other lines (line 5 and line 8) have 5,456 calls, but the magnitude bar for each of these cases shows small execution times. This is good: It means the statements are fast. So the biggest problem right now is the number of calls made to the root routine. Reducing calls to a routine (PRIME3) The problem now is to reduce the number of calls to the root routine. Load PRIME3 into the Module window, then zoom the Module window and take a look at the source code. In PRIME3, the only routine modified is prime. We've added a new integer variable, limit, and set limit equal to root(n) before entering the for loop. The test in the for loop is based on limit. 378 C++ Use r' s G u ide In the Module window SpeedMenu, set areas to Every Line in Module. When you profile the program this time (choose Run IRun or press F9), the program runs quite a bit faster. PRIME3 shows an almost 25 percent decrease in total execution time. The printf routine is now the major resource consumer, eating up over half the execution time. By reducing the number of calls to the square root routine in root (from 5,456 to 999), we've decreased computational time substantially. Still more efficiency (PRIME4) There are still more ways to increase the efficiency of the prime routine. Load PRIME4 into the Module window now, then examine lines 8 through 17 of the source code. /****** PRlME4.C ******/ if (n % 2 == 0) return (n==2)i if (n % 3 == 0) return (n==3); i f (n % 5 == 0) return (n==5); for (i=7; i*i <= n; i+=2) i f (n % i == 0) return 0; return 1; There are a number of improvements here. • The three if statements in the prime routine weed out factors that are multiples of 2, 3, and 5, respectively. If you can't throw out a number n based on one of these tests, you must test the remaining numbers, up to the root of n. You can start at the value 7-the if statements have eliminated all possibilities below this number. • The for loop now increments by two on each iteration, because there's no point in testing even numbers. • The test i * i <= n has replaced the more expensive test involving the root routine. The net result is that we've shaved nearly half a second off the execution time. Eliminating CR/LF pairs (PRIMES) Here's one last change. Instead of printing a carriage retum/linefeed pair after each prime number, try printing just a space. This is the only change made in program PRIMES. Load PRIMES, set areas for every line, then run it. C hap t e r 24, A sam pie pro f iii n 9 s e s s ion 379 Surprise! Eliminating the carriage retum/linefeed pair cuts execution time by a factor of almost 7. Apparently, printing newline characters is expensive. The distribution of profiles is fairly even for execution times and counts. We'd be hard-pressed to squeeze more out of this program without substantially changing the algorithm. Where to now? We've taken you through the basics of profiling in this tutorial. By now, you should be familiar with using Turbo Profiler: loading and profiling programs, printing the contents of various windows, saving and restoring profile statistics, and rearranging the windows so you can analyze the statistics. Go ahead and quit Turbo Profiler now (choose File IQuit, or press Alt+X). For more information about Turbo Profiler's environment, as well as details about parts of the profiler not mentioned here, refer to Chapter 25. If you want more challenges than we've given in this tutorial, try these: • Profile for primes less than • • • • 2,500 5,000 7,500 10,000 • Set the profile mode (choose Statistics IProfiling Options to bring up the Profiling Options dialog box) to Passive analysis. What does this do to profiler overhead? What kinds of information do you lose in passive analysis? (See Chapter 26, "Profiling strategies," for information on passive profiling.) • Find out what kind of performance improvement you get by implementing the Sieve of Eratosthenes to compute primes up to 10,000. • Compare the cost of printing newline characters with calls to position the cursor. Note 380 There are a number of articles on the subject of profiling, but not many books. John , Bentley's book, Writing Efficient Programs, provides a summary of rules for designing efficient code, suggests a comprehensive methodology for profiling, and contains an extensive bibliography. C++ Use r s G u ide J The Turbo Profiler environment Turbo Profiler makes it as easy and efficient as possible for you to profile your programs. When you start Turbo Profiler, everything you need is literally at your fingertips. That's what an environment is all about. The Turbo Profiler environment also boasts these extras to make program profiling smooth: • Multiple, movable, resizable windows • Mouse support for any mouse compatible with the Microsoft mouse version 6.1 or later • Dialog boxes to replace multilevel menus Part 1: The environment components There are three visible components to the integrated environment: the menu bar at the top, the window area in the middle, and the status line at the bottom. Many menu items also offer dialog boxes. Before we discuss each menu item in the environment, we'll describe these more generic components. The menu bar and menus Turbo Profiler has both global and SpeedMenus. Global menus are ones you access via the menu bar, and SpeedMenus are ones you access from within a window. The menu bar is your primary access to all the global menu commands. In addition, it displays a program activity indicator on the right side that tells, for example, whether the profiler is READY for you to do something, RUNNING your program, or WAITing while it processes a processor-intensive task. The only time the menu bar is not visible is when you're viewing your program's output in the user screen. C hap t e r 25, The T u r boP r 0 f i I ere n vir 0 n men t 381 Choosing menu commands from the keyboard Here's how to execute global menu commands using just the keyboard: Press F10. This makes the menu bar active, which means the next thing you type pertains to it, and not to any other component of the environment You see a highlighted menu title when the menu bar is active. The menu title that's highlighted is the currently selected menu. 2 Once the global menu is active, use the arrow keys to select the menu you want to display. Then press Enter. Note To cancel an action, press Esc. As a shortcut for this step, just press the initial letter of the menu title. (For example, press F to display the Files menu.) If an ellipsis (... ) follows a menu command, the command displays a dialog box when you choose it. If an arrow (~ ) follows the command, the command leads to another menu. 3 If the command opens another menu, use the arrow keys again to select the command you want. Then press Enter. Again, as a shortcut, you can just press the highlighted letter of a command to choose it, once the menu is displayed. At this point, Turbo Profiler either carries out the command, displays a dialog box, or displays another menu. SpeedMenus In addition to the global menus that you access through the menu bar, each of Turbo Profiler's windows has its own unique SpeedMenu. When you're in a window, press Alt+F10 to bring up the SpeedMenu. For more information on accessing SpeedMenus, refer to the discussion on page 389. Choosing menu commands with the mouse To use the mouse to choose commands from global menus, click the desired title on the menu bar to display the menu, then click the desired menu command. You can also drag straight from the menu title down to the menu command. Release the mouse button on the command you want. (If you change your mind, just drag off the menu; no command will be chosen.) Shortcuts Turbo Profiler offers many quick ways to choose menu commands. For example, with "a mouse you can combine the two-step process into one: Drag from the menu title down to the menu commands, then release the mouse button when the command you want is selected. 382 C++ Use r 's G u ide From the keyboard, you can use keyboard shortcuts (or hot keys) to access the menu bar and choose commands. Table 25.1 Menu hot keys etrl and the highlighted letter of the . SpeedMenu command Alt plus the highlighted letter of the menu command The highlighted letter of the dialog box component The hot key combination listed next to a menu command Carry out the SpeedMenu command Display a menu from the menu bar Execute that menu command or select that dialog box component Carry out the menu command Turbo Profiler windows Most of what you see and do in the Turbo ProfHer environment happens in a window. A window is an area of the screen that you can move, resize, ZOOID, layer, close, and open. You can have many windows open in Turbo ProfHer (memory allowing), but only one window can be active at any time. Any command you choose or text you type applies only to the active window. Note The active window is the one that you're currently working in. Turbo Pro filer makes it easy to spot the active window by placing a double-lined border around it. The active window always has a close box. If your windows are overlapping, the active window is the one on top of all the others (the frontmost one). There are several types of windows. Most of them have these things: a title bar, a close box, two scroll bars, a resize corner, a zoom box, an iconize box, and a window number (1 to 9). Window management Some windows are divided into two or more panes for displaying different kinds of information. Individual panes often have their own SpeedMenu. The following table provides a qUick rundown of how to handle windows in Turbo ProfHer. You can perform these actions with a mouse or the keyboard. Table 25.2 Manipulating windows Open a window Close a window Choose View to open aprofiler window that's not already open. Choose Close from the Window menu or press AIt+F3 or, if active, click the window's close box. Chapter 25, The Turbo Profiler environment 383 Table 25.2 Manipulating windows (continued) Activate a window View the windows contents Move the active window Resize the active window Zoom the active window Iconize the active window Move from pane to pane Click anywhere in the window, or Press Alt plus the window number (1 to 9, in the upper right border of the window), or Choose Window and select the window from the list at the bottom of the menu, or Choose Next from the Window menu (or press F6) to make the next window active (next in the order you first opened them). Use cursor keys to scroll the window up and down or left and right, or Use the mouse to operate the scroll bars: • Click the direction arrows at the ends of the bar to move one line or one character in the indicated direction. • Click the area in the middle of the bar to move one window size in the indicated direction. • Drag the scroll box to move as much as you want in the direction you want. Drag its title bar or any left border character that isn't a scroll bar, close box, or zoom or iconize box, or Choose Size/Move from the Window menu (or press Ctr/+F5), use the arrow keys to place the window where you want it, then press Enter. Drag the resize comer, or Choose Size/Move from the Window menu (or press Ctrl+F5), press Shift+Arrowto change the size of the window, then press Enter, or Drag any part of the right or bottom border that isn't a scroll bar to resize the window. Click the zoom box, or Double-click the window's title bar, or Choose Zoom from the Window menu, or press F5. Click the iconize box, or Choose Iconize/Restore from the Window menu. When a window is fully zoomed, it has only an unzoom box.([t]) When it is iconized, it has only a zoom box (t). In its restored state, it has both an up and a down arrow. Press Tab, Shift+ Tab, or Shift+Arrow, or Choose Window INext Pane. The status line The status line at the bottom of the Turbo Profiler screen provides the following information: • It reminds you of basic keystrokes and shortcuts applicable at that moment in the active window. (You will see that the status bar changes if you hold down Alt or Ctrl.) • It provides onscreen shortcuts you can click to carry out the action (instead of choosing the command from the menu or pressing the hot key on the keyboard). • It offers one-line information on any selected menu command or dialog box item. The status line changes as you switch windows or activities. You can click any of the shortcuts to carry out the command. 384 c++ User's Guide The only time the status line is unavailable is when a dialog box or menu is open. You must close the dialog box or menu before doing anything else. When you've selected a menu command, the status line changes to display a one-line summary of the routine of the selected item. For example, if the Options menu title is selected (highlighted), the status line displays the currently selected item in the Options menu. Dialog boxes If a menu command has an ellipsis after it (... ), the command opens a dialog box. A dialog box is a convenient way to view and set multiple options. When you're making settings in dialog boxes, you work with six basic types of controls: radio buttons, check boxes, action buttons, text boxes, list boxes, and standard buttons. If you have a color monitor, Turbo Profiler uses different colors for various elements of the dialog box. . Part 2: The menu reference This section gives you an item-by-item description of each menu command and dialog box option in the Turbo Profiler environment. == menu (System) The == menu (called the System menu) appears on the far left of the menu bar. To activate the == menu, either press Alt+Spacebar, or press F10, then use Right or Left to go to the == symbol and press Enter. With the commands in the == menu, you can • Repaint the screen • Restore your original window configuration • Activate the Turbo Profiler information box Repaint Desktop Choose Repaint Desktop when you want Turbo Profiler to redraw the screen. You might need to do this, for example, if a memory-resident program has left stray characters on the screen, or possibly if you have display swapping turned off. Restore Standard When you start up Turbo Profiler, it sets the environment windows' size, window status (open or closed), and placement according to information stored in the configuration file TFCONFIG.TF. Once Turbo Profiler is onscreen, you can move and resize the windows, close some and open others, and generally make a real mess of your screen. The Restore Standard command provides a quick way to rectify such a situation. Chapter 25, The Turbo Profiler environment 385 When you choose Restore Standard, Turbo Profiler puts all the windows back the way they were when you first started the profiler. About When you choose About from the == menu, the About box pops up. This box lists the Turbo Profiler version number. Press Enter or choose OK to close the box. File menu The File menu contains commands for • • • • • Opening and loading a program to be profiled Changing the current directory Obtaining information about your program and system memory allocation Opening up a DOS shell Quitting the profiler Open The File IOpen command, used to load an explicit file into the Module window, opens a two-tiered set of dialog boxes. The first is the Load a New Program to Profile dialog box. Figure 25.1 The Load A New Program to Profile dialog box TRPOF.EXE's Load a New Program to Debug dialog box contains an additional button, Session, to support its remote profiling feature. For more information on remote profiling, and the Session button, see Chapter 30, "Remote profiling." If you know the name of the program you want to load, enter the executable name into the Program Name input box and press Enter. To search through directories for your program, click the Browse button to open the second dialog box (the Enter Program Name to Load dialog box): Figure 25.2 The Enter Program Name to Load dialog box 386 c++ User's Guide The Files list box displays the files in the currently selected directory. By entering a file mask into the File Name input box (such as *.EXE), you can specify which files should be listed. You can also use the File Name input box to change disk drives. To "walk" through disk directories,double-click the entries listed in the Directories list box (the .. entry steps you back one directory level). Once you've selected a directory, choose a file to load from the Files list box. To quickly search for a file, type a file name into the Files list box. Turbo Profiler's incremental matching feature moves the highlight bar to the file that begins with the letters you type. Once you've selected a file, press OK. This action returns you to the Load a New Program to Profile dialog box. To support remote debugging, TPROF.EXE contains buttons in the Load a New Program to Profile dialog box. The Session radio buttons specify whether or not the program you're debugging is on a local or remote system. If it's located on a remote system, select the Remote Windows radio button; if it's not on a remote system, select Local. See Chapter 29, "Customizing the Turbo Profiler," for complete instructions on remote debugging. Note Before loading a program into the profiler, be sure to compile your source code into an executable file (.EXE or .DLL) with full debugging information. Although you can load programs that don't have debug information, you will not be able to use the Module window to view the program's source code. (The profiler cannot reference the source code of executable modules that lack debug information. If you load a module that doesn't contain debug information, Turbo Profiler opens the Disassembly window to show the disassembled machine instructions of that module.) When you run a program under the control of Turbo Profiler, the program's executable files (including all.DLL files) and original source files must be available. In addition, all .EXE and .DLL files for the application must be located in the same directory. Session Saving When you exit Turbo Profiler, it saves to the current directory a session-state file that contains information about the profiling session you're leaving. When you reload your program from that directory, Turbo Profiler restores the history lists from the last profiling session. By default, all history lists are saved to the session-state file. Session-state files are named XXXX.TP and XXXX.TPW by TPROF.EXE and TPROFW.EXE, respectively, where XXXX is the name of the program you're profiling. If no program is loaded when you exit Turbo Profiler, then XXXX is named either TPROF or TPROFW. The Options ISet Restart Options command opens the Restart Options dialog box, from where you can set how Turbo Profiler handles the session-state files. In this dialog box, the Restore at Restart check box specifies whether you want to save the profiler's history lists. The Use Restart Info radio buttons specify how you want to handle the file: Table 25.3 Alway~ Ignore if old Turbo Profile session-state saving options Always use the session-state file. Don't use the session-state file if you've recompiled your program. C hap t e r 25, The T u r boP r 0 f i I ere n vir 0 n men t 387 Table 25.3 Turbo Profile session-state saving options (continued) Prompt if old Never Prompts if you want to use the session-state file if you've recompiled your program. Do not use the session-state file. Get Info The File I Get Info command displays a text box with information about the program being profiled and your system's current memory configuration. Information in the Get Info box is for display only; you can't change any settings from this box. Here's what the categories in this information box represent: • Program is the program being profiled; you determine which file to profile with the File I Open command. • Status describes how Turbo Profiler gained control: it can be anyone of the following messages: Loaded Control-Break Terminated, exit code XX Stopped by area NMI Interrupt Exception XX Divide by zero No program loaded • Mode is the profiling mode (active, passive, or coverage); you specify the profiling mode with the Profile Mode radio button in the Profiling Options dialog box· (accessed by choosing Statistics I Profiling Options). • Collection tells whether automatic data collection is enabled or disabled; you specify the data-collection setting with the Statistics I Accumulation command. • Memory shows the use of memory: • DOS: Memory occupied by DOS and/ or various device drivers • Profiler: Total memory used by the profiler • Symbols: Memory allocated for the program's symbol table 1& Program: Memory allocated to the current program being profiled • Available: Amount of remaining available memory 1& DOS version shows the current DOS version on your system. 1& Current date and time is taken from the system clock. After reviewing the information in the Get Info box, click OK or press Enter to return to the current window. DOS Shell The File I DOS Shell command steps you out of Turbo Profiler and into a DOS shell. To return to Turbo Profiler, type EXIT at the DOS prompt. 388 C++ User's Guide Note In remote profiling mode, the DOS command line appears on the Turbo Profiler screen rather than on the user screen; this allows you to switch to DOS without disturbing your program's output. Because your program's output is always available on one screen in the system, Window IUser Screen and Alt+FS are disabled during remote profiling. (See Chapter 30 for details about remote profiling.) Quit @D@ The File IQuit command exits Turbo Profiler, removes it from memory, and returns to the DOS command line. If you have any profile data or setup parameters that you want to keep (such as the profile statistics, profiling and display options, and screen layout options), save them with the Statistics ISave and Options ISave commands before exiting. If you don't, you'll lose the options you've set. Note Each time you exit Turbo Profiler, it remembers the areas you set up for the current program by saving the settings in a .TFA file. Then, the next time the program is loaded, the area settings are automatically put into effect. .View menu The View menu lets you open several kinds of windows in which you can examine information about your program's performance. Table 25.4 Summary of Turbo Protiler windows Module Execution Profile Source code for the program being profiled Callers Overlays Information about how often a routine is called and which routines call it Information about overlays for Borland's line of Pascal compilers, Borland's C and C++ compilers, and Turbo Assembler Interrupts Information about interrupt calls made by the program Statistical information about a program after the program has run Files Information about file activity Areas Routines Detailed information about data-collection activities at the places marked in your source code' All routines that can be used as profile area markers Disassembly Text File Contents of any text file you specify Coverage In its default setting, lists the code blocks which havef\'t yet been executed The current profile area in the Module window, as disassembled source code SpeedMenus Each Profiler window has its own SpeedMenu (actually, some windows have more than one SpeedMenu, depending on the number of panes in the window). A SpeedMenu contains commands and settings specific to the window pane. To activate a SpeedMenu, press Alt+F10 (if there is more than one window pane, press Tab to alternate between the panes). When the SpeedMenu pops up, use the arrow keys to select the command you want and press Enter, or press the highlighted letter. Once Chapter 25, The Turbo Profiler environment 389 you choose a SpeedMenu command, Turbo Profiler either carries it out, displays a dialog box, or displays another menu. To activate a SpeedMenu item directly from the window (without bringing up the SpeedMenu), press the Ctrl+{letter) hot key, where letter is the menu item's highlighted . letter. To pop up the active menu's SpeedMenu using a mouse, click the mouse's right button. Then, select the command you want by clicking on the menu item. Module The Module window displays source code for the program being profiled. In the Module window, you can examine code and set areas to be profiled. Special hot keys and window links connect the code in this window to data and statistics in other windows. When you choose View IModule, a list box appears that lists all the source modules linked with the program currently loaded into the Module window. Highlight the new module you want to display, and press OK to load it into the Module window. If the Modified appears in the title bar of the Module window, it indicates that the source code to the file you're viewing has changes since the program was last compiled. Figure 25.3 The Module window (zoomed) When you run the profiler, both the .EXE file and the original source file must be available. Turbo Profiler looks for your program's source code in these places, in this order: In the directory where the program was originally compiled. The name of the directory where the program was originally compiled is contained in .EXE and .OBJ files if you compiled your program with symbolic debugging information. 2 In the directories (if any) you've listed under Options IPath for Source (or stated in the command-line option using the -sd switch). 3 In the current directory. 4 In the directory that contains the .EXE file of the program you're profiling. 390 C++ Use r 's G u ide Press Alt+F10 or click the right mouse button to bring up the Module window's SpeedMenu. With the SpeedMenu commands, you can perform these actions: • Move the cursor to a specific line or code label. • Search for text in the source code. • Add and remove profile areas. • Set the profiling acti~n that will occur for a given area. • Specify the level of call-path recording for a given routine. • Load another module or another source file of the current module into the Module window. • Invoke the editor specified when you run TFINST. Line I9illUJ To move swiftly to a particular line of code in the Module window, choose Line from the SpeedMenu. The dialog box that pops up requests the line number you seek; type in the new line number, then choose OK (or press Enter). If you enter a line number after the last line in the file, you will be positioned at the last line in the file. I9illlID To search for a character string in the current module, choose Search. The prompt box that pops up requests the string to search for; type in the string, then choose OK (or press Enter). Search If the cursor is positioned over text that looks like a variable name, the prompt box comes up initialized to that name. If you mark a block in the file, the profiler uses that block to initialize the search prompt. This saves you from extraneous typing if the text you want to search for is a string already in the Module window. You can use the standard DOS wildcards (? and *): The ? indicates a match on any single character, and the * matches 0 or more characters. The search begins from the current cursor position and does not wrap around from the end of the file to the beginning. To search the entire file, start at the first line. Next 19i1l@ Once you've defined a search string with the Module window's local Search command, you can search for successive occurrences of that string with the Next command. Choose Next from the SpeedMenu, or press the shortcut, Ctrl+N. You can use Next only after issuing a Search command. 19i1l@ To position the Module window's cursor on a particular routine or other code label in your program's source code, choose Goto. The prompt box that pops up requests the address you want to examine. Type in a line number, a routine name, or a hex address, then choose OK (or press Enter). Gata Note Use the hex format of your program language. C hap t e r 2 5, The T u r boP r 0 f i I ere n vir 0 n men t 391 Add Areas 19i1l@ Add Areas on the Module window's SpeedMenu leads to·another menu. • All Routines adds area markers for all routines in the program being profiled, including routines for which source code is unavailable (such as library routines linked in as object modules). • Modules with Source adds area markers for all routines in modules whose source code is available. • Routines in Module adds area markers for all routines in the current module (the one in the Module window). • Every Line in Module adds area markers for all lines inthe current module. • Lines in Routine adds area markers for all lines in the current routine (whichever routine the cursor is on in the Module window). • Current Routine adds an area marker for whichever routine the cursor is on in the Module window. • This Line adds an area marker for the line the cursor is on in the Module window. Remove Areas 19i1llB) Choosing Remove Areas on the Module window's SpeedMenu displays another menu. This menu is almost identical to the Add Areas menu just described. Except for the All Areas command, which removes all markers, each command on the Remove Areas menu erases area markers the same way as the respective Add Areas command adds area markers. Operation 19i1l(Q) The Operation command opens the Area Options dialog box, which contains settings for the area marker on the current line in the Module window. Figure 25.4 The Area Options dialog box You can specify two options with the radio buttons in this dialog box: Operation and Timing. In addition, the Window Procedure check box enables message tracking for Windows programs. ' • Operation specifies what profiling action will occur for the current area. Window Procedure, when checked, specifies that the current area marks a procedure specific to Windows. When you mark an area, a marker symbol signifying the chosen operation appears to the left of that area in the Module window. A different symbol is used to refer to each type of area marker: A Normal area is marked with =~, a Stop area is marked with s~, an Enable area is marked with e~, and a Disable area is marked with d~. 392 C++ Use r 's G u ide .. Normal collects profile statistics for this area as specified in the Statistics menu (callers, file activity, interrupts, overlays, and so on) and Area Options dialog box, which you reach through the SpeedMenus of the Module and Areas windows . .. Stop stops program execution at this marker. .. Enable turns on the collection of statistics at this point in the program. CIt Disable temporarily turns off the collection of statistics at this point in the program. Data collection resumes once program control passes an Enable marker. Note Coverage mode provides only one type of area marker, denoted by a single> character. The marker indicates that the block has not been executed. • Messages becomes active when the Window Procedure check box is checked. Choosing Messages displays the Window Procedure Messages dialog box. • Timing specifies whether the profiler will add the current area's execution time to a higher-level area or keep it separate. .. Separate adds any timer ticks in the current routine to that routine's statistics. . .. Combined sums the timer ticks of the marked routine with the timer ticks of all the children of that routine. You can specify combined time for an area only if that area's Callers setting is Immediate or All. VVhen you set a routine's Timing to Combined, Turbo Profiler does not display timing statistics for the children of that routine-their times are reported as part of the routine whose timing is set to Combined. The following illustration shows how Combined timing works: In this illustration, the routine FI has its Timing set to Combined. Turbo Profiler collects the timing information for all the routines (FI, F2, F3, and F4), and sums them into the timing information collected for the routine Fl. Callers ©!ill© The Callers command on the SpeedMenu leads to the Stack Trace dialog box. Figure 25.5 The Stack Trace dialog box C hap t e r 2 5, The T u r boP r 0 f i I ere n vir 0 n men t 393 You specify how callers are handled with two sets of radio buttons, Areas and Stack. • Areas specifies which areas you want call paths recorded for. • This Routine sets only the current routine (the one the cursor is on in the Module window) to the setting specified in Stack. • This Module sets all routines in the current module to the setting specified in Stack. • All Routines sets all routines in all program modules to the option specified in Stack. • Stack specifies how extensive ("deep") the recorded call stack should be. e All Callers records all available call stack information for the routine(s) you've specified with the Areas option. • Immediate Caller records only "parent" information for the routine(s) you've specified with the Areas option. • None turns off call stack information for the routine(s) you've specified with the Areas option. When OK is selected from the Stack Trace dialog box, the areas specified by the Areas options are set according to the selected Stack option. Changes made in this dialog box are reflected in the Areas window. Module r£0)(M) The Module command on the SpeedMenu leads to the Pick a. Module dialog box that lists all your program's modules for which source code is available. Most modules have only a single source code file; other files included in a module (such as C header files) usually define only constants and data structures. Use this command to open a different module in the Module window. This option displays only the file names for the source code modules that are associated with the program being profiled. It allows you to move rapidly from one module to another without having to search your source directory explicitly. The Module command searches for the source code in the following places, in the order listed: In the directory where the program was originally compiled. 2 In the directories (if any) you've listed under Options I Path for Source (or stated in the command-line option using the -sd switch). 3 In the current directory. 4 In the directory that contains the .EXE file of the program you're profiling. File r£0)[£) 394 The File command on the Module SpeedMenu leads to a dialog box that lists all the source files used to compile the current module. Use this command if your module has source code in more than one file and the file you want is not displayed in the module window. C++ Use r 's G u ide The File command searches for the source code in the same order as the Module command in the previous section. Edit command rQ!ill~ Although Turbo Profiler does not have a built-in editor, you can specify your own favorite editor as an option when you customize the profiler with the Turbo Profiler installation program, TFINST. See Chapter 29 for information about TFINST. Once you've installed an editor using TFINST, whenever you choose Edit from the Module window's SpeedMenu, Turbo Profiler automatically shells out to DOS and invokes your editor. To return to the profiler from your editor, simply quit the editor. Execution Profile The Execution Profile window is where Turbo Profiler displays your program's profile statistics (after you've set areas and run the program under control of the profiler). The Execution Profile window consists of one pane, divided into two display areas (top and bottom). The top display area lists • Total Time: your program's total execution time. • % of Total: how much of that total (a percentage) is represented by the statistics for the areas you've chosen. • Runs: the current profile run (if you're collecting and averaging statistics from more than one run). • The options you've chosen from the SpeedMenu (display format, filter status, and sort order). • Total Ticks: the total number of timer ticks which occurred during the program run. Timer Ticks displays only during passive mode profiling. The·bottom display area lists one or two lines of profile data for each area you've marked. The information shown in this display area can include each area's name or line number, the execution counts for each marked area, the time spent in each marked area, the average time per pass for each marked area, and the most time spent in a marked area on a single pass. If you have a Module window and an Execution Profile window onscreen at the same time, the Execution Profile window is positioned automatically to show the statistics for the area the cursor is on in the Module window. To specify how the Execution Profile window displays your program's statistics, activate the SpeedMenu (press Alt+F10). Through this SpeedMenu, you can • Select what type of modules will be profiled: Window procedures or normal areas. • Choose anyone of six different ways to display profile statistics in the Execution Profile window. • Sort the displayed statistics. • Temporarily remove one or more areas' statistics from the display. C hap t e r 2 5, The T u r boP r 0 f i I ere n vir 0 n men t 395 • Examine the source code for an area. • Delete an area's statistics from memory and erase the associated area marker. Display r9ill@ When you choose Display from the Execution Profile window's SpeedMenu, the Display Options dialog box comes up. Figure 25.6 The Display Options dialog box You can specify three options with the radio buttons in this dialog box: Profile, Display, and Sort. • Profile specifies which areas are displayed in the Execution Profile window. • Normal Areas displays all marked areas, including any Window procedures that are marked. • Window Procs filters the displayed areas to show only the classes and Windows messages that are specified in the Windows Procedure Messages dialog box. See Chapter 31 for a complete description of the Windows Procedure Messages dialog box. • Display specifies what form the data will be displayed in. • Time displays the profile statistics for each area as the time (in milliseconds) program control was in that area. • Counts displays profile statistics for each area as pass counts: how many times program control entered that area. • Both displays the statistics for each area as both time (the top line) and counts. This provides a graphic measure of a routine's efficiency. • Per Call displays each area's statistics as the Time:Counts ratio. This provides the average time spent in each call to the routine. • Longest displays, for each area, the longest single time program control was in that area. • Module displays, for each module in the program, the time program control was in that module. This setting is useful only if Turbo Profiler is in passive mode, which means it's recording with every clock tick which module the program is in. This option is helpful as a first cut at profiling a large program. • Sort specifies what order the data will be sorted in. • Name sorts the profile statistics by area name, in alphanumeric order. • Address sorts profile statistics by memory location, starting with the lowest address. ' • Frequency sorts the statistics numerically, with the highest frequency at the top. 396 C++ Use r 's Gu ide The top display area of the Execution Profile window lists the current display and sort options. Filter (Q0)(E) The Filter command on the SpeedMenu leads to the three-item menu shown here. • All restores all collected statistics for the current program to the Execution Profile window. After you've filtered out certain statistics from the Execution Profile window (with Filter IModule or Filter ICurrent), choose Filter IAll to restore all profile statistics to the window. • Module filters out all but one module's statistics. This command leads to the Pick a Module dialog box, which lists all modules for the current program. Use the Up and Down arrow keys to highlight one module in the list, then press Enter. Only the areas in the chosen module show up in the Execution Profile window. • Current temporarily removes the highlighted area's statistics from the Execution Profile window. Choose Filter ICurrent if you want to throw out one area's statistics and see what happens to the remaining percentages. The Current command is a temporary filter that hides report information from sight without deleting any information; it does the following: Removes the current area's statistics from the Execution Profile window. 2 Calculates original total execution time minus the time of the removed area. S Recalculates the remaining areas' percentages as fractions of the newly calculated total execution time. When you filter one or more areas' statistics from the Execution Profile window, the profiler calculates a new total execution time based on the statistics displayed in the window, but the Total Time value shown in the top of the window does not change. When you use Filter ICurrent, the original total execution time for the entire program remains displayed in the Execution Profile window's top display area. Filter ICurrent is a temporary filter that hides report information from sight; Remove actually affects area marker settings by removing them in both the Module and Areas windows. Note Don't confuse Filter ICurrent with the Remove command on the Execution Profile window's SpeedMenu. Module (Q0)(M) The Module command on the SpeedMenu takes you to the line of source code in the Module window for which the statistics are highlighted in the Execution Profile Window. Note that in addition to the Ctrl+Mhot key, you can press Enter from the Execution Profile window to execute the same command. C hap t e r 2 5, The T u r boP r 0 f i I ere n vir 0 n men t 397 Suppose you highlight the statistics for routine frank in the Execution Profile window, then choose Module from the SpeedMenu to activate the link. Turbo Profiler activates the Module window and places the cursor on the first line of frank in the source code. After that, you move the cursor to line 25 in the Module window (line 25 has an area marker). Automatically, the Execution Profile window's contents scroll so that the statistics for line 25 show at the top of the statistics display area. The link is unidirectional: If you go back to the Execution Profile window (after going to the Module window) and move the highlight bar, the source code in the Module window does not scroll or track the highlight bar's position. (If it did, you could get very frustrated. ) If, when you choose the Module command, source code for the highlighted line is unavailable, the link goes to the corresponding line of code in the Disassembly (CPU) window. This happens, for example, if you've marked areas for All Routines and the highlighted line is a library routine. (See page 409 for details about the Disassembly window.) Position @ill(£) The Position command is identical to the Module command, with the exception that the Position command does not activate the Module window; the Execution Profile window remains active. Another shortcut for this command is the. Spacebar. @ill® The Remove command removes area marker settings from the currently highlighted line in the Execution Profile window. Remove Warning The Remove command erases statistical data. Use it with discretion. Once you remove the line's area markers with the Remove command, the statistics you had gathered for that line are erased and no more statistics are gathered for that line of code. To undo a Remove action, you must 1 Activate the Module window and bring up its SpeedMenu. 2 Place the cursor on the line whose marker you removed. 3 Choose Add Areas IThis Line. 4 Run the program again (collecting a new set of statistics). Callers The Callers window is where Turbo Profiler displays the call paths for each marked routine in your program. A call path is a list of all the routines that were called to execute the currently selected routine. The call path starts with the original calling routine. You must set the Statistics ICallers menu item to Enabled before the profiler will record any call-path information. 398 G+ + Use r 's G u ide Figure 25.7 The Callers window, showing calls in CALLTEST The left pane in the Callers window lists each marked routine by name. When you highlight a routine name in the left pane, the right pane displays each unique call path for that routine. If a call path is wider than the right pane, you can zoom the window or switch to the right pane and scroll left and right through the path. Note An underscore precedes the identifier names in this Callers window because Borland's C and C++ compilers add the underscore to all symbol names appearing in .OBI files and symbolic debugging information. Although the Callers window displays the call-path information, you must specify what type of call path recording you want. This is done through either the Module window or the Areas window. In the Module window, you can set callers options for whole groups of routines. With the cursor on a marked routine in the Module window, press Alt+F10 to bring up the SpeedMenu. 2 Choose Callers to see the Stack Trace dialog box. 3 Set the Areas option. You can choose to record call paths for the current routine, all routines in the current module, or all routines in the program (including library routines). 4 Set the Stack option. You can choose to record all callers for the chosen routine(s), immediate callers (the routines' parents only), or no callers at all. 5 Press Enter or choose OK to go back to the Module window. In the Areas window, you can set callers options for individual marked routines. (See page 405 for more information about the Areas window.) In the Areas window, place the highlight bar on the routine you want to set call-path options for, then press Alt+F10 to bring up the SpeedMenu. 2 Choose Options to see the Area Options dialog box. 3 Set the Callers option. You can choose to record all callers for the chosen routine(s), immediate callers (the routines' parents only), or no callers at all. 4 Press Enter or choose OK to go back to the Areas window. Figure 25.7 shows routine c highlighted in the left pane of the Callers window, after a profile run of this program, CALLTEST: /* Program CALLTEST */ /* Copyright (c) 1990, Borland International */ #include main() C hap t e r 2 5, The T u r boP r 0 f i I ere n vir 0 n men t 399 c(); b2() ; bl() ; a(); a() { int i; for (i = 0; i < 100; i++) b2 (); bl() ; bl () { int i; for (i c(); 0; i < 33; i++) b2 () { int i; for (i c(); = 0; i < 77; i++) . c() { int i; for (i = 0; i < 3; i++) The Callers window's right pane lists each unique call path for routine c: • • • • • 1 call from main to c 77 calls from main to b2 to c 33 calls from main to bi to c 7,700 calls from main to a to b2 to c 33 calls from main to a to b I to c You'll find the Callers window useful when you must make decisions about restructuring code, especially when it's possible to reach a routine through several different call paths. 400 c++ User's Guide Both panes of the Callers window have SpeedMenus. In the Callers window's right pane, the Inspect SpeedMenu item brings up a subsequent menu containing the commands areas, module, and profile. Inspect (left pane) ©.liDOJ When the highlight bar is on a routine name in the left pane, choose Inspect (or press its shortcut, Ctrl+O to view the source code for that routine in the Module window. ©.liDOJ When the highlight bar is on a call path in the right pane of the Callers window, you can "inspect" (view information about) elements in that call path in one of three other windows. Inspect (right pane) Choose Inspect to bring up a list of those other windows. 2 Choose the window you're interested in (Areas, Module, or Profile) from the list. This brings up the Pick a Caller dialog box, which lists all callers on the current call path. 3 In the dialog box, highlight the caller in question (use the arrow keys or a mouse click), then choose OK or press Enter. If the window you choose to inspect isn't already open, the profiler opens it automatically, then goes to the caller's location in that window. Sort (right pane) ©.liD® With the local Sort command in the Callers window's right pane, you can sort the list of call paths in two ways: • Called sorts the call paths in the same order that program control traversed them at run time. • Frequency sorts the call paths by how often program control traversed each path, with the most-used path at the top of the list. Overlays The Overlays window is where Turbo Profiler displays information about overlay activity for Borland/s Pascal compilers, Borland's C and C++ compilers, and Turbo Assembler programs. You must set the Statistics IOverlays menu item to Enabled before the profiler will record any overlay information (if your program has overlays, Turbo Profiler automatically enables the Overlay option). Figure 25.8 The Overlays window The information listed in this window can include: • How many times your program loads each overlay into memory. • When each overlay was loade0-. Chapter 25, The Turbo Profiler environment 401 • The sequence in which your program loads the overlays. • The size of the overlay Like the 'Execution Profile window, the Overlays window is divided into two display areas, top and bottom. The top display area lists total execution time for your program and the current display option for overlay statistics. The bottom display area lists the overlay statistics as either a histogram or a list of events. Note Press any key to halt the execution of the program OVRDEMO. If you have one qf Borland's Pascal compilers, there's a program, OVRDEMO, that gives a live demonstration of how the Overlays window works~ Load this program into the profiler. Then set area markers for every line in the module OVRDEMO, enable Statistics IOverlays, and run the program. (You'll need the files OVRDEMO.PAS, OVRDEMOl.PAS, OVRDEM02.PAS, and OVRDEMO.EXE to profile this program.) The Overlays window's SpeedMenu provides two commands, shown here. Display rQ!ill[Q) Display specifies how the data will appear; you toggle between Count and History by pressing Enter. Count produces a histogram that shows, for each overlay, how much memory that overlay consumes and how many times your program loaded the overlay into memory. History lists your program's overlay activity as a sequence of events; each line names the overlay and specifies when, in the course of program events, that overlay was loaded. Inspect rQ!illOJ Inspect goes automatically to the Module window (opening it, if necessary) and places the cursor on the source code for the highlighted overlay. Interrupts The Interrupts window is where Turbo Profiler displays information about the video, disk, keyboard, DOS, and mouse interrupt events in your program. The Statistics I Interrupts menu item must be Enabled before the profiler will record any interrupt-call information. Figure 25.9 The Interrupts window The Interrupts window is divided into three panes: top left, top right, and bottom. 402 c++ User's Guide • The top left pane displays the list of specific interrupts to be profiled (by INT number and name). • The top right pane lists information about the display mode and the current interrupt (the one highlighted in the top left pane), number of calls, and execution time. You cannot tab to the top right pane; it only displays information. • In the bottom pane, you see a profile of data for each interrupt, shown as a histogram or as start time and duration. Each entry in the bottom pane of the Interrupt window can list • The interrupt by name or !NT number (or both) • The number of calls to that interrupt (as an absolute number and as a percentage) • The total amount of execution time spent in that interrupt (as an absolute number and as a percentage) Both active panes of the Interrupts window have SpeedMenus. Collection (top pane) rQli])@ The Collection, command enables or disables collection of statistics for the current interrupt (the one highlighted in the left display area of the top pane). rQli])(§) The Subfunctions command enables or disables collection of statistics for sub functions of the current interrupt (this is particularly useful for DOS INT 21H calls). Subfunction numbers are determined from the value in the AH register when the interrupt is called. rQli])@ The Add command adds an interrupt, by number, to the list in the pane's left display area. Type the interrupt number in hexadecimal notation. For example, type 21 for INT 21H (if you type 33, Turbo Profiler adds INT 33H to the list). rQli])CE) The Pick command displays a predetermined list of interrupts, so you can pick one to add to the list in the left display area. rQli])(ffi The Remove command removes the current highlighted interrupt from the list in the pane's left display area. rQli])@ The Delete All command removes all the listed interrupts in the pane's left display area. Subfunctions (top pane) Add (top pane) Pick (top pane) Remove (top pane) Delete All (top pane) Chapter 25, The Turbo Profiler environment 403 Display (bottom pane) 19i1l@ The Interrupt window's bottom pane has a one-item SpeedMenu; its command, Display, leads to a subsequent menu. From this second menu, you can choose to display interrupt statistics in one of four different formats, as shown in Table 25.5: Table 25.5 Summary of interrupt statistic formats Time Calls Both Time and Calls Events Displays the amount of time spent in each interrupt and its subfunctions. Displays the number of tiffies each interrupt and its subfunctions were called. Displays both the amount of time and the number of times that each interrupt and its subfunctions were called. Displays a time-ordered list of interrupt calls. Files The Files window is where Turbo Profiler displays information about file activity that occurred during your program's run. For Turbo Profiler to record any file-activity information (such as read, write, open, or close), Statistics IFiles must be set to Enabled. Figure 25.10 The Files window The Files window is divided into three panes: top left, top right, and bottom. The top left pane lists files by name, including STDIN and STDOUT. As you move the highlight bar over the file name you're interested in, the top right pane shows, for that file, • • • • • • • • The handle number The time the file was opened How long the file was open The time required to open the file The number of reads and writes from and to the file The total number of bytes read and written The time for all reads from and writes to the file The time required to close the file The top right pane only displays information. You can't tab to it, and it does not have a SpeedMenu. The lower pane displays file activity statistics (reads, writes, opens, and closes) as individual entries, rather than as statistical totals associated with a single file-name entry. Each entry provides information about a given file activity. 404 c++ User's Guide Both active panes of the Files window have SpeedMenus. Collection (top pane) 19.ill© The Collection command enables or disables the collection of file activity statistics for the current file (the one highlighted in the left display area of the top pane). Each entry in the bottom pane of the Files window provides information about a given file activity. Detail (top pane) 19.ill@ The Detail command enables or disables the collection of a detailed listing of file-activity statistics. A detailed listing logs each file read and write separately, the time it occurred (calculated from the from the program start), and the number of bytes transferred. When Detail is disabled, only file open and close activities are logged; reads and writes are summarized. 19.ill&YJ The When Full command specifies what happens when the memory set aside for fileactivity statistics fills up. When Full (top pane) Wrap means that the newest file-activity statistics will overwrite the oldest ones when the memory area fills up. Stop means that file-activity statistics gathering will stop when the memory area fills up. Display (bottom pane) 19.ill@ In the Files window's bottom pane, you can choose one menu item, Display, which leads to the Display Options dialog box. You can specify two options with the radio buttons in this dialog box: Display and Sort. • Display specifies how you want file-activity statistics to appear in the bottom pane. e Graph displays each activity's total time as a bar graph. III Detail displays each activity's exact time in seconds. Both options display the execution time in seconds; however, Graph also graphs the display and Details tells when, in the course of program execution, the .file activity took place. • Sort specifies the order in which Turbo Profiler sorts the displayed statistics. • Start Time sorts the files' statistics by sequential order of occurrence. • Duration sorts the files' statistics by how long the open, read, write, or close operation took. Areas The Areas window is where Turbo Profiler displays detailed information about your program's marked profile areas. The Areas window is used to inspect areas that have been set arid to adjust the behavior of individual areas. Chapter 25, The Turbo Profiler environment 405 Figure 25.11 The Areas window By default, the Areas window lists each area in alphabetical order. For typical programs, these areas are designated by the names of the routines to which they correspond. However, if you mark each line in a routine, the area name is (generically) ModName#Fi1 eName#NN where ModName is the module name, FileName is the file name, and NN is the line number. If you mark a line associated with a label (for example, a routine name), the profiler uses the label as the area name. Note The file name appears only if the module is made up of more than one file. The Areas window shows the following information associated with each marked area: • Start: starting address in hexadecimal. • Length: length in bytes, as a hexadecimal number. • Clock: whether the area uses a separate or combined clock in timing descendent areas. : • Action: the area operation (what Turbo Profiler should do when it passes the marker). • Callers: whether the profiler tracks the area's immediate caller only, all callers, or no callers. • Winproc: "Yes"· if the area is a Windows procedure, otherwise it is blank. This column is pertinent only if a Windows program is being profiled with TPROFW, or with TPROF acting a~ a remote Windows profiler. The Areas window is more than a source window for static display of information. With the SpeedMenu, you can • • • • Add or remove areas Inspect areas Change options for individual areas Sort the displayed information Add Areas ©lill@ Choose Add Areas to add area markers. When selected, this command leads to another menu that contains the commands All Routines, Module, and Routine. • All Routines places markers at each routine in the current module. • Module leads to the Pick a Module dialog box. This command lets you place markers in a program module other than the one present in the Module window. 406 c++ User's Guide For more information on the Pick a Module dialog box, refer to the "Module" section on page 394. • Routine, when selected, leads to the Enter Routine Name to Add text box. Type the name of the routine that you want to select, and choose OK. Remove Areas 1Q!ill(B) Remove Areas is used to erase markers that have been set. .• All Areas removes the markers from all areas in the program, including the modules not currently displayed in the Module window. • Module leads to the Pick a Module dialog box. From this dialog box, choose a module whose area markers you want to delete. • This Area removes the area marker currently highlighted in the Areas window. Inspect IQ!illOJ When you choose Inspect, the profiler switches to the Module window and places the cursor on the first line of source code corresponding to the current area highlighted in the Areas window. If the area highlighted does not correspond to a program source line, the CPU window is opened instead. IQ!ill (Q) When you choose Options from the Areas window's SpeedMenu, the Area Options dialog box comes up. Options Figure 25.12 The Area Options dialog box You can specify three options with the radio buttons in this dialog box: Operation, Callers, and Timing. • Operation specifies what profiling action will occur for the current area. See page 392 for a complete discussion on the Operation option. • Callers specifies the depth of call-path information. • All Callers records all available call-path information for the current routine. • Immediate Callers records only "parent" information for the current routine. • None turns off call-path information for the current routine. • Timing specifies whether the profiler will add the execution time of the current area's child routines to a higher-level area or keep it separate. The timing option is described in detail on page 393. C hap t e r 25, The T u r boP r 0 f il ere n vir 0 n men t 407 • Window Procedure, when checked, specifies that the current area marks a procedure used by Windows. • The Messages box becomes active when the Window Procedure check box is checked. When Messages is chosen, the Window Procedure Messages dialog box is displayed. For a complete discussion of the Window Procedure Messages dialog box, refer to Chapter 31. Sort rillilllm The Sort command rearranges the information displayed in the Areas window. You can sort alphabetically (by Name) or numerically (by Address). Sorting by Address lists the areas in an order more consistent with the order in which they appear in your source code. Routines The Routines window is where Turbo Profiler displays a list of all routines that you can use as area markers. Use it when you can't remember the name of a routine, or when you want to see which routines have markers set on them. You can use the Inspect command on the Areas SpeedMenu to go to other modules by "inspecting" a routine in a particular module. The information displayed is basically a list of all global symbols available from debug information included in the executable file. These symbols include all routine and procedure names in standard libraries for Borland's line of C++ or Pascal compilers, as well as the names of routines in any third-party libraries you might be using (provided you link to those libraries with symbolic debug information turned on). Note The Routines menu gives you easy access to information related to symbols. Figure 25.13 The Routines window The Routines window is divided into two panes. The left pane lists routines global to your whole profiled program, and the right pane lists routines that are local to the current module of the program you're profiling. Local routines include nested routines and procedures in Pascal, and static routines in C. Global routines with area markers appear highlighted in the right pane. (By default, an underscore ( _ ) precedes all global variables in Borland C and C++ programs.) Both panes of the Routines window have SpeedMenus. 408 c++ User's Guide Local Module (right pane) 19i1lCb) When you choose Local Module in the Local Routines pane, the Pick a Module dialog box pops up, listing all modules in your program. After you highlight a module and choose OK, the profiler displays that module's local symbols in the right pane of the Routines window. Areas (both panes) 19i1l@ The Areas command opens an Areas window and positions that window's highlight bar on the current routine (the one that's highlighted in the Routines window). Callers (both panes) 19i1l© The Callers command opens a Callers wi1}dow and shows the current routine's callers. Module (both panes) 19i1l(M) The Module command opens a Module window and positions the cursor on the source code for the current routine. . 19i1l® The Profile command opens the Execution Profile window and shows the profile statistics for the current routine. Profile (both panes) Disassembly (CPU) The Disassembly window (labeled "CPU" when it's on the screen) displays the current area in the Module window as disassembled source code. The title bar of the Disassembly window indicates your system processor type and the word Protected appears if your program is a protected-mode program. You use the Disassembly (CPU) window to help determine if you want to rewrite parts of your program in assembly language. Figure 25.14 The Disassembly (CPU) window The left part of each disassembled line shows the instruction's address, either as a hexadecimal Segment:Offset value or, if the segment value is the same as the current CS register, as a CS:Offset value. If the window is wide enough (zoomed or resized), it also displays the bytes that make up the instruction. The disassembled instruction appears to the right of each line. Chapter 25, The Turbo Profiler environment 409 In the Disassembly (CPU) window, global symbols appear simply as the symbol name. Static symbols appear (generically) as THAT#ModName#SymbolName ModName.SymbolName /* Borland c++ * / Borland Pascal } where ModName is the module name and SymbolName is the static symbol name. Line numbers appear (also generically) as #ModName#LineNumber ModName.LineNumber /* Borland C++ */ { Borland Pascal } where ModName is the module name and LineNumber is the decimal line number. In the Disassembly (CPU) window, you can use the F2 function key to set area markers for each machine instruction you want to monitor. Any marked instructions that have no symbol name appear in the Areas window as hex addresses in Segment:Offset form. (Note that F2 can also be used to remove a marker from an area.) With the Disassembly (CPU) window's SpeedMenu commands, you can go immediately to any of these locations: • • • • • A specified address The current program location (CS:IP) The destination address of the current instruction The previous instruction pointer address The address in the source code You can also choose a SpeedMenu item to activate the Module window and move its cursor to the source for the current instruction, or to display disassembled instructions and source code three different ways. ' Gata ~(Q) When you choose Goto, a dialog box pops up and requests the address you want to go to. Enter a hexadecimal address, using the hex format for your programming language. You can enter addresses outside of your program to examine code in the BIOS ROM, inside DOS, and in resident utilities. The Previous command restores the Disassembly (CPU) window to the position it had before you chose Goto. Origin ~(Q) You choose Origin to position the window's highlight bar at the current program location as indicated by the CS:IP register pair. This command is useful when you have . been looking at your code and want to get back to the address of the current instruction pointer (CS:IP), where your program is stopped. The Previous command restores the Disassembly (CPU) window to the position it had before you chose Origin. 410 C++ Use r' s G u ide Follow 1Qli))CE) The Follow command positions the Disassembly (CPU) window's highlight bar at the destination address of the currently highlighted instruction. The window scrolls to display the code at the address where the currently highlighted instruction will transfer controL For conditional jumps, the window shows the address as if the jump occurred. You can use this command with CALL, JMP, and conditional jump aZ, ]NE, LOOP, JCXZ, and so on) instructions. The Previous command restores the Disassembly (CPU) window to the position it had before you chose Follow. Previous 1Qli))(f) When you issue a command that changes the instruction pointer address (such as Goto, Origin, or Follow), the Previous command goes back to the address displayed before you issued that address-changing command. If you move around with the arrow keys and the PgUp and PgDn keys, the profiler does not remember the window's position, but you can always return to the origin, which is the current CS:IP. Repeated use of the Previous command switches the Disassembly (CPU) window back and forth between two addresses. View Source 1Qli))(Y) The View Source command opens a Module window and shows the source code for the current routine. 1Qli))lM) There are three ways to display disassembled instructions and source code in the Disassembly (CPU) window. You choose the window's display format with the SpeedMenu's Mixed command, which toggles between three choices: No, Yes, and Both. Mixed • No means that no source code is displayed, only disassembled instructions. In No mode, global label names are still used in place of addresses for calls, jumps, and references to data items. • Yes means that source code lines appear before the first disassembled instruction for that source line. The profiler automatically sets the window to Yes if your current module is a highlevel language source module. • Both means that source code lines replace disassembled lines for those lines that have corresponding source code; otherwise, the disassembled instruction appears. The profiler sets the window to Both if your current module is an assembler source module. Use Both if you're profiling an assembler module and want to see the original source code line, instead of the corresponding disassembled instruction. C hap t e r 25, The T u r boP r 0 f i I ere n vir 0 n men t 411 Text File You can examme or modify any file on your system by using a Text File window. You can view the file only as ASCII text, so files containing binary data may display characters from the extended ASCII character set. Before you can open a File window, you must choose the View IText File command from the menu bar. This command brings up a dialog box in which you can use DOSstyle wildcards to get a list of file choices, or you can type a specific file name to load. Once you've chosen your file, Turbo Profiler displays it in the File window. The File window shows the contents of the file you've selected. The name of the file you're viewing is displayed at the top of the window, along with the line number the cursor is on. The File window SpeedMenu has a number of commands for moving around in a disk file, changing the way the contents of the file are displayed, and making changes to the file. Goto rQ!ill@ Positions you at a new line number in the file when you enter the new line number to go to. If you enter a line number after the last line in the file, you will be positioned at the end of the file. rQ!ill® Searches for a character string, starting at the current cursor position. You are prompted to enter the string to search for. If you have marked a block in the file using the Ins key, that block will be used to initialize the Search dialog box. This saves you from typing if you want to search for a string that is already in the file you are viewing. The search string can include simple wildcards, with? indicating a match on any single character, and * matching a or more characters. Search The search begins from the current cursor position and does not wrap around from the end of the file to the beginning. To search the entire file, start at the first line (press Ctrl+PgUp to move to the top of the file). You can also invoke this command by simply starting to type the string you want to search for. This brings up a dialog box exactly as if you had specified the Search command. Next rQ!ill(ffi Searches for the next instance of the character string you specified with the Search command; you can use this command only after first issuing a Search command. This command is useful when your Search command didn't find the instance of the string you wanted. You can keep issuing this command until you find what you want. 412 c++ User's Guide File rn® Displays the same Program Load dialog box as the View I Text File command, enabling you to load a different file. Edit rnlIl Lets you make changes to the file you're viewing by invoking the editor you specified with the TFINST installation program. This is done through the Editor Program Name field (located under the Options I Directories dialog box in TFINST). This option is not available when profiling Windows applications with TPROFW. Coverage The Coverage window has two panes: the left pane displays a list of selected modules, and the right pane shows the blocks contained in those modules. A block is a section of code that has only one entry point and one exit point; there are no jumps into or out of a block. Figure 25.15 The Coverage window Selecting coverage mode (Statistics I Profiling Options) opens the Coverage window, replacing the Execution Profile window. By default, Turbo Profiler selects as many program modules as possible in the left pane and all blocks within those modules are listed in the right pane. Note The Coverage window and the Execution Profile window are mutually exclusive; only one can be open at any given time. In its default setting, the Coverage window lists only unexecuted blocks in the right pane. Blocks that have been executed (hit) during a program run will be deleted from the listing. Before a program run, all program blocks are marked in the Module window with a ~ character. In the default Coverage mode, Turbo Profiler removes the ~ character from each block as it is hit. Successive program runs continue to remove block markers, allowing you to attempt different actions in order to hit the remaining marked blocks. Note Turbo Profiler automatically marks all progr(;lm blocks with a single marker. To restore all program blocks to an unhit status, choose Delete All from the Statistics menu. Each pane of the Coverage window has its own SpeedMenu. The left pane's SpeedMenu provides commands for selecting which modules are to be included in the profiling session. The right pane's SpeedMenu provides commands pertaining to how blocks are displayed. C hap t e r 2 5, The T u r boP r 0 f i I ere n vir 0 n men t 413 Add All Modules (left pane) @ill@ When you choose Add All Modules, the blocks from all program modules contained in the executable program are marked for the profile session. The keyword All indicates this selection. @ill® Remove All Modules removes all modules from the module list, leaving both panes in the Coverage window empty. @illlM) The Add Module command opens the Pick a Module dialog box, allowing you to select from the list of modules in the current program. Remove All Modules (left pane) Add Module (left pane) For more information on the Pick a Module dialog box and its use, refer to page 394. Remove Module (left pane) _ @ill(Y) Choosing Remove Module opens the Pick a Module dialog box. Using this dialog box, you can remove a module from subsequent profile runs. @ill(Q) The Delete This Item command either deletes or adds the currently highlighted item for the remaining profile runs. If the item has no dash (-) in front of it, the item is deleted. If the item does have a dash in front of it, it's added. @ill(Q) When you choose Display from the right pane's SpeedMenu, the Coverage Display dialog box appears. Delete This Item (left pane) Display (right pane) Figure 25.16 The Coverage Display dialog box • The Display buttons define what gets displayed in the right pane of the Coverage window. • When you choose All, all blocks (both hit and unhit) are displayed in the right pane. Blocks that have been hit show how many times they've been hit, and blocks that haven't been hit display a zero (0) next to their entries. You can set the number of hit counts that the Profiler tracks from the Profiling Options dialog box's Maximum Coverage Count option. See Figure 25.18 on page 418 for more information on setting Turbo Profiler's coverage hit count. 414 C++ User's Guide .. Not Hit (the default setting) means that only blocks that haven't been hit are displayed. • The Sort buttons define the order of block display. This menu item is available only if All is selected from the Display option and Max Coverage Count in the Profiling Options dialog box is greater than 1. .. A sort by Address lists blocks in alphabetical order. \1l A sort by Count lists the blocks in order of number of hits, starting with those blocks that have not been hit. • The Group radio buttons allow you to group blocks individually, or by routine or module. Note The Group buttons are available only if Display is set to All. Selecting Block (the default setting) causes all blocks to be listed in the window pane. Selecting Routine causes blocks to be grouped together by routine. With this selection, only routine names from the modules displayed in the left pane are listed in the right pane. However, in addition to each routine name, a count of blocks contained in the routine and the total number of blocks that have been hit is displayed. @ @ Figure 25.17 The Coverage window, listing blocks by routine $ The Module radio button applies only to programs with multiple modules. It works similarly to the Routine button, except that it groups blocks by module instead of by routine name. Position (right pane) rQ!ill[f) Use the Position command to inspect source code for a particular block of code. When in the right pane, select a block by moving the highlight bar with the arrow keys. After you select a block, choose Position to bring the source code into view in the Module window or the CPU window while keeping the Coverage window active. Pressing Spacebar also executes the Position command. Module (right pane) rQ!illlMJ The Module command is much like Position, except that Module activates the Module or CPU window and positions the cursor at the top of the block selected. Pressing Enter also executes the Module command. Note When Coverage mode is in effect, certain Turbo Profiler functions are no longer . pertinent, and respective menu items will be dimmed. Specifically, the following C hap t e r 25, The T u r boP r 0 f i I ere n vir 0 n men t 415 windows are unavailable from the View menu: Execution Profile, Callers, Files, Areas, and Routines. The Statistics menu dims both the Callers and Files functions. Also, the Accumulation toggle switch in the Statistics menu is automatically set to Enabled. Lastly, the SpeedMenu of the Module window dims the functions Add areas, Remove Areas, Operation, and Callers. Run menu The Run menu provides three commands for running your program: Run, Program Reset, and Arguments. Control returns to the profiler when one of the following events occurs: • • • • Your program finishes running Your program encounters an area marker whose operation is Stop You interrupt execution with the interrupt key Your program causes an exception (Usually, the interrupt key is the Ctrl+Break key combination; you can change this to another key with TFINST, the profiler installation program. When profiling a Windows application using TPROFW, use the keystroke sequence Ctrl+Alt+SysRq to interrupt the program. See Chapter 31 for details.) You can run your program even if the Module window is closed (as long as there's a program loaded into Turbo Profiler). Note When you choose Run IRun or Run IProgram Reset after reaching the run count limit, any statistics collected for a previous execution are reset. If you want to save a set of statistics, use Statistics ISave before you select Run or Program Reset, or use Statistics I Profiling Options to set the run count greater than 1. Run The Run command runs your program and collects performance statistics. If you set the Display Swapping option in the Display Options dialog box to Always, your program's output replaces the Turbo Profiler environment screen until the program finishes or you interrupt it. Program Reset The Run IProgram Reset command reloads your program from disk. Use this command if you've run your program too far during a profiling session and need to restart execution at the start of the program. If you select Run IProgram Reset when the Module or Disassembly (CPU) window is active, the display in that window won't return to the start of the program. Instead, the cursor stays exactly where it was when you chose Program Reset. Arguments The program you're profiling might expect command-line arguments. With Run I Arguments, you can store your program's command-line arguments within Turbo Profiler. Then, when you choose Run IRun or Run IProgram Reset, the profiler passes 416 C++ Use r 's G u ide the arguments to your program just as if you had typed them in at the command line. You can change these arguments from within Turbo Profiler and rerun your program. Enter the arguments exactly as you would at the DOS command line. (Do not enter the program name.) Statistics menu The Statistics menu contains commands to • • • • • • • Specify the type of data the profiler will collect (callers, files, interrupts, overlays) Set the profile mode to active, passive, or coverage Determine the number of program runs and areas Tum automatic data collection on and off Erase profile statistics Save profile statistics to a file Restore previously saved statistics The default extension is .TFS, but you can use any extension you want. You can save all statistical information from the current profile to a ~TFS file. Then, whenever you want to study the profile results, you can load that .TFS file-recovering all the saved statistics without having to rerun the profile. This feature is most useful if your programs take a long time to run or profile. You can save multiple versions of profiles under different conditions, then restore each of the resulting profiles for quick comparison at a later date. To automate this process, you can create a macro or DOS batch file to automatically run several profiles with different options or area markers, saving the results to individual.TFS files. Then, using the macro or batch file, you can run the profiles and view your results later. Note The first four items on the Statistics menu are toggle switches. When selected, the Callers, Files, Interrupts, and Overlay options will toggle between the Enabled and Disabled modes. Callers When you set the Callers option to Enabled, the profiler gathers statistics about which routines call other routines. To specify which routines you want call histories for, you choose the Callers command on the Module window's SpeedMenu or the Options command on the Areas window's SpeedMenu, then select the appropriate radio buttons under Callers and Areas. Note You must run your program and accumulate some statistics before these windows show any information. After running your program and gathering the profile information, use the Callers window to look at the call-history statistics. Gathering caller information consumes memory and slows down your program's run speed. If you don't need caller information, set Callers to Disabled. Chapter 25, The Turbo Profiler environment 417 Files When you enable the Files option, the profiler gathers statistics about which files your program opens, and which read and write operations take place. After running your program and gathering the profile information, use the Files window to look at your program's file activity. Gathering file-activity information consumes memory and slows down your program's run speed. If you don't need file-activity information, set Files to Disabled. Interrupts When the Interrupts option is set to Enabled, the profilercollects statistics about which interrupts your program calls. The profiler keeps separate statistics for DOS, video, disk BIOS, mouse, and keyboard interrupts. After running your program and gathering the profile information, use the Interrupts window to look at which interrupts your program called. Gathering interrupt information consumes memory and slows down your program's run speed. If you don't need interrupt information, set Interrupts to Disabled. Overlays The Overlays option toggles whether statistics are collected for the overlays your program loads. If your program does not contain overlays, an error message is displayed if you try to enable this menu item, and the option remains disabled. Gathering overlay information consumes memory and slows down the speed at which your program runs. If you don't need overlay information, set this option to Disabled. Profiling Options The Statistics I Profiling Options command opens the Profiling Options dialog box, shown here: Figure 25.18 The Profiling Options dialog box With the Profi~ing Options dialog box, you can set any of the following options: • Profile Mode specifies the analysis mode. The default mode is Active. • Active analysis means full statistical information is collected for each marked area. This includes basic clock timing information, and for routines, how many times the routine was called and where it was called from. 418 C++ Use r 's G u ide «I e Passive analysis means only basic clock timing information for each marked area is collected. Passive mode is not available in TPROFW when running Windows in 386 enhanced mode. Coverage analysis, in its default setting, means that Turbo Profiler tracks the blocks of code that haven't been hit during a succession of program runs. If you change analysis mode from Active or Passive to Coverage (or vice versa), you'll be prompted with Reload program and change profiling mode? If you select the YES button in answer to this prompt, the current set of statistics is deleted, and the new analysis mode becomes effective. Be sure to save any vital profile statistics before changing analysis modes, or they'll be lost. Note e Run Count sets how many times your program will run while the profiler collects statistics. The default is l. If Run Count is set to a number higher than I, Turbo Profiler will reset statistics only after the specified number of runs. Note e Clock Speed defines the speed of the timing clock, in ticks per second. The default is 100 ticks per second. Clock speed is available only in passive mode. e Maximum Areas specifies the maximum number of areas you can divide the current program into. Turbo Profiler sets default areas based on the density of the symbols it finds appended to the executable file. Increasing this setting will decrease the amount of memory left for the profiled program. e Maximum Windows Messages sets the maximum number of Windows messages that can be marked. The default setting is 20. Increasing this setting will decrease the amount of memory left for the profiled program. e Maximum Coverage Count sets the maximum number of hit counts that the Profiler will keep track of while in coverage mode. The default for this setting is 1 (a block has either been hit, or it has not). Increasing this setting will decrease the amount of memory left for the profiled program and will increase the time it takes to run. With the options in this dialog box, you can tailor the profiling session to meet your unique programming needs. Active analysis mode provides the most detailed analysis of your program at the cost of slowing program execution speed. On the other hand, passive mode allows your program to run at almost full speed, but does not provide any information about how many times a routine was called or which routines called it. If there are not many clock ticks during the time your profiled program runs, the data collected might not accurately reflect the time spent in various parts of the program. Running the program several times helps improve the accuracy by increasing the total number of data points collected. Speeding up the clock is another way to increase the total number of data points; this increases the accuracy of the timing statistics for each region at the expense of slowing down program execution speed. Note The profiler doesn't actually time each area, but uses the interrupt timer to increment a timer count. When the program terminates, the profiler converts the values in the timer counts to execution times, based on the current setting of the Clock Speed option in the Profiling Options dialog box. Chapter 25, The Turbo Profiler environment 419 Accumulation The Statistics I-Accumulation option turns automatic data collection on and off. This means you can collect data for a subset of all marked areas without removing any area markers, and manually tum data collection on after your program begins running. To collect data for a subset of all marked areas, do this: In the Areas window's SpeedMenu, choose Options to open the Area Options dialog box. 2 For those areas whose statistics you want, change the area marker from Normal to Enable (to start data collection) or to Disable (to stop data collection). 3 Set Statistics IAccumulation to Disabled. 4 Run your program. The profiler will not start collecting data until it trips an area marker that's set to Enable. To tum on data collection manually after your program has started running, do this: 1 Set area markers. 2 Set Statistics IAccumulation to Disabled. 3 Run your program from the profiler (press F9). 4 When the program is in the appropriate run-time state, interrupt it. S Enable the collection of profile data (set Statistics IAccumulation to Enabled). 6 Resume program execution (press F9 again). Turbo Profiler starts accumulating statistics immediately for the marked areas. Disabling accumulation Sometimes when many different places in your program call a routine or family of routines, you want to know only • The time spent in the routine • When a specific part of your code calls the routine • The time spent in the routine after a specific event To monitor only certain calls to a routine, use Statistics IAccumulation to disable data collection at the start. Mark an area that enables collection just before the call to the routine that you want to collect statistics for (set the area marker to Enabled). Mark another area that disables collection after the routine returns. You can also enable and disable areas in unrelated parts of the code; do this when you want to collect statistics only after a certain event. Example #1: Collecting only for a specific call to a routine Suppose you're interested in calls to abc only when it is called from xyz, but not at any other time. main() => { 420 C++ Use r 's G u ide /* normal area marker at routine */ abc (); /* don't want to collect stats for this call */ xyz (); } => xyz() /* normal area marker at routine */ { abc (); e> /* want to collect statistics for this call */ d> => abc() /* normal area marker at routine */ { Notice the ~ that enables collection and the ~ that disables collection. You must disable Statistics IAccumulation before running your program, or the profiler will erroneously collect statistics for the first call to abc in main. Example #2: Collecting after a certain event has occurred Suppose that routine xyz behaves differently depending on some global state information controlled by the two routines bufferon and bufferoff. You are interested only in the time spent in xyz when bufferflag equals 1. => main() /* normal area marker at routine */ { xyz (); /* no statistics collected here */ bufferon () ; xyz (); /* will collect statistics for this call */ bufferoff () ; xyz (); => bufferon() /* no statistics collected here */ /* normal area marker at routine */ { bufferflag = 1· e> d> } bufferoff () /* normal area marker at routine */ { bufferflag = 0; Chap t e r 25 J The T u r boP r 0 f i I ere n vir 0 n men t 421 => xyz() /* normal area marker at routine */ { Notice that the use of e~ to enable collection and the. to disable collection are not near the calls to xyz. Once again, you must disable data collection at the start (by setting Statistics IAccumulation to Disabled), or the first call to xyz will erroneously contribute to the collected statistics. Delete All The Statistics IDelete All command erases all statistics collected for the current profiling session---essentially wiping the data slate clean so you can start afresh. Delete All removes all profile data from the open profile report windows (Execution Profile, Callers, Interrupts, Files, Overlays, and Coverage), but it does not delete the profiling options you've set. Save The Statistics ISave command saves the following data, settings, and options: • All statistics for which collection was enabled when you ran the current profile (execution times and counts, ~allers, file activity, interrupts, overlays, coverage counts). • All area information (area names, operations, callers, separate versus combined timing) displayed in the Execution Profile window. Once you've saved statistics to a file, you can recover them at any time with the Statistics IRestore command. When you choose Statistics ISave, the Enter File ~ame to Save dialog box appears. The Name input box lists a default .TFS file name (progname.TFS, where progname is the current program's name). Saving Files To save the current profile statistics to the default file, choose OK. To save them to a different file, 1 Activate the File IName input box. 2 Type in the desired file name (including disk drive and path, if you so choose). 3 Choose OK (or press Enter) . . If the statistics file already exists, a message box asks if it's all right to overwrite the file. Restore When you choose Statistics IRestore, the Enter File Name to Restore dialog box appears. The Restore dialog box works just like the profiler's other file-loading dialog boxes. You can 422 C++ User's Guide • Enter a file name or a specification (with DOS wildcards) in the File Name input box. • Choose a different disk drive or directory from the directory tree. • Choose a file name from the Files list box. • Choose OK to complete the transaction (or choose Cancel to leave the dialog box without loading a file). • Choose Help to open a window of information about how to use the dialog box. After you load a statistics file, Turbo Profiler restores all the saved options, settings, and resulting statistical information to the environment screen. Print menu Turbo Profiler's Print menu enables you to print the contents of any open profiler window to a new or existing disk file, or directly to the printer. Statistics The Print IStatistics command prints the contents of all open profiler windows (except . for the Module, Routines, Text File, and Disassembly windows) to the printer, or to the destination file named in the Printing Options dialog box. Before you choose Print IStatistics, open the Printing Options dialog box (choose Print I Options) and verify that the current printing options (dimensions, output location, character set used, and-,-if you're printing to a file-destination file name) are what you want. If you choose to print statistics to an existing disk file, a menu pops up so you can choose whether to append the existing file, overwrite it, or cancel the printing operation. .i' Module From the Pick a Module dialog box accessed by choosing Print IModule, you specify which of your program's modules you want printed to the printer or to the disk file named in the Printing Options dialog box. You can choose a specific module by name, or choose All Modules to print all your program's available source code. When the profiler prints a module, it produces an annotated source listing that lists execution time and counts data next to each source line or routine you've marked as an area, as shown in the following listing: Chapter 25, The Turbo Profiler environment 423 Program: C:TPROFILEPRIME1.EXE Time File PRIME1.C Counts #include 0.0090 999 prime(int n) { int i; 0.0117 1.1456 0.0080 0.0017 0.0101 999 78022 831 168 999 0.0000 1 for (i=2; i #include void main() { printf ( "Entering main \n" ) ; route66 () priritf ("Back in main\n") ; delay(lOOO) ; highway80 (); printf ( "Back in main \n" ) ; delay(lOOO); printf ( "Leaving main \n \n" ) ; route66 () { printf ("Entering Route 66\n"); delay (2000) ; printf ("Leaving Route 66\n"); highway80 () { printf ("Entering Highway 80\n"); delay(2000) ; printf ("Leaving Highway 80\n") ; C hap t e r 27, Ins ide the pro f i I e r 451 In the previous program, setting areas to Routines in Module effectively sets up four time-collection compartments and four count-collection compartments. Turbo Profiler keeps execution times and counts for main, route66, and highway80. In addition, Turbo Profiler keeps a total for both execution times and for counts. Area boundaries In this section, you follow program execution and see what the profiler does as each area marker is passed. It's best to think of this process as going through a series of tollbooths. After you pass a tollbooth, you're on a section of road associated with that tollbooth until you come to another tollbooth. You're in no tollbooth's territory before you reach the first tollbooth. When you pass the first tollbooth, time spent on each section of roadway is tracked by the tollbooth in charge of that section of the road. Note that you can only go one direction down the road: Loops and jumps are like airlifts that take you back to some previous position on the road. Time and count collection Before you enter the main program block, C startup code is executed, which is equivalent to no tollbooth's territory. Any timer ticks encountered here are thrown away, unless you have explicitly set an area in the startup code. As soon as you pass the area marker (tollbooth) at main, the count associated with main increments by 1. Any timer tick that occurs between the time you enter main and the time when route66 is called goes into main's timer compartment. Next, main calls route66 and you enter a new stretch of highway. The moment execution passes through the area marker (the tollbooth) at route66, several things happen: • The current area is set to route66. • The compartment for the caller (main, in this case) goes on a stack. • The count-collection compar~ent associated with route66 increments by 1. Any timer tick that occurs, between now and the time you return from route66 automatically increments route66's time-collection compartment. The global program time-collector also continues to increment with each timer tick. As soon as execution passes through a return point for route66, the profiler pops the caller's compartment from a stack. The caller's count compartment is not incremented on a return. However, any timer ticks that occur between now and the call to highway80 are added to the time-collection compartment for main as well as to the program's global compartment. To verify this, tum off route66's area marker (position the cursor on route66's area marker and press F2) and compare the result with a profile for which that area marker was set. You should see essentially the same total execution time. However, main's execution time should increase by the amount of time it took to execute route66. 452 C++ Use r 's Gu ide Showing routine call overhead You might want to measure the time consumed by calling a routine (for example, route66) and ignore the time spent inside the routine. You can also get this kind of information using passive analysis, discussed in Chapter 26, "Profiling strategies." The easiest way to get this information is to disable collection at the entry point for route66, and then to reenable collection upon return from route66. To disable route66, position the cursor on the function header. Next, choose Operation from the Module window's SpeedMenu to open the Area Options dialog box, and set Operation to Disable. When you disable collection on entry to route66, returning from it doesn't automatically reenable collection. You must set an area marker at the closing brace for route66, and set the operation for that area marker to Enable (using the Area Operations dialog box). Who pays for loops? The tollbooth analogy helps explain why passing through an area marker and jumping back to a program statement that precedes that marker (using a loop or goto statement) doesn't change the current area. Even though you're lexically outside the scope of the marker, you haven't passed through any new markers. Any timer ticks that occur will still be associated with the most recently tripped marker. Knowing this, take a look at the next program: #include #include lost_in_town() ; => void main ( ) printf ("Entering main\n") lost_in~town ( ) ; delay(1000); printf ("Leaving main \n\n"); delay(1000); => lost_in_town() { int i; printf ( "Looking for highway ... \n" ) ; delay (100) ; for (i=O; i<10; i++) { => printf ( "Ask for directions \n"); printf ("Wrong turn \n\n"); delay(1000) ; printf ( "On the road again \n"); Chapter 27, Inside the profiler 453 In program plost, we've complicated the routine lost_in_town by using a compound statement inside a loop. Assume that three area markers have been set: one for main, one for lost_in_town, and one for the line that prints Wrong turn. Things get tricky when you get into losCin_town. When you first enter the routine, lost_in_town becomes the current area. The time as?ociated with printing Looking for highway is associated with this marker. Time for executing the loop statement is still associated with the routine marker, and the first time you Ask for directions, timing information is associated with the routine marker. However, once you trip the line marker for Wrong turn, the remainder of the time spent in the routine is associated with that line marker. Just because you pass into an area that was previously associated with another marker doesn't mean the current area changes. The current area changes only when you trip an area marker. This can produce unexpected results. For instance, if you set the three markers for program pfost as already described (one each for the main function, the lost_in_town function, and the Wrong Turn statement), approximately 84 percent of program time will be associated with printing "Wrong tum," while only 1 percent of execution time will be associated with lost_in_town. This is because nine out of ten calls to Ask for directions, plus all calls to the subsequent delay statement, occur after the Wrong Turn marker was tripped. If you toggle off the area marker for Wrong turn, 84 percent of the remaining execution time will be logged to the routine lost_in_town. Now, consider the following ·code: main while (!kbhit () { func1 (); statementl; statement2; func2 (); func1 () { func2 () { Assume that areas are set for All Routines in the module so that routines main, func1, and func2 each mark the beginning of an area. You enter main, which trips main's area marker. When this happens, Turbo Profiler internally encounters a breakpoint. This encounter sets a variable indicating that, until you trip another breakpoint, main is the current area. This encounter also increments a variable associated with execution counts for main by 1. 454 C++ User's Guide The scope of these areas is dynamic rather than lexical. That is, main is the current area until func1 is called. As soon as you enter func1, you're in a new area until you encounter another function call or until you return from func1. This means that the profiler puts the caller (main, in this case) on a stack. When you exit func1, you trip a return marker that the profiler set up when it entered func1. The routine main becomes the current area again. Any timer ticks that occur while the program is executing staternentl or statement2 will update the timer for the area associated with main. Two things are going on here: Every time you encounter an area, the profiler calls an internal routine that adjusts variables and updates a routine call stack. Two variables are associated with each area: execution counts and execution time. Each time you enter an area, the execution . count associated with that area increments. 2 Every time a timer tick occurs, the profiler calls another internal routine that checks to see what area is current, then increments the timer variable associated with that area by the appropriate amount of time. When the .program terminates, Turbo Profiler converts the counts variable for each area to an actual time (based on the total number of timer ticks that occurred for the entire program). Multiple return statements What do you do about multiple return statements? The answer is related to the implicit return points at the end of routines. Note Even though you might have several explicit return points in your function, Borland's C and C++ compilers actually tum all returns into jumps to a single exit point at the end of the routine. The line that receives the area marking for a return statement is the line associated with the closing brace for the routine. This is the actual assembly language return statement to which all other return statements in the routine are vectored. Disabling often-called functions The easiest way to disable collection for a function is to set a Disable marker at the function header and an Enable marker on the line after the call to the function. However, if a function is called from more than one place,. it may be difficult to set Enable markers after each function call. In this case, set the Enable marker at the closing brace of the function, or (better yet) at the actual return statement in the function code. For example, if you want to overlook the time spent in func1, set a Disable marker at the header for func1. Then; enable collection again at the return statement for func1: 1 Go to the Disassembly window (View IDisassembly). 2 Set an area marker at the ret statement of the function. 3 Go to the View IAreas window. Chapter 27, Inside the profiler 455 4 Set options to Enable (Ctrl+O, E). Now, whenever func1 is called, collection will be disabled upon entry to the function, and enabled at the exact point that the function returns. A simpler yet less accurate way to reenable collection is to set the Enable marker at the closing curly brace of the function in question. The drawback of this method, however, is that timing information will be collected for the time it takes to return from the function. Logging callers An active routine is a routine currently on the profiler's routine call stack. In active analysis, Turbo Profiler maintains its own routine call stack. This stack is similar to the stack found in any DOS program. However, the profiler's stack is separate from the user's program stack and is used strictly to retain information about routine calls for which a return statement has not yet been executed. In order to maintain an active routine stack, Turbo Profiler recognizes two types of area markers: • Routine-entry area markers (routine markers) • Normal area markers (label markers) When the profiler encounters a routine-entry area marker, it pushes the currently active routine (the last encountered routine-entry marker) onto its active routine stack. The newly encountered routine marker then becomes the active routine marker. Now, if a normal area marker trips, this encounter will have no effect on the current routine or on the active routine stack. When a normal area marker trips, it simply becomes the active area, which means that the profiler forgets the previously active area. The currently active routine, however, remains on the stack until the profiler encounters a return statement. When a return is issued within an active routine, the area marker associated with that routine becomes inactive. The routine on top of the profiler's active routine stack pops off the stack and becomes the active routine until a return statement executes within that routine, or until another routine-entry area marker is tripped. Thus the profiler can maintain a complete call history for every marked routine. If you have enabled Statistics ICallers for all marked routines, then each time a routine-entry area marker is tripped, the profiler saves the entire profiler call stack in a buffer linked directly to the routine-entry marker. If that call stack is identical to a call stack that was saved for a prior entry to this routine, the profiler increments a counter, rather than saving the call stack again. If, however, the call stack is different, the profiler allocates a new buffer and logs the profiler call stack to that new buffer. This makes it possible to maintain a record of every call path to a routine and the number of times each call path is traversed. The profiler's active routine stack is related to three menu settings: • Statistics ICallers (set to either Enabled or Disabled) 456 c++ User's Guide • The Callers option, set from the Areas' local window Option selection • The Stack option, set from the Module's local window Callers selection While all selections relate to call~rs, you gain finer control over logging call paths by using the SpeedMenu of the Module window. From this menu, you can set the Areas option to log callers for a single routine, for all the routines in a single module, or for all the routines in the program. As well, the Stack command allows you to specify callers as All Callers, Immediate Caller, or None. • All Callers means log the entire routine call stack each time the entry point is tripped. • Immediate Caller means log only the top entry on the routine call stack when the entry point is tripped. • None means don't log any routine stack information when this routine-entry marker is tripped. By default, when you first profile a program, the Callers option for all routine-entry area marks is set to None. Enabling Statistics ICallers from the main menu is the same as setting the Callers option to All Callers for each area marker listed in the Areas window. However, once you've hand-set any of the Callers options in the Areas window, setting Statistics ICallers to Enable won't change the value of the Callers options for any of the areas. Disabling the Statistics rCallers option at this point tells the profiler not to log any stack information, but doesn't change the Caller settings in the Areas window. (Neither does setting Statistics ICaller.) Sampling vs. counting This section relates only to passive mode. The profiler doesn't actually measure time: It comes up with a very accurate estimate of time based on information from timer tick counts. This is a form of statistical sampling. By taking regular periodic samples of the current area, and by keeping a count for each area (which increments each time that area is active when the timer interrupts), the profiler can estimate the time spent in a given area. The profiler knows the total time taken to run the program. It also knows the total number of times the timer interrupted the program. The time spent in a given area can be calculated as timearea = timertotal * countsarea / countstotal This is not the true time spent in an area. If your program iterates over some routine at a frequency that is a multiple of the timer frequency (for example, a routine that generates a steady sound tone), the execution of a particular line (or area) might exactly coincide with most of the timer interrupts. This resonance could occur even though that line is not where the program is spending most of its time. This is rare, but possible. C hap t e r 2 7, Ins ide the pro f i I e r 457 If you suspect this sort of frequency collision, change the value of the clock speed (Statistics IProfiling Options IClock Speed) and compare the resulting profile to the previous one. Profil~r memory use The profiler allocates memory for area information on the far heap. If you add areas while the program is running, the far heap will expand into the user program area to make room for new area variables and buffers. This is why, if you modify areas during a run, you should always reset the program with Run IProgram Reset. If you don't, the results of a profile might be unpredictable; you could hang your computer. 458 e++ User's Guide Turbo Profiler's command·line options This is the generic command-line format for running Turbo Profiler: TPROF [tprof_options] [progname [program_args]] where tprof_options is a list of one or more command-line options for the profiler (see Table 28.1), progname is the name of the program you want to profile, and programyrgs is a list of one or more command-line arguments for the profiled program. You can type TPROF without a program name or any arguments; if you do, you must then load the program you want to profile with Turbo Profiler's environment. Here are some example Turbo Profiler command lines: tprof -se progl a b Starts the profiler with the -sc option and loads program PROG1 with two command-line arguments, a and b. tprof prog2 -x Starts the profiler with default options and loads program PROG2 with one argument, -x. The command-line options All of Turbo Profiler's command-line options start with a hyphen (-). At least one space or tab separates each option from the TPROF command and any other command-line components. To tum an option off at the command line, type a hyphen after the option. For example, -v:~- explicitly turns the graphics save option off. Normally you'll tum an option off only if it s permanently enabled in the profiler's configuration file, TFCONFIG.TF. (You can modify the configuration file with the TFINST installation program described in Chapter 29, "Customizing Turbo Profiler.") C hap t e r 2 8, T u r boP r 0 f il e r 's com man d - lin e 0 p t ion 5 459 Table 28.1 summarizes Turbo Profiler's command-line options; we cover these options in greater detail in the following pages. Table 28.1 Turbo Profiler command-line options -b -bccount -cfile -do -dp -ds -h -? -ji -jn -jn -jn -p -r -mL;R -rpN -rsN -sc -sdDIR -Sn -vg -Vll -vp Loads Turbo Profiler in batch mode. Run in batch mode with run count of count. Reads in configuration file file. Runs the profiler on a secondary display. Shows the profiler on one display page, the output of the profiled program on another. Maintains separate screen images for the profiler and the program being profiled. Displays a help screen. Also displays a help screen. Session-state saving: Don't use session-state file if you've recompiled yo~ program. Session-state saving: Don't use session-state file. Session-state saving: Prompt for session-state file use if you've recompiled your program. Session-state saving: Use session-state file, even if you've recompiled your program. Enables mouse support. Enables profiling on a remote system. Remote network profiling, where L is the local machine and R is the remote machine. Sets the remote link port to port N. Sets the remote link speed. Ignores case when you enter symbol names. Sets one or more source directories to scan for source files. Don't load symbols. Saves complete graphics image on program screen. Disables 43/50 line display. Enables EGA palette save for program output screen. Batch mode (-b) The -b command-line argument instructs Turbo Profiler to run in batch mode. Turbo Profiler's environment isn't activated in batch mode; instead, the profiler runs the program and saves all statistics to a filename. TFS file, where filename is the name of the executable file. The -b argument lets you create a DOS batch file of one or more TPROF commands. If the program you're profiling doesn't require any keyboard input, you can run the batch process while you're doing something else. Note Before profiling in batch mode, an area file must be set up to instruct the profiler what areas to inspect and what profiling mode to use. To set up the area file, load your program and choose the profiling mode you want to use (Statistics IProfiling Options). Next, mark areas that you want inspected, setting up all Enable and Disable markers as needed. Then, exit Turbo Profiler. This creates a .TFA file that records the selected areas and profiling mode. 460 c++ User's Guide Once the area file is set, create a DOS batch file with the desired Turbo Profiler commands. Here's an example: TPROF -b MYPROG argl arg2 rename MYPROG.TFS MYPROG1.TFS TPROF -b MYPROG argl arg3 rename MYPROG.TFS MYPROG2.TFS TPROF -b MYPROG arg2 arg2 rename MYPROG.TFS MYPROG3.TFS TPROF -b MYPROG arg2 arg3 Alternately, you can set run count >1 to accumulate all statistics into the same file. Notice that you must rename the .TFS file after each TPROF command. If you fail to do so, successive runs of the same program will overwrite the statistics file already created. Once you've written your batch file, run it from the DOS command line. Configuration file (-c) This option tells Turbo Profiler to use the indicated configuration file. The default is TFCONFIG.TF; if you want to load a different one, you must use -c, followed immediately (no space) by the name of the configuration file you want to use. Display update (-d) All-d options affect the way Turbo Profiler updates the display. -do Runs the profiler on a secondary display. You can view the program's screen on the primary display while Turbo Profiler runs on the secondary display. -dp This is the default option for color displays. It shows the profiler on one display page, and the output of the program being profiled on another. Using two display pages minimizes the time it takes to swap between two screens. You can use this option only on a color display, because only color displays have multiple display pages. You can't use this option if the profiled program itself uses multiple display pages. -ds This is the default option for monochrome displays. It maintains separate screen images for the profiler and the program being profiled. Each time you run the program or reenter the profiler, Turbo Profiler loads an entire screen from memory. This is the most time-consuming method of displaying the two screen images, but it works on any display and with programs that do unusual things to the display. Help (-h and -?) Both of these options display Turbo Profiler's command-line syntax and options. C hap t e r 28, T u r boP r 0 f i 1e r' s com man d -I in e 0 p t ion s 461 Session-state saving (-jn) The session-state options specify how you want Turbo Profiler to handle the sessionstate files. See "Session Saving" on page 25 for more information. Mouse support (-p) This option enables mouse support (on by default). Remote profiling (-r) All"';'r options affect Turbo Profiler's remote profiling link. -r Enables profiling on a remote system. If no other -r command-line options are specified, -r uses the default serial port (COM1) and speed (115Kbaud), unless these have been changed using TFINST. -mL;R Enables profiling on a remote system over a local area network link. L and R are optional arguments, specifying the local and remote system names respectively. -rpN Sets the remote serial link port to port N. Set N = 1 for COM1; N = 2 for COM2, N=3 for COM3, and N=4 for COM4. -rsN Sets the remote serial link speed to the value associated with N. Set N=l for 9,600 baud, N=2 for 19,200 baud, N=3 for 38,400 baud, and N=4 for 115,000 baud. Source code and symbols (-s) All-s options affect the way Turbo Profiler handles source code and program symbols. -sc Ignores case when you enter symbol names, even if your program has been linked with case-sensitivity enabled. -.. Without the -sc option, Turbo Profiler ignores case only if you've linked your program with the "case ignore" option enabled. -sdDIR Sets one or more source directories to scan for source files; the syntax is: Note: There shouldn't be a space between -sd and the directory name. -sddirname dirname can be a -relative or absolute path and can include a disk letter. To set multiple directories, use the -sd option for each separate directory, or list them together like this: sddirlidir2idir3 Turbo Profiler searches directories in the order specified. If the configuration file specifies a directory list, the profiler appends the ones specified by the -sd option to that list. 462 C++ Use r 's G u ide Video hardware (-v) All-v options affect how Turbo Profiler handles the video hardware. -vg Saves the program screen's complete graphics image. This option requires extra memory but lets you profile programs that use special graphics display modes. Try this option if your program's graphics screen becomes corrupted when running under Turbo Profiler. -vn Disables the 43/50 line display mode. Specify this option to save some memory. Use -vn if you're running on an EGA or VGA and know you won't switch into 43- or 50-line mode once Turbo Profiler is running. -vp Enables you to save the EGA/VGA palette for the program output screen. Use this option for programs that output to special EGA/VGA graphics modes. Chapter 28, Turbo Profiler's command-line options 463 464 c++ User's Guide Customizing Turbo Profiler Turbo Profiler is ready to run as soon as you make working copies of the files on the distribution disk. However, you can change many of the default settings by running the customization program called TFINST. You also can change settings using commandline options when you load Turbo Profiler. If you find yourself frequently specifying the same command-line options over and over, you can make those options permanent by running the customization program. The customization program lets you set the following items: • Window and screen colors and patterns • Display parameters: screen-swapping mode, screen lines, tab column width, fast screen update, 43/50-line mode, full graphics saving, and user-screen updating • Your editor startup command and directories to search for source files and the Turbo Profiler help and configuration files • User input and prompting parameters: history list length, beep on error, interrupt key, mouse, and control-key shortcuts • NMI intercept and remote profiling • Display mode Running TFINST To run the customization program, enter TFINST at the DOS prompt. As soon as TFINST comes up, it displays its main menu. You can either press the highlighted first letter of a menu option or use the Up and Down arrow keys to move to the item you want and then press Enter. For instance, press D to change the display settings. Use this same technique for choosing from the other menus in the installation utility. To return to a previous menu, press Esc. You may have to press Esc several times to get back to the main menu. Choose Quit (or Alt+X) from the menu to exit TFINST. Chapter 29, Customizing Turbo Profiler 465 Setting the screen colors Choose Colors from the main menu to bring up the Colors menu. It offers you two choices: Customize and Default Color Set. Customizing screen colors If you choose Customize, a third menu appears, with options for customizing Windows, Dialogs, Menus, and Screens. Windows To customize windows, choose the Windows command. This command opens a fourth menu, from which you can choose the kind of window you want to customize: Text, Statistics, or Disassembly (the CPU window). Choosing one of these options brings up yet another menu listing the window elements, together with a pair of sample windows (one active, one inactive) in which you can test various color combinations. The screen looks like this: Figure 29.1 Customizing colors for windows When you select an item you want to change, a palette box pops up over the menu. Use the arrow keys to move around in the palette box. As you move the selection box ' through the various color choices, the window element whose color you are changing is updated to show the current selection. When you find the color you like, press Enter to accept it. Note Turbo Profiler maintains three color tables: one for color, one for black and white, and one for monochrome. You can change only one set of colors at a time, based on your current video mode and display hardware. So, if you are running on a color display and want to adjust the black-and-white table, first set your video mode to black and white by typing MODE BW8 a at the DOS prompt, and then run TFINST. Dialog boxes and menus If you choose Dialogs or Menus from the Customize menu, a screen 'appears with a menu listing dialog box or menu elements, and a sample dialog box or menu for you to experiment with. 466 c++ User's Guide As with the Windows menu, choosing an item from the current menu opens a palette from which you can choose the color for that item. Screen Choosing Screen from the Customize menu opens a menu from which you can access another menu with screen patterns and palettes for screen elements, as well as a sample screen background on which to test them. The default colors If you choose Default Color Set from the Colors menu, facsimiles of an active text window and an inactive window appear onscreen. The facsimiles show you the default colors for their elements. A dialog box lets you select text, statistics, or low-level windows to view. ~Setting Turbo Profiler display parameters Choose Display from the main menu to bring up the Display Options dialog box. Figure 29.2 The Display Options dialog box Note These display options include some you can set from the DOS command line when you start up Turbo Profiler, as well as some you can set only with TFINST. See page 474 for a table of Turbo Profiler command-line options and corresponding TFINST settings. Display Swapping You use the Display Swapping radio buttons to control whether Turbo Profiler switches between its own display and the output of the program you're profiling. You can toggle between the following settings: None Always Don't swap between the two screens. Use this option if you're profiling a program that does not output to the user screen. Swap to the user screen every time the user program runs. Use this option if your program writes to the user screen. This is the default option. C hap t e r 29, C u s tom i z in 9 T u r boP r 0 f i I e r 467 Screen Lines Use these radio buttons to toggle whether Turbo Profiler should start up with a display screen of 25 lines or a display screen of 43 or 50 lines. Note Only EGA and VGA monitors can display more than 25 lines. Fast Screen Update The Fast Screen Update check box lets you toggle whether your displays will be updated quickly. Toggle this option off if you get "snow" on your display with fast updating enabled. You need to disable this option only if the "snow" annoys you. (Some people prefer the snowy screen because it gets updated more quickly.) Permit 43/50 Lines Turning this check box on allows big (43/50-line) display modes. If you turn it off, you save approximately 8K, since the large screen modes need more window buffer space in. Turbo Profiler. This may be helpful if you are profiling a very large program that needs as much memory as possible to execute in. When the option is disabled, you will not be able to switch the display into 43/50-line mode even if your system is capable of handling it. Full Graphics Saving Turning this check box on causes the entire graphics display buffer to be saved whenever there is a switch between the Turbo Profiler screen and the user screen. If you tum it off, you can save approxima,tely 12K of memory, which is helpful if you are profiling a very large program that needs as much memory as possible to execute. Generally the only drawback to disabling this option is that the user screen might show a small number of corrupted locations that usually don't interfere with profiling. Tab Size In this input box, you can set the number of columns between tab stops in a text or source file display. You are prompted for the number of columns (a number from 1 to 32); the default is 8. 468 c++ User's Guide User Screen Updating The User Screen Updating radio buttons set how the user screen is updated when Turbo Profiler switches between its screen and your program's user screen. There are three settings: Other Display Flip Pages Swap Runs Turbo Profiler on the other display in your system. If you have both a color and monochrome display adapter, this option lets you view your program's screen on one display and Turbo Profiler's on the other. Puts Turbo Profiler's screen on a separate display page. This option works only if your display adapter has multiple display pages, like a eGA, EGA, or VGA. You can't use this option on a monochrome display. This option works for the majority of profiling situations; it's fast and disturbs only the operation of programs that use multiple display pages-which are few and far between. Uses a single display adapter and display page, and swaps the contents of the user and Turbo Profiler screens in software. This is the slowest method of display swapping, but it is the most protective and least disruptive. If you are profiling a program that uses multiple display pages, use this option. Also use the Swap option if you shell to DOS and run other utilities or if you are using a TSR (such as SideKick) and want to keep the current Turbo Profiler screen as well. Turbo Profiler options The Options command in the main menu opens a menu of options, which in tum open dialog boxes for you. The Directories dialog box This dialog box contains input boxes in which you can enter: Editor program name Source directories Turbo directory Specifies the DOS command that starts your editor. This lets Turbo Profiler start up your favorite editor when you are profiling and want to change something in a file. Turbo Profiler adds to the end of this command the name of the file that it wants to edit, separated by a space. Sets the list of directories Turbo Profiler searches for source files. Sets the directory that Turbo Profiler searches for its help and configuration files. The User Input and Prompting dialog box This dialog box lets you set options that control how you input information to Turbo Profiler, and how Turbo Profiler prompts you for information: C hap t e r 29, C u s tom i z in 9 T u rb 0 Pro f i Ie r 469 Figure 29.3 The User Input and Prompting dialog box History List Length This input box lets you specify how many earlier entries are to be saved in the history list of an input box. Interrupt Key The Interrupt Key radio buttons let you change the Turbo Profiler interrupt key from its default of Break to Escape, NumLock, or another key or key combination. Pushing the Other radio button displays a prompt asking you to press the key or key combination you want to use as the interrupt key. Mouse Enabled This check box controls whether Turbo Profiler defaults to mouse support. Beep on Error Turbo Profiler can give a warning beep when you press an invalid key or do something that generates an error message. Checking the Beep on Error check box enables the warning beep. Control Key Shortcuts This check box enables or disables the .control-key shortcuts. When control-key shortcuts are enabled, you can invoke any SpeedMenu command directly by pressing the Ctrl key in combination with the first letter of the menu item. However, in that case, you can't use those control keys as WordStar-style cursor-movement commands. The Miscellaneous Options dialog box The Miscellaneous Options dialog box contains options controlling interrupts, EMS memory, DOS shell swapping, and remote profiling. 470 C++ Use r 's G u ide Figure 29.4 The Miscellaneous Options dialog box Printer Output This option lets you toggle whether to print both extended and standard ASCII characters, or just the straight ASCII character set. NMllntercept The nonmaskable interrupt (NMI) is a hardware interrupt that the processor must deal with immediately. It is typically used to halt processing when there is a memory parity error: an error message like "Memory Parity Error" is displayed and the system hangs. Another use for this interrupt is to enable a debugger board to perform a breakout when you press the breakout button. Because the NMI defaults to OFF with Turbo Profiler, you will probably want to turn this interrupt on if you use a debugger board. If your computer is not a Tandy 1000, IBM PC compatible, ACER 1100, or NEC MultiSpeed, you can run TFINST and try turning on the NMI Intercept check box. Some computers use the NMI in ways that conflict with Turbo Profiler, so if you have problems loading in applications under Turbo Profiler after turning this option on, run TFINST again and disable Turbo Profiler's use of this interrupt. Ignore Case of Symbols If this check box is turned on, Turbo Pro filer will ignore the difference between uppercase and lowercase. If it is not checked, case sensitivity will be in effect. International support If this check box is checked, Turbo Profiler will sort all items in list boxes according to the country setting in your CONFIG.5YS file (when using DOS), or according to the country checked in the Windows Control Panel (when using Windows). For more information on setting the country code, refer to your DOS or Windows User's Guide. If the box is not checked, Turbo Profiler will sort entries in list boxes according to the ASCII values of the items in the box (when using DOS), or according to the ANSI values of the items in the box (when using Windows). C hap t e r 2 9, C u s tom i z i n 9 T u r boP r 0 f i I e r 471 DOS Shell Swap Size (Kb) In this input box you can set the number of kilobytes of memory to be swapped out for the DOS shell. Memory swapping allows you to use the File IDOS Shell command even when a large program is loaded. . DOS Shell Swap Size is not available in TPROFW. Remote type The Remote Type radio buttons let you specify the type of remote profile link. None, the default mode, specifies that profiling is local; there is no remote link. The Serial button enables remote serial profiling. The communication port and link speed are defined by Remote Link Port and Link Speed options. The Network button specifies remote LAN profiling. Warning! Usually you won't want to save a configuration file that specifies remote profiling, since Turbo Profiler will then look for the remote link each time it's loaded. Remote Link Port The Remote Link Port radio buttons let you choose either the COM1, COM2, COM3, and COM4 serial ports for the remote serial link. Link Speed The Link Speed radio buttons let you choose one of the four speeds that are available for the remote serial link: 9,600 baud, 19,200 baud, 38,400 baud, or 115,000 baud. Network local name This text box lets you define the default name of the local system when using remote LAN profiling. By default, the name LOCAL is given to the local system. This name should be changed if more than one person is using the network for remote profiling. Network remote name This text box lets you define the default name of the remote system when using remote LAN profiling. By default, the name REMOTE is given to the local system. This name should be changed if more than one person is using the network for remote profiling. Setting the mode for display Choosing Mode for Display from the main menu opens a menu from which you can select the display mode for your system. Default Turbo Profiler automatically detects the kind of graphics adapter on your system and selects the display mode appropriate for it. 472 C++ Use r 's G u ide Color If you have an EGA, VGA, CGA, MCGA, or 8514 graphics adapter and choose this as your default, the display will be in color. Black and White If you have an EGA, VGA, CGA, MCGA, or 8514 graphics adapter and choose this as your default, the display will be in black and white. Monochrome Choose this only if you are using a color monitor with a Hercules or monochrome text display adapter. LCD Choosing this instead of Black and VVhite if you have an LCD monitor makes your display much easier to read. When you're through ... After configuring and customizing the way Turbo Profiler looks and behaves, you'll want to save the settings out to disk. You can either modify the Turbo Profiler executable program directly (TPROF.EXE), or you can create a configuration file that gets loaded as you load Turbo Profiler. Saving changes When you have all your Turbo Profiler options set the way you want, choose Save from the main menu to determine how you want them saved. Save Configuration File If you choose Save Configuration File, a dialog box opens, initialized to the default configuration file TFCONFIG.TF. You can accept this name by pressing Enter, or you can type a new configuration file name; If you specify a different file name, you can load that configuration by using the -c command-line option when you start Turbo Profiler. For example, tprof -cmycfg myprog You can also use the Turbo Profiler Options I Restore Configuration command to load a configuration once you have started Turbo Profiler. Modify TPROF.EXE If you choose Modify TPROF.EXE, any changes you've made to the configuration are saved directly into the Turbo Profiler executable program file TPROF.EXE. The next time you enter Turbo Profiler, those settings will be your defaults. C hap t e r 2 9, C u s tom i z i n 9 T u r boP r 0 f i I e r 473 Note If at any time you want to return to the default configuration that Turbo Profiler is shipped with, copy TPROF.EXE from yout master disk onto your working system disk, overwriting the TPROF.EXE file that you modified. Exiting TFI~ST To get out of TFINST at any time, choose Quit from the main menu. Command-line options and TFINST equivalents , Some of the options described above can be overridden when you start Turbo Profiler from DOS. The following table shows the correspondence between Turbo Profiler command-line options and the TFINST program command that permanently sets that option. Table 29.1 -do -dp -ds -p Command-line options and TFINST equivalents Display IDisplay Options (e) Other Display (e) Flip Pages (e) Swap Options I Input and Prompting I User Input and Prompting [ X] Mouse Enabled -p- [] -r- Options I Miscellaneous I Miscellaneous Options (e) None -r (e) Serial -m (e) Network -rpl -rp2 -~l Mouse Enabled Options I Miscellaneous I Miscellaneous Options (e) COM1 (e ) COM2 Options I Miscellaneous I Miscellaneous Options (e) 9,600 baud -rs2 (e) -~3 (e) 38,400 baud -rs4 (e) 115,000 baud 19,200 baud Options IMiscellaneous IMiscellaneous Options -se -se- [ X] [] Ignore Case of Symbol Ignore Case of Symbol Options IDirectories IDirectories -sd 474 Source Directories C++ Use r 's G u ide Table 29.1 Command-line options and TFINST equivalents (continued) Display IDisplay Options -yo [] Permit 43/50 Lines -vo- [X] Permit 43/50 Lines TFINST.EXE uses the following syntax: TFINST [options] [exefile] Items enclosed in brackets are optionaL For a list of options, see the following table. Table 29.2 -cfile -h, -7 -p -w TFINST.EXE options Use configuration file file. Display help screen. Enable mouse support. .Configure TPROFW.EXE. C hap t e r 2 9, C u s tom i z i n 9 T u r boP r 0 f i I e r 475 476 C++ Use r 's G u ide Remote profiling· Remote profiling is just what it sounds like: You run Turbo Profiler on one computer and run the program you're profiling on another. The systems can be connected by either the serial ports of the systems or through a NETBIOS-compatible local area network (LAN). Remote profiling is useful in several situations: • When your program needs a lot of memory, and you can't run both the program and Turbo Profiler on the same computer. When this happens, you'll get Not enough memory error messages. • When your program loads under Turbo Profiler, but there's not enough memory left for it to operate properly. Here, you'll get memory allocation errors during the profiling session. • When you are profiling a Windows program. If you're profiling a Windows application, you have the choice of running Turbo Profiler for Windows (TPROFW) and the application on a single machine, or of running Windows, WREMOTE, and the application on one machine and running Turbo Profiler (TPROF) on another. Although there are many reasons why you'll want to profile a program using two systems, the advantages become even greater when you are developing a Windows application: • If you have a single monitor, running Turbo Profiler and the application on the same machine means that you must switch between Turbo Profiler's character mode screens and the application's graphics mode screens. If you use remote profiling, you can see the application's screens and Turbo Profiler's screens at the same time. (This same result can be achieved if you have two monitors attached to the same system.) C hap t e r 3 0, Rem 0 t e pro f iii n 9 477 • TFREMOTE and WREMOTE use far less memory than Turbo Profiler, so the program you're profiling will behave more like it does when running normally, without the profiler in the background. Hardware and software requirements You choose between a serial or a LAN connection for the remote session. The two setups do use different hardware; however, both share the following requirements: • A development system with enough memory to load TPROF (this is the local system). • Another PC with enough memory and disk space to hold either TFREMOTE and the DOS program you want to profile or WREMOTE, Windows, and the Windows program you want to profile (this is the remote system). If you're going to profile a Windows application, the remote machine must be able to run in protected mode, which means that the CPU must be at least an 80286. The amount of memory required depends on the mode in which you're running Windows, but must be at least 1MB. For a serial connection, you'll need a null modem cable to connect the serial ports of the two systems. Make sure the cable connecting the two systems is set up properly: You can't use a straight-through extension-type cable. At the very least, the cable must swap the transmit and receive data lines (lines 2 and 3 on a 25-pin cable). For a LAN connection, you'll need a LAN running Novell Netware-compatible software (IPX and NETBIOS version 3.0 or later). Note NETBIOS must be loaded onto both the-local and remote systems before TPROF, TFREMOTE, TFREMOTE, or WREMOTE can be loaded. This is true for both DOS and Windows profiling. Profiling remote DOS applications To profile a remote DOS application, you must run TFREMOTE and the application on one machine and Turbo Profiler on another. In this discussion, the machine running TFREMOTE and the application is called the remot~machine, and the machine running Turbo Profiler is called the local machine. Setting up the remote system Copy the remote profiling driver TFREMOTE.EXE onto the remote system, as well as any files required by the program you're profiling. These files can be data input files, configuration files, help files, and so on. If you want, you can also copy your application program onto the remote system. However, Turbo Profiler automatically sends it over the remote link if necessary. To put files on the remote system, you can use floppy disks or the TDRF remote file transfer utility. 478 C++ Use r 's G u ide Configuring TFREMOTE When starting TFREMOTE, you must configure it so it can communicate over the remote link. You do this by starting the driver with specific command-line options. Start an option with either a hyphen (-) or a slash (I). Table 30.1 TFREMOTE command-line options -?or-h -m -rpl -rp2 -rp3 -rp4 -rsl -rs2 -rs3 -rs4 -w Note Displays a help screen Remote LAN profiling Port 1, (COMl); default Port 2, (COM2) Port 3, (COM3) Port 4, (COM4) Slowest speed (9,600 baud) Slow speed (19,200 baud) Medium speed (38,400 baud) High speed (115,000 baud); default Writes options to the executable program file For a list of all available TFREMOTE command-line options, type the following at the remote DOS prompt: TFREMOTE -h Customizing TFREMOTE If TFREMOTE is started without command-line options, it assumes remote serial profiling at the default port and speed built into TFREMOTE.EXE (COM1 and 115,000 baud respectively, unless you've changed them with the -w option). You can make TFREMOTE's command-line options permanent by writing them back to disk. To do this, specify -won the command-line along with the other options you want to make permanent. TFREMOTE then prompts for the name of the executable file to write to; if you enter a nonexistent executable file name, TFREMOTE creates the file. If you press Enter, the currently running program (usually TFREMOTE.EXE) is overwritten. If you are running DOS version 3.0 or later, the prompt indicates the path and file name from which you executed TFREMOTE. You can accept this name (press Enter), or enter a new executable file name. (If you're running DOS 2.xx, you must supply the full path and file name of the executable program.) For example, on the remote system, type the following command line at the DOS prompt: TFREMOTE -w -rs3 -rp2 When prompted, enter the name of the prGgram to modify, for instance, tfremot2.exe. With this, TFREMOTE creates a new remote driver named TFREMOT2.EXE, where the defaqlt speed is 38,400 baud (-rs3) and the default port is COM2 (-rp2). C hap t e r 3 0, Rem 0 t e pro f iii n 9 479 The remote DOS driver To begin a remote profiling session, you must first start the driver on the remote system and then load TPROF on the local system. Before starting TFREMOTE, be sure the directory on the remote system is set to the one that contains the program files. This is essential because TFREMOTE puts the program to be profiled into the directory that is current when you start TPROF. You don't give the program name on the TFREMOTE command line, since TPROF controls the loading of the program. When loaded, TFREMOTE signs on with a copyright message, then indicates that it's waiting for you to start Turbo Profiler at the other end of the link. To stop and return to DOS, press Ctrl+Break. Starting the remote serial driver If you're using a null modem cable to connect the two systems, you must use the command-line options -rs and -rp to indicate the speed and port of the data communications. If the remote system's serial port is set up as COMl, type TFREMOTE -rpl -rs4 Note that this is the default setting of TFREMOTE, and is the same as issuing the command TFREMOTE if the default settings haven't been changed. If the remote system's serial port is set up as COM2,type TFREMOTE -rp2 -rs4 to start TFREMOTE. If you're using a PS/2, use the command-line option -rsl. All three of these commands start the link at its maximum speed (115,000 baud). This speed works with most PCs and cable setups. However, if you experience communication difficulties, see Table 30.1 on page 479 for how to start the link at a slower speed. Note It's possible that the local and remote systems use different serial ports for the null modem cable connection. In this case, the two systems' serial port settings will not match. However, the communication speed of the two systems must always be the same for the connection to work. Starting the remote LAN driver If you're using a LAN to connect the two systems, you must use the -m command-line option to start TFREMOTE. For example, issuing the following command at the DOS prompt will start TFREMOTE over a LAN connection, naming the remote system remotelink: TFREMOTE -rnremotelink 480 ett User's Guide If a remote name is left out of the command, the default name REMOTE is used. For more on naming remote systems, see the "LAN connection" section that follows. Establishing the remote DOS link Once TFREMOTE has been loaded on the remote system, start Turbo Profiler on the local system using command-line options that correspond to the established data link (serial or LAN). Serial connection TPROF and TFREMOTE use the same syntax for specifying the speed and port settings for remote serial communications. For the link to work properly, you must set both systems to the same speed (with the -rs option). After loading TFREMOTE on the remote system, run TPROF on the local system to complete the remote link. The following DOS command will load Turbo Profiler, establishing a connection through serial port 2, at the default speed of 115,000 baud: TPROF -rp2 filename When the link is successful, the message Link established appears on the remote system, and the activity indicator on the local system displays READY. Turbo Profiler's display then appears on the local system. If the program filename is not on the remote system, then Turbo Profiler will send the program over the remote link. For more about loading programs over the link, refer to "Loading programs onto the remote system" on page 485. Instead of using -rs and -rp, you can use the -r command-line option, which starts the remote serial link using the default speed and serial port. Unless you've changed the defaults using TFINST, -r specifies COM1 at 115,000 baud. LAN connection TPROF uses the -m command-line option to initiate a remote LAN link. However, the syntax used with Turbo Profiler is slightly different from that used with TFREMOTE. Following is the Turbo Profiler remote LAN syntax: TPROF -rn [Local] [;Remote] filename The -m command-line option takes two optional parameters: the local system name and the remote system name, separated by a semicolon. Since both parameters are optional, there are four ways to use the -m command-line option with TPROF. These DOS commands all load Turbo Profiler, specify a remote LAN connection, and load the program filename for profiling. TPROF -rn filename Uses the default names Local and Remote for both the local and remote systems. TPROF -rnLOCALl filename Specifies LOCAL1 as the local system name, but uses the default (Remote) for the remote system name. Chap t e r 30, Rem 0 t e pro f iii n 9 481 TPROF -rn;REMOTEl filename· Uses the default (LOCAL) for the local system name, but specifies REMOTEl for the remote system. . TPROF -rnLOCAL1;REMOTEl filename Specifies both system names.The handshake should take less than 15 seconds after you enter the TPROF command. Local and remote system names can be up to 16 characters long. Note If only one person on a network is using remote profiling, then it isn't necessary to define special local and remote system names. However, if more than one person uses remote profiling on a given network, unique names must be given to all systems. Profiling remote Windows applications To profile a remote Windows application, you must run Windows, WREMOTE, and the application on one machine and Turbo Profiler on another. In this discussion, the machine running Windows, WREMOTE, and the application is called the remote system, and the machine running Turbo Profiler is called the local system. Setting up the remote system Copy to the remote system the remote profiling driver WREMOTE.EXE, the configuration program WRSETUP.EXE, and any files required by the program you're profiling. These files include data input files, configuration files, help files, Windows OLL files, and so on. If you want, you can also copy your application program onto the remote system. However, Turbo Profiler automatically sends it over the remote link if necessary. To put files on the remote system, you can use floppy disks or the TORF remote file transfer utility. TORF is described in the online Help. Configuring WREMOTE Before running WREMOTE for the first time, you should run the WRSETUP program to establish the communication settings. Set up WREMOTE withWRSETUP. When you run WRSETUP, you see a window displaying the commands File, Settings, and Help. Choosing Settings displays the following screen: 482 c++ Use r 's G u ide Figure 30.1 WRSETUP main window and Settings dialog box Eile §ettings lielp fZl Q.uit when host quits Starting J!.irectory: Baud rate ll600 o @ 192.!!.0 Remote type @§erial o 3.!!.400 o l1~OOO o Network Comm port Networkremot!! name: @COM! IHEMOTE OCOMZ OCOMl OCOM~ Serial configuration If you're using serial communications, select the Serial radio button, and set a baud rate and communications port that works for your hardware setup. The defaults are 19,200 baud and COMl. LAN configuration If you're using LAN communications, select the Network radio button, and specify the desired remote system name in the Network Remote Name text box. By default, the remote system name is REMOTE. For more on remote system names, refer to "LAN connection" on page 481. In the Starting Directory text entry box, enter the directory path where Turbo Profiler should look for the program you're profiling. If you want WREMOTE to return control to Windows when you terminate Turbo Profiler on the local machine, select Quit When Host Quits. If you are using the higher transmission speeds (38,400 or 115,000 baud) check the Disable Clock Interrupts box. This will help WREMOTE and Turbo Profiler establish a connection in the Windows environment. As with any .IN! file, you can edit the file directly using any word processor that produces ASCII text. Once you've set your options and-closed the WRSETUP window, WRSETUP will save your settings to the file TDW.INI in your Windows directory. The following TDW.INI file sets WREMOTE at 19,200 baud on COM2 with clock interrupts disabled and the program returning control to Windows when Turbo Profiler terminates: [WRemote] BaudRate=2 Port=2 Chapter 30, Remote profiling 483 Quit=l Clock=l WREMOTE command-line options You can use WREMOTE command-line options to override the default settings or the settings listed in the WREMOTE.INI file. Start an option with either a hyphen (-) or a slash (I). TabJe30.2 WREMOTE command-line options -c -d -reO -rc1 -m -rpl -rp2 -rp3 -rp4 -rqO -rql -rsl -rs2 -rs3 -rs4 Use as the configuration (.INI) file Use as the startup directory Clock interrupts enabled Clock interrupts disabled Remote LAN profiling Port 1 (COM1); default Port 2 (COM2) Port 3 (COM3) Port 4 (COM4) Don't quit when Turbo Profiler quits Quit when Turbo Profiler quits Slowest speed (9,600 baud) Slow speed (19,200 baud) Medium speed (38,400 baud) Fast speed (115,000 baud); default Starting the remote Windows driver After you start WREMOTE from Windows, the program displays an hourglass at the mouse cursor location, indicating that it's ready for you to start Turbo Profiler at the other end of the link. To terminate WREMOTE while it is waiting to establish a connection with TPROF, press Ctrl+Break on the remote machine. Establishing the remote Windows link If you're using a null modem cable to connect the two systems, you may use the command-line options -rs and -rp to indicate the speed and port of the data communications. For more on command-line options, see "Serial connection" on page 481. Both Turbo Profiler and WREMOTE must beset to the same speed to work properly. You can use the -rs parameter to set the baud rate for Turbo Profiler, or you can use the -r command-line option, which starts the remote serial link using the default speed and serial port. Unless you've changed the defaults using TFINST, -r specifies COMl at 115,000 baud. 484 c++ User's Guide LAN connection TPROF uses the -rn command-line option to initiate a remote LAN link. For more on -rn, see "LAN connection" on page 481. Here's a typical Turbo Profiler command to start the remote Windows link: TPROF -rs2 myprog This command begins the link on the default serial port (usually COM1) at the link speed (19,200 baud), and loads the program myprog into the remote system if it's not already there. When Turbo Profiler starts on the local machine, it displays copyright and version information and the following message: Waiting for handshake from remote driver (Ctrl+Break to quit) While waiting for a connection, an hourglass is displayed on the remote system. Turbo Profiler's normal window display comes up on the local machine. Press Ctrl+Break to exit WREMOTE if the link is not successful. Loading programs onto the remote system If a file name is included as a TPROF command-line argument, or if you load a new file into the profiler using the File IOpen command, Turbo Profiler will automatically check to see if the program needs to be sent to the remote system. Windows DLL files are not automatically transferred to the remote system. Turbo Profiler is smart about loading programs onto the remote system. First, a check is made to see if the program exists on the remote system. If the program doesn't exist on the remote system, it's sent over the link right away. If the program does exist on the remote system, Turbo Profiler looks at the date and time of the program on the local system and compares this with the copy on the remote system. If the program on the local system is later (newer) than the remote copy, Turbo Profiler assumes you've recompiled or relinked the program, and sends it over the link. At the highest link speed, file transfers move at a rate of about 10K per second. A typical 60K program takes roughly six seconds to transfer. On DOS systems, Turbo Profiler indicates that the system is working by displaying the number of bytes transferred on the remote system. Remote profiling sessions Once you start TPROF in remote mode (using either TFREMOTE or WREMOTE), the Turbo Profiler commands work exactly the same as they do on a single system; there is nothing new to learn. Because the program you're profiling is actually running on the remote system, any screen output or keyboard input to that program happens on the remote system. The Window IUser Screen command has no effect when you're running on the remote link. Chapter 30, Remote profiling 485 The remote system's CPU type appears as part of the CPU window title, with the word REMOTE before it. To send files over to the remote system while running Turbo Profiler, go to DOS (choose File I DOS Shell) and then use TDRF to perform file-maintenance activities on the remote system. To return to Turbo Profiler, type EXIT at the DOS prompt and continue profiling your program. Troubleshooting Here's a list of troubleshooting techniques you can try if you experience problem~ with the remote setup: '. Check your cable hookups. • Check that you're using the correct serial port settings or that you're properly connected to the network. • Try running the link at a slower speed (using the -rs command-line option) until you find a speed that works. • Some hardware and cable combinations don't always work properly at the highest speed, so if you can get the link to work only at a lower speed, you might want to try a different cable or different computers. • If you're profiling a Windows program and can't get the connection to work at any speed, use WRSETUP to Disable clock interrupts and try running the link at 9,600 baud. If that works, try successively higher speeds. TFREMOTE messages nn bytes downloaded TFREMOTE is receiving a file from the local system. This message shows the progress of the file transfer. At the highest link speed (115,000 baud), transfer speed is about 10K per second. Can't create file TFREMOTE can't create a file on the remote system. This can happen if there isn't enough room on the remote disk to transfer the executable program across the link. Can't modify .exe file You specified a file name to modify that is not a valid copy of the TFREMOTE utility. You can modify a copy of the TFREMOTE utility only with the -w option. Can't open .exe file to modify TFREMOTE can't open the file name you specified. You've probably entered an invalid filename. Download complete Your file has been successfully sent to TFREMOTE. 486 c++ User's Guide I Download failed, write error on disk TFREMOTE can't write part of a received file to disk. This usually happens when the disk fills up. You must delete some files before TFREMOTE can successfully download . the file. Enter program file name to modify If you are running on DOS version 3.0 or later, the prompt indicates the path and file name from which you executed TFREMOTE. You can accept this name (press Enter), or enter a new executable file name. If you're running DOS version 2.xx, you must supply the full path and file name of the executable program. Interrupted You pressed Ctrl+Breakwhile waiting for communications to be established with the other system. Invalid command-line option You gave an invalid command-line option when you started TDRF from the DOS command line. Link broken The program communicating with TFREMOTE has stopped and returned to DOS. Link established A program on the other system has just started to communicate with TFREMOTE. Loading program name from disk Turbo Profiler has told TFREMOTE to load a program from disk into memory in preparation for profiling. . No network present TFREMOTE is unable to detect a NETBIOS compatible network. Make sure you have loaded NETBIOS (version 3.0 or greater) and are connected to the network. Program load failed, EXEC failure DOS could not load the program into memory. This can happen if the program has become corrupted or truncated. Delete the program file from the remote system's disk to force Turbo Profiler to send a new copy over the link. If this message appears again after deleting the file, you should relink your program using TLINK on the local system and try again. Program load failed; not enough memory The remote system doesn't have enough free memory to load the program you want to profile. Program load failed; program not found TFREMOTE could not find the program on its disk. Program load successful TFREMOTE has finished loading the program Turbo Profiler wants to profile. Reading file name from Turbo Profiler This appears on your remote screen so that you know when a remote file is being sent to Turbo Profiler. C hap t e r 3 0, Rem 0 t e pro f iii n 9 487 Unknown request: message TFREMOTE has received an invalid request from the local system (where you're running Turbo Profiler). If you get this message, check that the link cable is in good working order. If you keep getting this error, try reducing the link speed (use the -rs command-line option). Waiting for handshake (press Ctrl+Breakto quit) TFREMOTE has started and is waiting for a program on the local system to start talking to it. To return to DOS before the other system initiates communication, press Ctrl+Break. WREMOTE messages Can't find configuration file You used the -c command-line option to specify a file that doesn't exist. Can't load WINDEBUG.DLL The dynamic link library WINDEBUG.DLL isn't in the current directory. WREMOTE requires this DLL in order to run. Can't open COMx serial port WREMOTE is trying to use a COM port that is either in use or doesn't exist. Invalid switch You specified an unknown option on the WREMOTE command line. No network present WREMOTE is unable to detect a NETBIOS compatible network. Make sure you've loaded NETBIOS (version 3.0 or greater) and are connected to the network. 488 c++ User's Guide Turbo Profiler for Windows Turbo Profiler for Windows (TPROFW) lets you profile applications you've written for Microsoft Windows, version 3.0 and higher. It runs under Windows on the same machine as the program you are profiling and switches between its own screens and your application's screens, just as Turbo Profiler does. You profile in Windows much as you would in DOS, except that you can also access information particular to Windows applications, such as • Messages received and sent by your application's windows • The complete list of modules loaded by Windows (including dynamic-link libraries) • Dynamic-link library (DLL) profiling TPROFW runs in Windows standard mode or 386 enhanced mode, which means that your computer must have an 80286 processor or higher and at least 1MB of memory. TPROFW.EXE supports several different video adapters through the use of several DLLs. After you've installed TPROFW, run TDWINI.EXE to help you select or modify the driver that's used with your setup. By default, TPROFW uses the SVGA.DLL video driver, which supports most video adapters and monitors. For more information on the available video DLLs, refer to the entries for DUAL8514.DLL, STB.DLL, SVGA.DLL, and TDWGUI.DLL in the online Help system of TDWINI.EXE. Like Turbo Profiler, TPROFW can also take advantage of a second monitor attached to your computer, allowing you to view TPROFW screens on one monitor and your application's screens on another. You select this display option by starting TPROFW with the -do command-line switch or by running the TFINST utility and setting User Screen Updating to Other display. C hap t e r 3 1, T u r boP r 0 f i I e r for Win dow s 489 Installing TPROFW When you install Turbo Profiler on your system, the installation program puts the following two Windows-related files in the same directory as your Turbo Profiler files: • TPROFW.EXE, the TPROFW program • TFWHELP.TFH, the TPROFW help files The installation process creates an icon for TPROFW and installs it in the Windows Program Manager group for your Borland language. You can run TPROFW by choosing the icon, just as you can with any other Windows application. Installing TDDEBUG.386 The TDDEBUG.386 file on your installation disks provides the same functionality as the Windows SDK file WINDEBUG.386. In addition, it provides better support than WINDEBUG.386 for the Ctrl+Alt+SysRq key combination (used to break out of a Windows application and return to TPROFW). The installation program should copy this file to your hard disk and alter your Windows SYSTEM.INI file so that Windows loads TDDEBUG.386 instead of WINDEBUG.386. If, for some reason, the installation program can't complete this task, you'll have to do it by hand as follows: 1 The installation program will have copied TDDEBUG.386 from the installation disks to your hard disk. The standard directory for this file is C: \ WINDOWS. If you move the file to another directory, substitute that directory in the instructions. 2 With an editor, open the Windows SYSTEM.IN! file, search for [386enh}, and add the following line to the 386enh section: device=c:\windows\ddebug.386 3 If there's a line in the 386enh section that loads WINDEBUG.386, either comment the line out with a semicolon or delete it altogether. (You can't have both TDDEBUG.386 and WINDEBUG.386 loaded at the same time.) For example, if you load WINDEBUG.386 from the C: \ WINDOWS directory, the commented-out line would be ;device=c:\windows\windebug.386 Configuring TPROFW Just as with Turbo Profiler, you can configure TPROFW two ways: by entering command-line options or by using the TFINST utility. 490 C++ Use r 's G u ide Using TPROFW command-line options You can set the configuration of TPROFW by using various command-line options followed by an optional program name with its own command-line options. The program name can be preceded by a path name. Because TPROFW is a Windows program, you will probably enter any command-line options either by using the Program Manager's File I Run command or by using the Program Manager's File I Properties command to change the command-line property of the TPROFW icon. You can also start Windows and TPROFW from the DOS command line. Follow the Windows command with the TPROFW command, optionally followed by switches or a program name (with or without switches). The command-line syntax for TPROFW is TPROFW [options] [program-name [program-args]] Table 31.1 provides a summary of the command-line options for TPROFW: Table 31.1 TPROFW command-line options -b Uses batch-mode profiling. -bcount -cfilename -do -ds Use batch-mode profiling, and run the progrm count number of times. Uses configuration file filename. Runs TPROFW on the secondary display. Updates screens by swapping pages. -p Uses a mouse. If the mouse driver is disabled for Windows, it will be disabled for TPROFW as well, and the -p command-line option will have no effect. -sc Ignores case for symbol names. -sddir[;dir... ] Sets· one or more source file directories. -tdir Sets the starting directory. See Chapter 28, "Turbo Profiler's command-line options," for a complete description of the command-line options. Note The command-line option -t is available only with TPROFW. This option changes TPROFW's starting directory, which is where TPROFW looks for the configuration file and for .EXE files not specified with a full path. The syntax is -tdirname You can set only one starting directory with this option. If you enter this command more than once on the same command line, TPROFW uses only the last entry. Using TFINST with TPROFW To use TFINST with TPROFW, start TFINST using the -w command-line option. TFINST for TPROFW works just like TFINST for Turbo Profiler, except that the default C hap t e r 3 1, T u r boP r 0 f i I e r for Win dow s 491 configuration file is TFCONFIG.TFW and fewer options are available. (See the list of TPROFW command-line options in the previous section.) For a description of how to use TFINST, see Chapter 29, "Customizing Turbo Profiler." Using TPROFW When you load TPROFW, it comes up in full-screen DOS character mode, not in a DLL (unless you're using the TDWGULDLL video driver). Unlike other applications that run under Windows, you can't use the Windows shortcut keys (like Alt+Esc or Ctrl+Esc) to switch out of TPROFW and run another application. However, if the application you are profiling is active (the cursor is active in one of its windows), you can use these keys or the mouse to switch to other programs. Note If you do use Ctrl+Esc to switch out of an application running under TPROFW, you see the application name on the list of tasks. You will never see TPROFW on the task list because TPROFW is not a normal Windows task that you can switch into or out of. Profiling using TPROFW is pretty much the same as profiling using Turbo Profiler. However, there are some differences: • Switching from your application to TPROFW is accomplished by using the Ctrl+Alt+SysRq key combination. This operation is similar to using Ctrl+Break to switch out of a DOS application and back to Turbo Profiler, except that the DOS application terminates, while the Windows application is only suspended. • If possible, run your application to completion or use the System command to exit it before exiting TPROFW or loading in another program to be profiled. Failing to exit a Windows application properly can leave resources allocated that would otherwise have been deallocated, potentially causing problems with TPROFW or other applications. • The DOS Shell command from the File menu is not available. • The Edit command on the Module and Text File SpeedMenus are not available. • Interrupts, File I/O, and Overlay windows are not available. • Display Swapping settings are not available in the Display Options dialog box. Profiling window procedures TPROFW keeps track of routines inside window procedures by tracking the message classes called by the routine and window messages sent to the procedures. Before message classes and window messages can be tracked, you must first specify that an area marker represents a window procedure. Specifying a window procedure area marker is done from either the Module window's SpeedMenu I Operation command, or the Areas window SpeedMenu I Option command. 492 C++ Use r 's G u ide The Window Procedure Messages dialog box After an area marker is specified as a window procedure marker, you must then select which messages and classes you want to track for that particular procedure. When Messages is selected from either the Module window's SpeedMenu I Operation command or the Areas window SpeedMenu I Option command, the Window Procedure Messages dialog box is displayed. With the Window Procedure Messages dialog box, you can select the window messages / and message classes that are tracked for the current area marker. TPROFW, by default, tracks all message classes. The Window Procedure Messages dialog box uses check boxes and text boxes for the following: • The Window Messages list box displays specially selected window messages. • Message Name is a text box that accepts a window message name or window message number. Use the Add command to append the specified message to the Window Messages list. Turbo Profiler will recognize only window message names that begin with WM_. If you wish to track a message other than a WM_ message, you must provide the window message number (window message numbers are acquired from either your program source files or from the windows header include files). Window message names are case sensitive. • Delete removes the currently highlighted message from the Window Messages list box. • Remove All deletes all specially selected messages from the Window Messages list box. When this command is selected, the Window Messages list box will be cleared of all entries. • Add All selects all WM_ messages from all classes. Each message is listed in the Window Messages list box after this command is chosen. Because so many messages come through, you'll probably want to narrow the focus by selecting only the classes of interest from the list of message names. Note Before selecting Add All, ensure the Max Windows Messages setting (Statistics I Profiling Options) has been adjusted to accommodate the number of messages you want to track. Including all message classes, there are over 140 WM_ messages. • Add appends the message name specified in the Message Name text box to the Window Messages list. • The Message Classes check boxes allow you to choose specific classes of messages to watch. When a specific Windows message class is selected, all WM_ messages from that class will be tracked. C hap t e r 3 1, T u r boP r 0 f i I e r for Win dow s 493 Table 31.2 describes the window message classes: Table 31.2 Window's message classes All Messages Mouse All messages starting with WM_. Messages generated by a mouse event (for example, WM_LBUITONDOWN and WM_MOUSEMOVE). Window Input Messages from the window manager (for example, WM_PAINT and WM_CREATE). Messages generated by a keyboard event or by the user's accessing a System menu, scroll bar, or size box (for example, WM_KEYDOWN). Messages generated by a system-wide change (for example, WM_FONTCHANGE and WM_SPOOLERSTATUS). Messages generated when an application creates a dialog box or a window (for example, WM_INITDIALOG and WM_INITMENU). System Initialization Clipboard Messages generated when one application tries to access the Clipboard of a window in another application (for example, WM_DRAWCLIPBOARD and WM_SIZECLIPBOARD). DDE Dynamic Data Exchange messages, generated by applications communicating with one another's windows (for example, WM_DDE_INITIATE and WM_DDE_ACK). Non-client Messages generated by Windows to maintain the non-client area of an application window (for example, WM_NCHITTEST and WM_NCCREATE). Any messages starting with.WM_ that don't fall into any of the other categories, such as owner draw control messages and multiple document interface messages. Other For a complete list of all WM_ messages, refer to your Borland compiler's online Help. Note When you've selected the appropriate window messages, profile your program as usual. To view window message statistics, choose Window Procedures from the Display Options dialog box, accessed through the Execution Profile SpeedMenu. Profiling dynamic-link libraries (OLLs) A DLL (dynamic-link library) is a Windows library of routines and resources that is linked to your application at run time instead of at compile time. This run-time linking allows multiple applications to share a single copy of routines, data, or device drivers, thus saving on memory usage. When an application that uses a DLL starts up, Windows loads it in memory so the application can access the DLL's entry points (if the DLL isn't already loaded into memory). TPROFW can load a DLL that doesn't have a symbol table, but only into a CPU window. When you load an application with DLLs linked to it, TPROFW determines which of these DLLs, if any, have symbol tables (were compiled with the debugging option turned on) and tracks them for you. TPROFW automatically loads in the symbol table and source of every DLL that's linked to your application, but only if the DLL has a compatible symbol table. A DLL has a symbol table compatible with TPROFW if it was compiled with debugging information turned on and the compiler was one of Borland's C++ Windows compilers, or Turbo Assembler. 494 C++ Use r 's G u ide Note DLLs that are loaded via the LoadLibrary call will not be automatically tracked by Turbo Profiler. To track these DLLs, you must set a Stop area marker after the LoadLibrary call. When the profiler encounters this area marker, you'll be able to access the DLL through the Module command on the Module window's SpeedMenu, or through View IModule. You'll need to set up a stop area on the last line of the DLL function in order to view the DLL's statistics. If you don't set the stop area, you will not be able to view or analyze the statistics. Because the symbol table for the DLL is not associated with the symbol table for the executable program, Turbo Profiler will produce a separate statistics file (.TFS) and a separate areas file (.TFA) for each DLL profiled. TPROFW error messages There is only one error message returned solely by TPROFW. In addition to this error message, Turbo Profiler error messages can also be returned. Ctrl+Alt+SysRq interrupt. System crash possible, Continue? You attempted either to exit TPROFW or to reload your application program while the program was suspended as a result of your having pressed Ctrl+Alt+SysRq. Because Windows kernel code was executing at the time you suspended the application, exiting TPROFW or reloading the application will have unpredictable results (most likely hanging the system and forcing a reboot). C hap t e r 3 1, T u r boP r 0 f i I e r for Win dow s 495 496 C++ Use r 's G u ide Prompts and error messages Turbo Profiler displays messages and prompts at the current cursor location. This chapter describes the prompts and error and information messages Turbo Profiler generates. We tell you how to respond to both prompts and error messages. All the prompts and error messages are listed in alphabetical order, with a description provided for each one. Turbo Profiler prompts Turbo Profiler displays a prompt in a dialog box when you must supply additional information to complete a ,command. The prompt describes the information that's needed. The contents may show a history list of previous responses that you have given. You can respond to a prompt in one of two ways-: • Enter a response and accept it by pressing Enter. • Press Esc to cancel the dialog box and return to the menu command that opened it. Some prompts only present a choice between two items (like Yes/No). You can use Tab to select the choice you want and then press Enter, or press Yor N directly. Cancel the command by pressing Esc. For a more complete discussion of the keystroke commands to use when a dialog box is active, refer to Chapter 25, "The Turbo Profiler environment." Here's an alphabetical list of all the prompts and messages generated by dialog boxes: Enter code label to position to Enter the address you wish to examine in the Disassembly pane. The Disassembly pane shows the disassembled instructions at the specified address. Enter command line arguments Enter the command-line arguments for the program you're profiling. You can modify the current command-line arguments or enter a new set. C hap t e r 3 2, Pro m p t san d err 0 r m e s sag e s 497 You will then be prompted whether you want to reload your program from disk. Some languages or programs, such as programs written in C, require you to reload the program before the arguments take effect. Enter file name to restore from Enter the name of the file to restore the statistics from. If you specify an extension to the file name, it will be used. Otherwise the extension .TFS will be used. Enter file name to save areas to Enter the name of the file to save the current areas to. If you specify an extension to the file name, it will be used. Otherwise the extension .TFS will be used. ' Enter file name to save to Enter the name of the file to save the current statistics to. If you specify an extension to the file name, it will be used. Otherwise the extension. TFS will be used. Enter interrupt number Enter the number of the interrupt that you wish to track. Enter name of file to view Enter the name of a text file that you want to inspect. The file specified will be brought into the File window. Enter new directory Enter the new drive and/ or directory name that you want to become the current drive and directory. Enter new line number Enter a new line number to position the text file to. The first line in the file is line 1. If you specify a line number that is greater than the last line in the file, the file is positioned to the last line. Enter program name to load Enter the name of the program to load. If the program has the .EXE extension, you don't have to specify it; if the program has any other extension, you must supply it. If you supply a wildcard specification or accept the default *.EXE, a list of matching files is displayed for you to select from. Enter routine name to add Enter the name of the function you wish to include, exclude, or set. Enter search string Enter a character string to search for. You can use a simple wildcard matching facility to specify an inexact search string; for example, use * to match zero or more of any characters, and? to match any single character. Enter source directory list Enter the directory or directories to search for source files. If you want to enter more than one directory, separate the different directory paths with a space ora semicolon (;). These directories will be searched, in the order that they appear in this list, for your source files. 498 C++ Use r 's G u ide Pick a caller Pick a routine from the list of callers. You will then be positioned to that routine in the window that you picked from the previous menu. Pick a method name You have specified a routine name that can refer to more than one method in an object. Pick the correct one from the list presented, with the arguments you want. Pick a module Select a module name to view in the Module window. You are presented with a list of all the modules in your program. Either use the cursor keys to move to the desired module, or start typing the name of the module. As you type the module name, the highlight bar will move to the first module that matches the letters you typed. When the highlight bar is on the desired module, press Enter. Pick a source file . Pick a new source file to display in the Module window. The list shows all the source files that make up the module. . Pick interrupt Pick an interrupt from the list of interrupts built into Turbo Profiler. Pick macro to delete Pick a macro to erase from the list of defined macros. Reload program and change profiling mode? When you change the profiling mode from active or passive to coverage, or from coverage to active or passive, all current profile statistics will be erased. If you wish to save the statistics before changing modes, answer NO to this prompt and save the statistics to a .TFS file. Otherwise, answer YES to the prompt. Turbo Profiler error messages Turbo Profiler uses error messages to tell you about things you haven't quite expected. Sometimes the command you have issued cannot be processed. At other times the message warns that things didn't go exactly as you wanted. Error messages can be accompanied by a beep. You can tum the beep on or off in the customization program, TFINST. Already recording, do you want to abort? You are already recording a keystroke macro. You can't start recording another keystroke macro until you finish the current one. Press Yto stop recording the macro, N to continue recording the macro. Ambiguous symbol symbol name You have entered a 'member function or data item name and Turbo Profiler can't tell which of the multiple instances of this member you mean. This can happen when a member name is duplicated in two multiply inherited classes. Use the classname:: override to name explicitly the member you want. C hap t e r 3 2, Pro mp t san d err 0 r me s sag e s 499 Bad or missing configuration file name You have specified a nonexistent file name with the -c command-line option when you started Turbo Profiler. The built-in default configuration values are used instead. Bad interrupt number entered You have entered an invalid interrupt number. Valid interrupt numbers are 9 to FF. Bad module name module name The module name that you have entered does not exist. Can't execute DOS command processor Either there was not enough memory to execute the DOS command processor, or the command processor could not be found (the COMSPEC environment variable is either absent or incorrect). Make sure that the COMSPEC environment variable correctly specifies where to find the DOS command processor. Can't find filename.DLL You attempted to load a program that requires one or more DLLs, but TPROFW can't find one of them. Make sure your executable file and the DLLs it requires are in the same directory, then load the program again. Can't swap user program to disk The program being profiled could not be swapped to disk. There is probably not enough room on the disk to swap the program. You will not be able to edit any files or execute DOS commands until some more room is made available. Edit program not specified You tried to use the Edit SpeedMenu command from a Module or Disk File window, but you cannot edit the file because Turbo Profiler does not know how to start your editor. Use the configuration program TFINST to specify an editor. Error loading program Your program could not be loaded. The format of the .EXE does not match the operating system. Error printing statistics There was an error sending to the printer. Check that the printer is online and not out of paper. Error reading statistics file An error occurred while you were restoring the collected statistics. Make sure that the disk is ready. Error saving configuration Your configuration could not be saved to disk. The disk might be full, or there might be no more free directory entries in the root directory. You can use the File I DOS Shell command to go to DOS and delete a file or two to make room for the configuration file. Error swapping in user program, program reloaded An error occurred while you were reloading your program that was swapped to disk. This usually means that the swap file was accidentally deleted. 500 c++ User's Guide You will have to reload your program using the Run IProgram Reset command before you can continue profiling. Error writing statistics file An error occurred while you were writing to the statistics file that stores your program statistics. Your disk is probably full. Make sure that the disk is ready and that there is enough room on the disk. Exception N, error code N Turbo Profiler encountered either an invalid memory reference or an invalid instruction in your program. You must correct the error before continuing profiling. Help file TFHELP.TFH not found You asked for help, but the disk file that contains the help screens could not be found. Make sure that the help file is in the same directory as Turbo Profiler. Invalid number entered The line number you specified is either a negative number, or contains an alphabetic character. Make sure you specify a positive integer as a line number. Invalid statistics file The file you specified to restore statistics from has an invalid format. Make sure the file name you specified was created using the Statistics ISave command. Invalid switch An invalid command-line option was encountered during program loading. Invalid window message number The window message that you have specified is not a valid name or number. Make sure that the message name is correctly spelled (window message names are case sensitive). Maximum number of areas has been reached There is no more room to add areas. Use the Options INumber of Areas command to increase the amount of memory set aside for areas. Maximum number of interrupts being monitored You can't watch any more interrupts; you have already told Turbo Profiler to watch as many interrupts as it is capable of doing. You will have to use the SpeedMenu Remove command to remove an existing interrupt before you can add any more. Maximum number of windows messages has been reached By default, Turbo Profiler sets the maximum number of window messages. If you attempt to track more than the number of messages specified in the Max Windows Messages text box (found through the Statistics IProfiling Options command), you'll receive this error message. When cited with this error message, no window messages will be added to the list by Turbo Profiler. Make sure to reset the Max Windows Messages count to reflect the number of messages that you want to watch, and then add the appropriate messages through the Window Procedure Messages dialog box. NMI interrupt The program you're profiling has generated an NMI (non-maskable interrupt). C hap t e r 3 2, Pro mp t 5 and err 0 r m e 5 5 age 5 501 No help for this context You pressed F1 to get help, but Turbo Profiler could not find a relevant help screen. Please report this to Borland Technical Support. No file name was given You have indicated that you wish to output a file, but you have not specified a file name. You must either specify a file name or switch to another output location before you can leave the dialog box. No modules with statistics There are no modules with any statistics collected, so there is nothing to print. No network present You must load NETBIOS (version 3.0 or above) before running TPROF or TFREMOTE with the -m option. No previous search expression You have used the Next command from the SpeedMenu of a text pane, without previously issuing a Search command. First use Search to specify what to search for, then use Next to look for subsequent instances. No program loaded You tried to issue a command that requires a program to be loaded. There are many commands that can be issued only when a program is loaded, for example, the commands in the Run menu. Use the File I Open command to load a program before issuing these commands. No source file for module module name The source file cannot be found for the module that you wish to view. The source file is searched for first in the current directory, and then in any directories specified in the configuration file and then in any directories specified by the command line -sd option. Not a code address You have entered an address that is not a code address in your program. You can set profiling areas only on code addresses. Not available when in coverage mode This error message appears when you attempt to use a function that can't be used in coverage mode. Most likely, you're trying to set (or remove) an area marker. Since Turbo Profiler automatically sets coverage mode markers, you can't set or remove them manually. Not enough memory for selected operation You issued a command that has to create a window, but there is not enough memory left for the new window. You must first remove or reduce the size of some of your windows before you can reissue the command. Also seethe -m option in Chapter 28, "Turbo Profiler's command-line options." Not enough memory to load program Your program's symbol table has been successfully loaded into memory, but there is not enough memory left to load your program. You can hook two systems together and run Turbo Profiler on one system and the program you're analyzing on the other. See Chapter 30, "Remote profiling," for more information on how to do this. 502 c++ User's Guide Not enough memory to load symbol table There is not enough room to load your program's symbol table into memory. The symbol table contains the information that Turbo Profiler uses to show you your source code and program variables. If you have any resident utilities consuming memory, you may want to remove them and then restart Turbo Profiler. You can also try making the symbol table smaller by having the compiler generate debug symbol information only for those modules you are interested in analyzing. When this message is issued, your program itself has not yet been loaded. This means you must free enough memory for both the symbol table and your program. Out of heap space Turbo Profiler ran out of memory to collect the information you requested. You'll need to reduce the amount of data that you want to gather in a single run. Overlay not loaded You have attempted to examine code in an overlay that is not loaded into memory. You can examine code only for overlays that are already in memory. However, you can still look at the source code for a module in a Module window. Setting an area's operation to stop will let you view the disassembled overlay. Overwrite existing macro on selected key You have pressed a key to record a macro, and that key already has a macro assigned to it. If you want to overwrite the existing macro, press Y; otherwise, press Nto cancel the command. Overwrite file name? You have specified a file name to write to that already exists. You can choose by entering Y to overwrite the file, replacing its previous contents, or you can cancel the command by entering N and leave the previous file unchanged. Path not found You entered a drive and directory combination that does not exist. Check that you have specified the correct drive and that the directory path is spelled correctly. The current drive and directory are left as they were before you issued the command. Premature end of string in symbol name The symbol name that you have entered is incomplete. If you specify a module name, it must be followed by either a line number or local symbol name. Press key to assign macro to Press the key that you want to assign the macro to. Then press the keys to do the command sequence that you want to assign to the macro key. The command sequence will actually be performed as you type it. To end the macro recording sequence, press the key you assigned the macro to. This macro will be recorded on disk along with any other keystroke macros. Procedure stack overflow Your program has too many nested procedure or function calls. You must remove some of the areas that are set on routines in the deepest calling path. Use the Callers window to find this area. Chapter 32, Prompts and error messages 503 Program does not have overlays The program you are profiling does not have any overlays, so you can't open an Overlay window. Program has invalid symbol table The program that you wish to load has a symbol table with an invalid format. Re-create your .EXE file and reload it. Program has no symbol table The program you want to analyze has been successfully loaded, but it does not contain any debug symbol information. Relink the program so that it has a symbol table. Program linked with wrong linker version The program you tried to load was linked with a linker whose version is incompatible with that of Turbo Profiler. Either the linker was an old one or you're using an old version of Turbo Profiler. Program not found The program you wish to load does not exist. Check that the name you supplied to the File IOpen command is correct and that you supplied a file-name extension if it is different from .EXE. Program out of date or missing on remote, send over link? You have specified a program to analyze on the remote system, but it either does not exist on the remote, or the file is newer on the local system than on the remote system. If you press Y, the program is sent across the link. If you press N, the program is not sent, and the File IOpen command is aborted. You'll usually respond with Y. If you are running the link at the slowest speed (using the -rsl command-line option), you might want to abort the command with N and transfer the file to the remote system using a floppy disk. Reload program so arguments take effect? With most programs, you must reload after changing their arguments. -. When you press Y, a Run IProgram Reset command is automatically performed for you. Reload program so new area count takes effect? In order for Turbo Profiler to reallocate the memory used for statistics areas, your program must be unloaded from memory and then reloaded and executed from the beginning again. Press Yto make this happen, or press Nif you can wait for the next manual program load for the new area size to take effect. Run out of space for keystroke macros There is not enough memory to record all your keystroke macro. Search expression not found The specified text string or byte list is not present in the file. Since the search proceeds forward from the current cursor position, you should return to the top of the file via the Ctrl+PgUp hot key, then repeat the search. 504 ett User's Guide Stopped by area Turbo Profiler encountered an area whose operation you set to "stop." You can continue profiling by using the Run IRun command. Symbol not a routine name The symbol name that you supplied is not a valid name of a routine. Symbol not found You have entered an expression containing an invalid symbol name. A valid symbol name consists of one of the following: • • • A global symbol name A module name, followed by #, followed by a local symbol name A module name, followed by a #, followed by a decimal line number Syntax error in symbol SymbolName You have entered an invalid symbol name. A valid symbol name consists of one of the following: • • • A global symbol name A module name, followed by #, followed by a local symbol name A module name, followed by a #, followed by a decimal line number Too many areas for a Windows program You've attempted to profile a program with more areas than the 511 supported by Windows. Some of the areas you set will not be profiled. You'll have to reduce the number of areas in order to control which areas are not included. Too many files match wildcard mask You specified a wildcard file mask that included more than 100 files. Only the first 100 file names are displayed. Unknown control point Turbo Profiler has encountered an 1NT 3 instruction in your program that it doesn't recognize. Because Turbo Profiler uses !NT 3 instructions to indicate control points, if you've put any in your program yourself, there will be a conflict. It's also possible that Turbo Profiler inserted a control point and then lost track of it. If you inserted the !NT 3 in your program, you'll have to remove it to run Turbo Profiler on your program. If you didn't put the !NT 3 in, then it's one of Turbo Profiler's. Removing the area containing the !NT 3 will allow you to continue profiling the program. Unable to determine procedure type Turbo Profiler can't determine whether the current area is a near or far procedure. You'll have to remove it from the list of areas for Turbo Profiler to proceed. Value must be between nn and nn You have entered an invalid numeric value for an editor setting (such as the tab width) or printer setting (such as the number of lines per page). The error message will tell you the allowed range of numbers. C hap t e r 3 2, Pro mp t 5 and err 0 r m e 5 5 age 5 505 Video mode switched while flipping pages You've started Turbo Profiler with a display updating mode that does not allow display pages to be saved, and the program that you are profi1ir1g has switched into a graphics mode. Turbo Profiler has changed the display mode back to text display, so the screen contents of the program you are profiling have been lost. To avoid this situation, start Turbo Profiler with display-swapping enabled (-ds command-line option). Waiting for remote driver. Press Esc to stop waiting You've started a remote profiling session, and Turbo Profiler is waiting to connect to the remote driver. Press Esc to about the remote session. 506 c++ User's Guide Error messages and warnings This appendix describes the error messages that can be generated by Borland C++. It begins by describing the four types of messages you can receive: fatal errors, errors, warnings, and informational messages. Next, it covers the different components that can generate messages: the compiler, the MAKE utility, the linker (TLINK), the librarian (TLIB), the integrated debugger, and the Windows Help compiler. This appendix also lists the errors that you can receive when you run your program (run-time errors). The remainder of the appendix lists messages ASCII alphabetic order and provides a description of each message that includes where the message was generated. Message categories Messages fall into four categories: fatal errors, errors, warnings, and informational messages. Fatal errors Fatal errors can be generated by the compiler, the linker, and the MAKE utility. Fatal errors cause the compilation to stop immediately; you must take appropriate action to fix the error before you can resume compiling. If the compiler or MAKE utility issues a fatal error, no .EXE file is created. If the linker issues a fatal error, any .EXE file that might have been created by the linker is deleted before the linker returns. Errors Errors can be generated by the compiler, the linker, the MAKE utility, and the librarian. In addition, errors can be generated by your program at run time. A Ppen d i x A, Err 0 r m e s sag e san d war n i n 9 s 507 Errors generated by the compiler indicate program syntax errors, command-line errors, and disk or memory access errors. Compiler errors don't cause the compilation to stop-the compiler completes the current phase of the compilation and then stops and reports the errors encountered. The compiler attempts to find as many real errors in the source program as possible during each phase (preprocessing, parsing, optimizing, and code-generating). Errors generated by the linker don't cause the linker to delete the .EXE or .MAP files. However, you shouldn't execute any .EXE file that was linked with errors. Linker errors are treated like fatal errors if you're compiling from the Integrated Development Environment (IDE). The MAKE utility generates errors when there is a syntax or semantic error in the source makefile. You must edit the makefile to fix these types of errors. Run-time errors are usually caused by logic errors in your program code. If you receive a run-time error, you must fix the error in your source code and recompile the program for the fix to take effect. Warnings Warnings can be issued by the compiler, the linker, and the librarian. Warnings do not prevent the compilation from finishing. However, they do indicate conditions that are suspicious, even if the condition that caused the warning is legitimate within the language. The compiler also produces warnings if you use machine-dependent constructs in your source files. Informational messages Informational messages inform you about the progress of tasks such as the status of a build. Message generators The messages in this appendix include messages that can be generated by the compiler, the MAKE utility, the linker (TLINK), the librarian (TLIB), the integrated debugger (IDE), and the Windows Help compiler. Run-time errors (errors you can receive when you run your program) are also included. Compiler errors and warnings Compile-time error messages indicate errors in program syntax, command-line errors, or errors in accessing a disk or memory. When most compile-time errors occurs, the compiler completes the current phase (preprocessing, parsing, optimizing, and codegenerating) of the compilation and stops. But when fatal compile-time errors happen, compilation stops completely. If a fatal error occurs, fix the error and recompile. Note 508 Be aware that the compiler generates messages as they are detected. Because C and C++ don't force any restrictions on placing statements on a line of text, the true cause of the C++ Use r 's G u ide error might be one or more lines before or after the line number mentioned in the error message. Warnings indicate that conditions which are suspicious but legitimate exist or that machine-dependent constructs exist in your source files. Warnings do not stop compilation. Warnings are issued as a result of a variety of conditions, such as: ANSI violations Warn you of code that is acceptable to Borland C++ (because of C++ code or Borland C++ extensions), but is not in the ANSI definition of C. Frequent warnings Alert you to common programming mistakes. These warning messages point out conditions that are not in violation of the Borland C++ language but can yield the wrong result. Less frequent warnings Alert you to less common programming mistakes. These warning messages point out conditions that are not in violation of the Borland C++ language but can yield the wrong result. Portability warnings Alert you to possible problems with porting your code to other compilers. These usually apply to Borland C++ extensions. C++ warnings Warn you of errors you've made in your C++ code. They might be due to obsolete items or incorrect syntax. Run-time erro,rs and warnings Run-time errors occur after the program has successfully compiled and is running. These errors are usuallycaused.by logic errors in your program code. If you receive a run-time error, you must fix the error in your source code and recompile the program for the fix to take effect. Linker errors and warnings As a rule, linker errors do not stop the linker or cause .EXE or .MAP files to be deleted. When such errors happens, don't try to execute the .EXE file. Fix the error and relink. A fatal link error, however, stops the linker immediately. In such a case, the .EXE file is deleted. All Linker errors are treated as fatal errors if you are compiling from the Integrated Development Environment (IDE). Linker warnings point out conditions that you should fix. When warnings occur, .EXE and .MAP files are still created. Appendix A, Error messages and warnings 509 Librarian errors and warnings Librarian errors and warnings occur when there is a problem with files or extended dictionaries, when memory runs low, or when there are problems as libraries are accessed. IDE debugger messages IDE debugger messages are generated by the integrated debugger and appear under the Runtime tab of the Message window; Many of these messages relate to options not set properly in the IDE integrated debugger screens. ObjectScripting error messages ObjectScripting error messages are messages that result from running scripts in the IDE. They appear under the Script tab in the Message window. Help compiler messages The Help compiler displays messages when it encounters errors or warnings while building the Help resource file. Messages generated during the processing of the project file begin with the letter P and are followed by an error number. Messages that occur during the processing of the RTF topic file(s) begin with the letter R and are followed by an error number. Whenever possible, the Help compiler displays the topic number and/ or the file name that contains the error. If you've numbered your topics, the topic number is given with an error message that refers to that topic's sequential position in your RTF file (first, second, and so on). These numbers might be identical to the page number shown by your word processor. In your Help source files, topics are separated by hard page breaks even though there are no "pages" in the Help system. Messages beginning with the word "Error" are fatal errors. Errors are always reported, and no usable Help resource file will result from the build. Messages beginning with the word "Warning" are less serious in nature. A build with warnings produces a valid Help resource file that loads under Windows, but the file might contain operational errors. Message formats Messages are displayed with the message class first, followed by the source file name and line number where the error was detected, and finally with the text of the message itself. Many of the messages appear in the Message view. For those messages, contextsensitive help is available. Point to the message and press FI to display the message description. 510 C++ Use r 's Gu ide If you are working from the command line or want to look up information on an error message, refer to the alphabetical list of error and warning messages in "Alphabetical list of messages" later in this chapter. Find the message you're interested in and click on it to display its description. Symbols in messages Some messages include a symbol (such as a variable, file name, or module) that is taken from your program. In the following example, 'filename' will be replaced by the name of the file causing the problem: Error opening 'filename' for output Table A.I describes what the symbols in error and warning messages stand for. Table A.1 argument base class constructor filename function group identifier language macroname member message module name number operator option parameter path reason segment size specifier symbol type variable Symbols that appear in error messages and warnings A hexadecimal number indicating the address where the error occurred An argument The name of a base element such as a base class A class name The name of a constructor such as a class constructor A file name (with or without extension) A function name A group name An identifier (variable name or other) . The name of a programming language The name of a macro The name of a data member or member function A message string A module name Any type of name An actual number The symbol for an operator such as ++ An option A parameter name A path name Reason given in message A segment name An actual number A type specifier A symbol name A type name A program variable A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 511 Alphabetical list of messages Messages are listedin·ASCII alphabetic order. Messages beginning with symbols come first, then messages beginning with numbers, and then messages beginning with letters of the alphabet. Messages that begin with symbols are alphabetized by the type of the symbols. For example, you might receive the following error message if you incorrectly declared your function myJune: myJunc must be declared with no parameters To find this error message, look under the alphabetized listing of "function." MAKE error ')' missing in macro invocation A left parenthesis is required to invoke a macro. ( expected Compiler message A left parenthesis was expected before a parameter list. ) expected Compiler message A right parenthesis was expected at the end of a parameter list. , expected Compiler message A comma was expected in a list of declarations, initializations, or parameters. This problem is often caused by a missing syntax element earlier in the file or one of its included headers. : expected after private/protected/private Compiler message When used to begin a private, protected, or public section of a C++ class, the reserved words "private," "protected," and "public" must be followed by a colon. < expected Compiler message The keyword template was not followed by <. Every template declaration must include the template formal parameters enclosed within < >, immediately following the template keyword. > expected Compiler message A new-style cast (for example, dynamic_cast) was found with a missing closing ">". @ seen, expected a response·files name Librarian message The response file name is not given immediately after @. { expected Compiler message A left brace was expected at the start of a block or initialization. } expected Compiler message A right brace was expected at the end of a block or initialization. 16·bit segments not supported in module 'module' Linker message 16-bit segments are not supported for Win32 applications. Check to make sure that you have not compiled the application with the 16-bit compiler. 512 C++ Use r' s G u ide 286/287 instructions not enabled Compiler message Use the 2 command-line compiler option or the 80286 option in the Options 1Project 116bit Compiler 1Processor settings to enable 286/287 opcodes. Be aware that the resulting code cannot be run on 8086- and 8088-based machines. 32-bit format in resource file. Please recompile. Resource Linker message The compiled resource (.RES) file you are trying to use with your application contains 32-bit resources, but the target type of your application is for 16-bit Windows. Recompile the resource file for Windows 3.1 or change the target type for your application to Win32. 32-bit processing not supported in overlays Linker message An invalid combination of 10 (overlays) and 13 (32-bit processing) was specified in the link command line. 32-bit record encountered Linker message An object file that contains 80386 32-bit records was encountered, and the /3 option was not used. Abnormal program termination Run-time message The program called abort because there wasn't enough memory to execute. This message can be caused by memory overwrites. Access can only be changed to public or protected Compiler message A C++ derived class can modify the access rights of a base class member, but only to public or protected. A base class member can't be made private. Added file 'filename' does not begin correctly, ignored Librarian message The librarian has decided that the file being added is not an object module. It will not try to add it to the library. The library is created anyway. Address of overloaded function 'function' doesn't match 'type' Compiler message A variable or parameter is assigned (or initialized with) the address of an overloaded function. However, the type of the variable or parameter doesn't match any of the overloaded functions with the specified name. Alias 'alias' defined in module 'module' is redefined in module module name Linker message A second definition to the alias was encountered, so the second alias is being used. Ambiguity between 'function1' and 'function2' Compiler message Both of the named overloaded functions could be used with the supplied parameters. This ambiguity is not allowed. Ambiguous member name 'name' Compiler message Whenever a structure member name is used in inline assembly, such a name must be unique. (If it is defined in more than one structure, all of the definitions must agree as to its type and offset within the structures). In this case, an ambiguous member name has been used. APpen d i x A, Err 0 r me s sag e san d war n i n 9 s 513 For example: struct A int a; int b; }; asm ax, .a; Ambiguous operators need parentheses Compiler message (Command-line equivalent for displaying this warillng = -wamb) This warillng is displayed whenever two shift relational, or bitwise-Boolean operators are used together without parentheses. Also, an addition or subtraction operator that appears without parentheses with a shift operator will produce this warning. Default = not displayed Ambiguous override of virtual base member 'baseJunction': 'derivedJunction' Compiler message A virtual function in a virtual base class was overridden with two or more different functions along different paths in the inheritance hierarchy. For example, struct VB virtual f(); }; struct A:virtual VB virtual f(); }; struct B:virtual VB virtual f(); Application is running Run-time message The application you tried to run is already running. For Windows, make sure the message loop of the program has properly terminated. PostQuitMessage(O); Array allocated using 'new' may not have an initializer Compiler message When initializing a vector (array) of classes, you must use the constructor that has no arguments. This is called the default constructor, which means that you can't supply constructor arguments when initializing such a vector. Array must have at least one element Compiler message ANSI C and C++ require that an array be defined to have at least one element (objects of zero size are not allowed). An old programming trick declares an array element of a structure to have zero size, then allocates the space actually needed with malloc. You can still use this trick, but you 514 c++ User's Guide must declare the array element to have (at least) one element if you are compiling in strict ANSI mode. Declarations (as opposed to definitions) of arrays of unknown size are still allowed. Example: char ray[]; char ray[O]; extern char ray[]; /* definition of unknown size -- ILLEGAL */ /* definition of 0 size -- ILLEGAL .*/ /* declaration of unknown size -- OK */ Array of references is not allowed Compiler message It is illegal to have an array of references, because pointers to references are not allowed and array names·are coerced into pointers. Array size for 'delete' ignored Compiler message (Command-line equivalent for displaying this warning = -wdsz) The c++ IDE issues this warning when you've specified the array size when deleting an array. With the new C++ specification, you don't need to make this specification. the compiler ignores this construct. This warning lets older code compile. Default = displayed Array size too large Compiler message The declared array is larger than 64K and the 'huge' keyword was not used. If you need an array of this size, either use the 'huge' modifier, like this: int huge array[70000L]; /* Allocate 140000 bytes */ or dynamically allocate it with farmalloc() or farcalloc( ),like this: int huge *array = (int huge *) farmalloc (sizeof (int) * 70000); ?? Allocate 140,000 bytes Array variable 'identifier' is near Compiler message (Command-line equivalent for displaying this warning = -wias) When you use set the Far Data Threshold option, the compiler automatically makes any global variables that are larger than the threshold size be far. When the variable is an initialized array with an unspecified size, its total size is not known when the compiler must decide whether to make it near or far, so the compiler makes it near. The compiler issues this warning if the number of initializers given for the array causes the total variable size to exceed the data size threshold. If the fact that the compiler made the variable be near causes problems, make the offending variable explicitly far. To do this, insert the keyword 'far' immediately to the left of the variable name in its definition. Default = displayed A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 515 Assembler stack overflow Compiler message The assembler ran out of memory during compilation. Review the portion of code flagged by the error message to ensure that it uses memory correctly. Assembler statement too long Compiler message Inline assembly statements can't be longer than 480 bytes. Assigning 'type' to 'enumeration' Compiler message (Command-line equivalent for displaying this warning = -weas) Assigning an integer value to an enum type. This is an error in C++, but is reduced to a warning to give existing programs a chance to work. Default = displayed Assignment to 'this' not allowed, use X::operator new instead Compiler message In early versions of C++, the only way to control allocation of class of objects was by assigning to the 'this' parameter inside a constructor. This practice is no longer allowed, because a better, safer, and more general technique is to define a member function operator new instead. For example: this = malloc(n); Attempt to export non-public symbol 'symbol' Linker message A symbol name was listed in the EXPORTS section of the module definition file, but no symbol of this name was found as public in the modules linked. If compiling in C++ mode, this is usually caused by the name mangling that occurs as a result of C++'s type safe linkage. Inserting the _export keyword in the function protoo/,Pe and function definition is required for all C++ Windows callback functions. Language-independent causes result from a mistake in spelling or case, case-sensitive exports, or a procedure with this name that was not defined. If you are using case sensitive exports, the Pascal calling convention used by Windows requires these symbols to be all upper-case characters. Attempt to export non::-public symbol 'symbol' Linker message The EXPORTS section in the .DEF file specified the name of a symbol which has no public definition. Attempt to grant or reduce access to 'identifier' Compiler message A C++ derived class can modify the access rights of a base class member, but only by restoring it to the rights in the base class. It can't add or reduce access rights. Attempting to return a reference to a local object Compiler message You attempted to return a reference to a temporary object in a function that returns a reference type. This may be the result of a constructor or a function call. This object will disappear when the function returns, making the reference illegal. 516 C++ Use r' s G u ide Attempting to return a reference to local variable 'identifier' Compiler message This C++ function returns a reference type, and you are trying to return a reference to a local (auto) variable. This is illegal, because the variable referred to disappears when the function exits. You can return a reference to any static or global variable, or you can change the function to return a value instead. Automatic data segment exceeds 64K Linker message The sum of the DGROUP physical segment, local heap, and stack exceeded 64K. You need to either specify smaller values for the HEAPSIZE and STACKSIZE statements in the module definition file, or decrease the size of your near data in DGROUP. The map file will show the sizes of the component segments in DGROUP. Bad character in parameters -> 'char' Linker message One of the following characters was encountered in the command line or in a response file: * < >? [ 1 I or any control character other than horizontal tab, line feed, carriage return, or Ctrl+Z. Bad 'directive' directive syntax Compiler message A macro definition starts or ends with the ## operator, or contains the # operator that is not followed by a macro argument name. An example of this might be: Bad ifdef directive syntax Note that an #ifdef directive must contain a single identifier (and nothing else) as the body of the directive. Another example is: Bad undef directive syntax An #Undef directive must also contain only one identifier as the body of the directive. Bad call of intrinsic function Compiler message You have used an intrinsic function without supplying a prototype. You may have supplied a prototype for an intrinsic function that was not what the compiler expected. Bad EXE header format in file. Executable format not recognized in file. Resource Linker message The executable file contained invalid information in its header. The file might not be a valid executable or might contain corrupted data. Bad EXE segment table in file. Resource Linker message The executable file contained invalid information in its segment table. The file might not be a valid executable or might contain corrupted data. Bad field list in debug information in module 'module' Linker message This is typically caused by bad debug information in the OBJ file. Borland Technical Support should be informed. Linker message Bad file name 'filename' An invalid file name was passed to the linker. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 517 Bad file name format in include directive Bad file name format in line directive Compiler message Include and line directive file names must be surrounded by quotes (" f i 1 ename . h") or angle brackets « f i 1 ename . h> ). The file name was missing the opening quote or angle bracket. If a macro was used, the resulting expansion text is not surrounded by quote marks. Bad filename format in include statement MAKE message Include file names must be surrounded by quotes or angle brackets. The file name was missing the opening quote or angle bracket. Bad GRPDEF type encountered, extended dictionary aborted Librarian message The librarian has encountered an invalid entry in a group definition (GRPDEF) record in an object module while creating an extended dictionary. The only type of GRPDEF record that the librarian and the linker support is segment index type. If any other type of GRPDEF is encountered, the librarian can't create an extended dictionary. It is possible that an object module created by products other than Borland tools can create GRPDEF records of other types. A corrupt object module can also generate this warning. Bad header in input LIB Librarian message When adding object modules to an existing library, the librarian found a bad library header. Rebuild the library. Bad LF_POINTER in module 'module' Linker message This is typically caused by bad debug information in the OBJ file. Borland Technical Support should be informed. Bad line number 'linenumber' IDE Debugger message You tried to add a source breakpoint at a specific line number but you typed an invalid line number. Use the IDE Debugger and correct the line number in the Add Breakpoint dialog box. Breakpoints must be set on executable lines of code. Bad loc for fixup in module 'module' near file offset 'offset' Linker message The linker encountered an object file with an incompatible .OBJ file format. This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Bad macro output translator MAKE message Invalid syntax for substitution within macros. Bad object file 'filename' near file offset 'offset' Linker message The linker has found a bad OBJ file. This is usually caused by a translator error. 518 C++ Use r 's G u ide Bad object file record Bad object file record in library file 'filename' near module file offset 'Oxxxxxxxxx' Bad object file record in library file 'filename' in module 'module' near module file offset 'Oxxxxxxxxx' An ill-formed object file was encountered. Linker messages This is most COmlnonly caused by specifying a source file, by naming an object file that was not completely built, or by corrupting the response file so that a non-OBI file is included in the .OB] file list or library file list. This can occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Bad OMF record type 'type' encountered in module 'module' Librarian message The librarian encountered a bad Object Module Format (OMF) record while reading through the object module. Because the librarian has already read and verified the header records in 'module', the object module is probably corrupt. Recreate it. Bad secondary target for fixup in module 'module' Linker message The linker encountered an object file with an incompatible .OB] file format. This error generally occurs due to an incompatible .OB] file format. If you're linking .OB] files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Bad syntax for pure function definition Compiler message Pure virtual functions are specified by appending "= 0" to the declaration, like this: class A { virtual voidf () = OJ} class B : public A { void f () {}j } You wrote something similar, but not quite the same. Bad 'type' debug info in module 'module' Linker message The linker encountered an object file with an incompatible .OB] file format. This error generally occurs due to an incompatible .OB] file format. If you're linking .OB] files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Bad undef statement syntax MAKE message An !undef statement must contain a single identifier and nothing else as the body of the statement. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 519 Base class 'class' contains dynamically dispatchable functions Compiler message This error occurs when a class containing a DDVT function attempts to inherit DDVT functions from multiple parent classes. Currently, dynamically dispatched virtual tables do not support the use of multiple inheritance. Base class 'class' is included more than once Compiler message A C++ class can be derived from any number of base classes, but can be directly derived from a given class only once. Base class 'class' is initialized more than once Compiler message In a C++ class constructor, the list of initializations following the constructor header includes base class 'class' more than once. Base class 'class1' is also a base class of 'class2' (Command-line equivalent for displaying this warning = -wibc) Compiler message A class inherits from the same base class both directly and indirectly. It is best to avoid this non-portable construct in your program code. Default = displayed Base initialization without a class name is now obsolete (Command-line equivalent for displaying this warning = -wobi) Compiler message Early versions of C++ provided for initialization of a base class by following the constructor header with just the base class constructor parameter list. It is now recommended to include the base class name. This makes the code much clearer, and is required when you have multiple base classes. Old way: derived::derived(int i) (i, 10) { ... } New way: derived::derived(int i) base(i, 10) { ... } Default = displayed 'base' is an indirect virtual base class of 'class' You can't create a pointer to a C++ member of a virtual base class. Compiler message You have attempted to create such a pointer (either directly, or through a cast) and access an inaccessible member of one of your base classes. Bit field cannot be static Compiler message Only ordinary C++ class data members can be declared static, not bit fields. Bit field too large This error occurs when you supply a bit field with more than 16 bits. Compiler message Bit fields must be signed or unsigned int Compiler message In ANSI C, bit fields may only be signed or unsigned int (not char or long, for example). Bit fields must be signed or unsigned int (Command-line equivalent for displaying this warning = -wbbf) 520 C++ Use r 's Gu ide Compiler message In ANSI C, bit fields may not be of type signed char or unsigned char. When you're not compiling in strict ANSI mode, the compiler allows these constructs, but flags them with this warning. Default = not displayed Bit fields must contain at least one bit Compiler message You can't declare a named bit field to have 0 (or less than 0) bits. You can declare an unnamed bit field to have 0 bits. This is a convention used to force alignment of the following bit field to a byte boundary (or to a word boundary, if you choose the or tum on the Word Alignment option in the Code Generation dialog box. Bit fields must have integral type Compiler message In C++, bit fields must have an integral type. This includes enumerations. Block overflow for block 'block' Linker message This message results from one of the linker's internal tables overflowing. The internal linker tables contain information such as linker or debugging data. The tables are set to a default size which was not sufficient for the data in your application. When this error occurs, the linker emits an IN! file called TLINK32.INI and includes the name of the block that overflowed along with its size. Edit the INI file and increase the size. The .DEF file is ill formed. You typed an illegal import sequence in the .DEF file. Body has already been defined for function 'function' Compiler message A function with this name and type was previously supplied a function body. A function body can only be supplied once. One cause of this error is not declaring a default constructor which you implement. For example: class A { public: virtual myex ( ) i } i A: :A() {} / / error Having not seen you declare the default constructor in the class declaration, the compiler has had to generate one, thus giving the error message when it sees one. this is a correct example: class A { public: A()i virtual myex()i } i A::A() {} Compiler message Both return and return of a value used (Command-line equivalent for displaying this warning = -wret) Appendix A, Error messages and warnings 521 The current function has return statements with and without values. This is legal C, but almost always an error. Possibly a return statement was omitted from the end of the function. Default = displayed Call of nonfunction Compiler message The name being called is not declared as a function. This is commonly caused by incorrectly declaring the function or misspelling the function name. Call to function 'function' with no prototype Compiler message This message is given if the "Prototypes required" warning is enabled and you call function 'function' without first giving a prototype for that function. Call to function with no prototype Compiler message (Command-line equivalent for displaying this warning = -wpro) This message is given if the "Prototypes required" warning is enabled and you call a function without first giving a prototype for that function. Default = displayed Call to undefined function 'function' Compiler message Your source file declared the current function to return some type other than void in C++ (or int in C), but the compiler encountered a return with no value. All int functions are exempt in C because in old versions of C, there was no void type to indicate functions that return nothing. Can't convert 'string' [which evaluates to 'result'] to an address IDE Debugger message The debugger dialog was expecting a memory address as input and it couldn't interpret the user input as a valid address. Can't debug during asynchronous compile IDE Debugger message . While compiling code with the Environment I Process Control I Asynchronous option set, you tried to issue a debugger command. Because the compiler is not re-entrant and the debugger and browser use the compiler code, you cannot debug or browse while an asynchronous (background) compile is taking place. Can't evaluate 'expression:' 'reason' IDE Debugger message The expression you tried to evaluate did not return a valid value. This error will be given any time invalid input is entered in a debugger dialog and there is no more information about the error. Every debugger dialog uses the debugger's evaluator to validate and interpret user input. Can't grow LEiLIDATA record buffer Librarian message Command-line error. The librarian is attempting to read a record of data from the object module, but it cannot get a large enough block of memory. If the module being added has a large data segment or segments, try adding this module before other modules. 522 C++ Use r 's G u ide Can't inherit non-RITI class from RITI base Can't inherit RITI class from non-RITI base Compiler messages When virtual functions are present, the RTTI attribute of all base classes must match that of the derived class. Can't inspect 'itemname' IDE Debugger message You specified an invalid item for inspection. Can't navigate to address 0 IDE Debugger message You are trying to bring up a source view on an address that evaluates to O. Can't run to 'filename', line 'linenumber' IDE Debugger message You tried to run the specified line of the specified file. Either the file does not exist or there is no executable code associated with the line.' Cannot access an inactive scope Compiler message You have tried to evaluate or inspect a variable local to a function that is currently not active. (This is an integrated debugger expression evaluation message.) Cannot add or subtract relocatable symbols Compiler message The orily arithmetic operation that can be performed on a relocatable symbol in an assembler operand is addition or subtraction of a constant. Variables, procedures, functions, and labels are relocatable symbols. Cannot allocate a reference Compiler message You have attempted to create a reference using the new operator. This is illegal, because references are not objects and can't be created through new. Cannot call 'main' from within the program Compiler message C++ does not allow recursive calls of main( ). Cannot call near class member function with a pointer of type 'type' Compiler message Member functions of near classes can't be called via a member pointer. This also applies to calls using pointers to members. (Remember, classes are near by default in the tiny, small, and medium memory models.) Either change the pointer to be near, or declare the class as far. Cannot cast from 'type1' to 'type2' Compiler message A cast from type 'identl' to type 'ident2' is not allowed. In C++, you cannot cast a member function pointer to a normal function pointer. For example: class A { public: int myex(); }; typedef int (*fp) (); test() { fp myfp - (fp) &A: :myex; //error The reason being that a class member function takes a hidden parameter, the this pointer, thus it behaves very differently than a normal function pointer. A Ppen d i x A, E rr 0 r me s sag e san d war n i n 9 s 523 A static member function behaves as normal function pointer and can be cast. For example: class A { public: static int myex(); }; typedef int (*fp) (); test() { fp myfp - (fp) &A::myex; Ilok However, static member functions can only access static data members of the class. InC: • A pointer can be cast to an integral type or to another pointer. • An integral type can be cast to any integral, floating, or pointer type. • A floating type can be cast to an integral or floating type. Structures and arrays can't be cast to or from. You usually can't cast from a void type. In C++: • User-defined conversions and constructors are checked for. If one can't be found, the preceding rules apply (except for pointers to class members). • Among integral types, only a constant zero can be cast to a member pointer. • A member pointer can be cast to an integral type or to a similar member pointer. A similar member pointer points to a data member (or to a function) if the original does. The qualifying class of the type being cast to must be the same as (or a base class of) the original. Cannot convert 'type1' to 'type2' Compiler message An assignment, initialization, or expression requires the specified type conversion to be performed, but the conversion is not legal. In C++, the compiler will convert one function pointer to another only if the signature for the functions are the same. Signature refers to the arguments and return type of the function. For example: myex( int ); typedef int ( *ffp ) ( float ); test () { ffp fp = myex; Ilerror Seeing that myex takes an int for its argument, and fp is a pointer to a function which takes a float as argument, the compiler will not convert it for you. In cases where this is what is intended, performing a typecast is necessary: myex( int ); typedef int ( *ffp ) ( float ); test() 524 C++ Use r 's G u ide ffp fp = (ffp)myex; Ilak Cannot create instance of abstract class 'class' Compiler message Abstract classes (those with pure virtual functions) can't be used directly, only derived from. When you derive an abstract base class, with the intention to instantiate instances of this derived class, you must override each of the pure virtual functions of the base class exactly as they are declared. For example: class A { public: virtual myex( int ) = 0; virtual twa ex ( canst int ) canst 0; }; class B : public A public: myex( int ); twaex( canst int ); }; B b; II errar The error occurs because we have not overridden the virtual function which twoex can act on canst objects of the class. We have created a new one which acts on non-canst objects. This would compile: class A { public: virtual myex( int ) = 0; virtual twaex( canst int ) canst 0; }; class B : public A public: myex( int ); twaex( canst int ) canst; }; B b; I I ak Cannot create pre-compiled header: 'reason' Compiler message This warning is issued when pre-compiled headers are enabled but the compiler could not generate one, for one of the following reasons: write failed code in header The compiler could not write to the pre-compiled header file. This is usually because the disk is full. One of the headers contained a non-inline function body. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 525 initialized data in header header incomplete One of the headers contained a global variable definition (in C, a global variable with an initializer; in C++ any variable not declared as 'extern'). The pre-compiled header ended in the middle of a declaration, for example, inside a class definition (this often happens when there is a missing "}" in a header file). Cannot declare or define 'identifier' here Compiler message You tried to declare a template in an illegal place or a namespace member outside of its namespace. Cannot define 'identifier' using a namespace alias Compiler message You cannot use a namespace alias to define a namespace member outside of its namespace. Cannot define a pointer or reference to a reference It is illegal to have a pointer to a reference or a reference to a reference. Compiler message Cannot evaluate function call Compiler message The error message is issued if someone tries to explicitly construct an object or call a virtual function. In integrated debugger expression evaluation, calls to certain functions (including implicit conversion functions, constructors, destructors, overloaded operators, and inline functions) are not supported. Cannot find 'class::class' ('class'&) to copy a vector Cannot find 'class'::operator=('class'&) to copy a vector Cannot find class::class ... Compiler messages When a C++ class 'class1' contains a vector (array) of class 'class2', and you want to construct an object of type 'class1' from another object of type 'class 1', you must use this constructor: class2::class2(class2&) so that the elements of the vector can be constructed. The constructor, called a copy constructor, takes just one parameter (which is a reference to its class). Usually, the compiler supplies a copy constructor automatically. However, if you have defined a constructor for class 'class2' that has a parameter of type 'class2&' and has additional parameters with default values, the copy constructor can't exist and can't be created by the compiler. This is because these two can't be distinguished: class2::class2(class2&) class2::class2(class2&, int = 1) You must redefine this constructor so that not all parameters have default values. You can then define a reference constructor or let the compiler create one. Cannot find class::operator= ... Compiler message Whena C++ class 'class1' contains a vector (array) of class 'class2', and you want to copy a class of type 'class1', you must use this assignment operator so that the elements of the vector can be copied: 526 C++ Use r 's Gu ide class2::class2(class2&) Usually, the compiler automatically supplies thls operator. However, if you have defined an operator= for class 'class2' that does not take a parameter of type 'class2&,' the compiler will not supply it automatically--you must supply one. Cannot find default constructor to initialize array element of type 'class' Compiler message When declaring an array of a class that has constructors, you must either explicitly initialize every element of the array, or the class must have a default constructor. The compiler will define a default constructor for a class unless you have defined any constructors for the class. Cannot find default constructor to initialize base class 'class' Compiler message Whenever a C++ derived class 'class2' is constructed, each base class 'classl' must first be constructed. If the constructor for 'class2' does not specify a constructor for 'classl' (as part of 'class2's' header), there must be a constructor classl: : classl () for the base class. This constructor without parameters is called the default constructor. The compiler will supply a default constructor automatically unless you have defined any constructor for class 'classl'. In that case, the compiler will not supply the default constructor automatically-you must supply one. class Base { public: Base (int) {} }; class Derived = public Base Derived() :Base(l) {} II must explicitly call the Base constructor, or provide a II default constructor in Base. Class members with constructors must be initialized in the class' initializer list, for example: class A { public A( int ); }; class B public: A a; B () : a ( 3 ) {}; I 10k }; Cannot find default constructor to initialize member 'identifier' Compiler message This error is displayed when the following occurs: • A C++ class 'classl' contains a member of class 'class2.' • You want to construct an object of type 'class1' (but not from another object of type 'class1'). There must be a constructor class2::class20 so that the member can be constructed. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 527 This constructor without parameters is called the default constructor. The compiler will supply a default constructor automatically unless you have defined any constructor for class 'class2'. In that case, the compiler will not supply the default constructor automatically-you must supply one. Cannot find MAKE.EXE MAKE message The MAKE command-line tool cannot be found. Be sure that MAKE.EXE is in either the current directory or in a directory contained in your directory path. Cannot generate 'function' from template function 'template' Compiler message A call to a template function was found, but a matching template function cannot be generated from the function template. Cannot generate COM file: data below initial CS:IP defined Linker message This error results from trying to generate data or code below the starting address (usually 100) of a .COM file. Be sure that the starting address is set to 100 by using the (ORC 100H) instruction. This error message should not occur for programs written in a high-level language. If it does, ensure that the correct startup (COx) object module is being linked in. Cannot generate COM file: invalid initial entry point address Linker message You used the /Tdc or It option, but the program starting address is not equal to 100H, which is required with .COM files. Cannot generate COM file: program exceeds 64K Linker message You used the /Tdc or It option, but the total program size exceeds the .COM file limit. Cannot generate COM file: segment-relocatable items present Linker message You used the /Tdc or It option, but the program contains segment-relative fixups, which are not allowed with .COM files. Cannot generate COM file: stack segment present Linker message You used the /Tdc or It option, but the program declares a stack segment, which is not allowed with .COM files. Cannot have a non-inline function/static data in a local class Compiler message All members of classes declared local to a function must be entirely defined in the class definition. This means that local classes cannot contain any static data members, and all of their member functions must have bodies defined within the class definition. Cannot have multiple paths for implicit rule MAKE message You can have only one 'path for each of the extensions in an implicit rule; for example, {path} . c. obj. Multiple path lists are allowed only for dependents in an explicit rule. Cannot have path list for target MAKE message You can only specify a path list for dependents of an explicit rule. For example, an invalid and a valid path list are shown here: {pathl;path2}prog.exe: prog.obj # Invalid prog.exe: {pathl;path2}prog.obj # Valid 528 C++ Use r 's G u ide Cannot initialize 'type1' with 'type2' Compiler message You are attempting to initialize an object of type 'typel' with a value of type 'type2' which is not allowed. The rules for initialization are essentially the same as for assignment. Cannot initialize a class member here Compiler message Individual members of structs, unions, and C++ classes can't have initializers. A struct or union can be initialized as a whole using initializers inside braces. A C++ class can only be initialized by the use of a constructor. Cannot modify a const object Compiler message This indicates an illegal operation on an object declared to be canst, such as an assignment to the object. Cannot overload 'main' Compiler message main is the only function that can't be overloaded. Cannot take address of 'main' Compiler message In C++, it is illegal to take the address of the main function. Cannot take address of member function 'function' Compiler message An expression takes the address of a class member function, but this member function was not found in the program being debugged. The evaluator issues this message. Cannot throw 'type'-ambiguous base class 'base' Compiler message It is not legal to throw a class that contains more than one copy of a (non-virtual) base class. Cannot use local type 'identifier' as template argument Compiler message A local type was used in an actual template type argument, which is illegal. Cannot use tiny or huge memory model with Windows Compiler message This message is self-explanatory. Use small, medium, compact, or large instead .. Cannot write a string option MAKE message The -W MAKE option writes a character option to MAKE.EXE. If there's any string option, this error message is generated. For example, the following string option generates this message: -Dxxxx="My_foo" or -Uxxxxx Cannot write GRPOEF list, extended dictionary aborted Librarian message The librarian cannot write the extended dictionary to the end of the library file. There may not be enough space on the disk. Case bypasses initialization of a local variable Compiler message In C++ it is illegal to bypass the initialization of a local variable. This error indicates a case label that can transfer control past this local variable. Case outside of switch Compiler message The compiler encountered a case statement outside a switch statement. This is often caused by mismatched braces. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 529 Case statement missing: Compiler message A case statement must have a constant expression followed by a colon. The expression in the case statement either was missing a colon or had an extra symbol before the colon. . 'catch' expected Compiler message In a C++ program, a 'try' block must be followed by at least one 'catch' block. Character constant must be one or two characters long Compiler message Character constants can only be one or two characters long. Character constant too long MAKE message A char constant in an expression is too long. Circular dependency exists in makefile MAKE message The makefile indicates that a file needs to be up-to-date before it can be built. Take, for example, the explicit rules filea: fileb: filec: fileb filec filea This implies that file a depends on fileb, which depends on filec, and filec depends on filea. This is illegal because a file cannot depend on itself, indirectly or directly. Class 'class' may not contain pure functions Compiler message The class being declared cannot be abstract, and therefore it cannot contain any pure functions. Class 'classname' is abstract because of 'member =0' Compiler message This message is issued immediately after the "Cannot create instance of abstract class classname' error message and is intended to make it easier to figure out why a particular class is considered abstract by the compiler. I For example, consider the following example of an illegal attempt to instantiate an abstract class: struct VB virtual void virtual void virtual void f () g () h () 0; 0; 0; }; struct Dl : virtual VB void f (); }; struct D2 : virtual VB void h(); }; struct DD v; 530 Dl, D2 II error 'DD' is an abstract class c++ User's Guide The above code will cause the following two error messages: Error TEST.CPP 21: Cannot create instance of abstract class 'DD' Error TEST.CPP 21: Class 'DD' is abstract because of 'VB::g() = 0' Class member 'member' declared outside its class Compiler message C++ class member functions can be declared only inside the class declaration. Unlike nonmember functions, they can't be declared multiple times or at other locations .. Code has no effect . Compiler message (Command-line equivalent for displaying this warning = -weff) This warning is issued when the compiler encounters a statement with some operators that have no effect. For example, the statement a + b; has no effect on either variable. The operation is unnecessary and probably indicates a bug. Default = displayed CodeGuarded programs must use the large memory model and be targeted for Windows Compiler message Only issued by the I6-bit compiler. Programs that have CodeGuard enabled must use the large memory model and be targeted for Windows. Colon expected MAKE message Your implicit rule is missing a colon at the end . . c.obj: .c.obj # Correct # Incorrect Command arguments too long MAKE message The arguments to a command exceeded the SII-character limit imposed by DOS. Command syntax error This message occurs if MAKE message ( • The first rule line of the makefile contains any leading whitespace. • An implicit rule does not consist of .ext.ext:. • An explicit rule does not contain a name before the: character. A macro definition does not contain a name before the = character. Common segment exceeds 64K Linker message The program has more than 64K of near uninitialized data. Try declaring some uninitialized data as far. Compiler could not generate copy constructor for class 'class' Compiler could not generate default constructor for class 'class' Compiler could not generate operator = for class 'class' Compiler messages Sometimes the compiler is required to generate a member function for the user. Whenever such a member function can't be generated due to applicable language rules, the compiler issues one of these error messages. Appendix A, Error messages and warnings 531 Compiler stack overflow Compiler message The compiler's stack has overflowed. This can be caused by a number of things, among them deeply nested statements in a function body (for example, if/else) or expressions with a large number of operands. You must simplify your code if this message occurs. Adding more memory to your system will not help. Compiler table limit exceeded Compiler message One of the compiler's internal tables overflowed. This usually means that the module being compiled contains too many function bodies. This limitation will not be solved by making more memory available to the compiler. You need to simplify the file being compiled. Compound statement missing} Compiler message The compiler reached the end of the source file and found no closing brace. This is most commonly caused by mismatched braces. Condition is always true OR Condition is always false Compiler message (Command-line equivalent for displaying this warning = -wccc) Whenever the compiler encounters a constant comparison that (due to the nature of the value being compared) is, always true or false, it issues this warning and evaluates the condition at compile time. For example: void proc(unsigned x){ if (x >= 0) 1* always 'true' *1 } Default = displayed Conflicting type modifiers Compiler message This occurs when a declaration is given that includes more than one addressing modifier on a pointer or more than one language modifier for a function. Only one language modifier (cdecl, and pascal) can be given for a function. One cannot multiply derive from a class declared to use the fast this pointer optimization, and one that was not. For example: class __ fastthis A { myex(); }; II one way to declare a class as using the II fast this optimization, note that II #pragma option -po- turns it off. class B { twoex() ; }; class c : A , B {}; II error II note that __fastthis is only recognized in 532 C++ Use r 's G u ide Be 4.0 or later Constant expression required Compiler message Arrays must be declared with constant size. This error is commonly caused by misspelling a #define constant. Constant is long Compiler message (Command-line equivalent for displaying this warning = -wcln) The compiler encountered one of the following: • A decimal constant greater than 32,767 or • An octal, hexadecimal, or decimal constant greater than 65,535 without a letter I or L following it The constant is treated as a long. Default = not displayed Constant out of range in comparison Compiler message (Command-line equivalent for displaying this warning = -wmg) Your source file includes a comparison involving a constant sub-expression that was outside the range allowed by the other sub-expression's type. For example, comparing an unsigned quantity to -1 makes no sense. To get an unsigned constant greater than 32,767 (in decimal), you should either • Cast the constant to unsigned-for example, (unsigned) 65535, or • Append a letter u or U to the constant-for example, 65535u. Whenever this message is issued, the compiler still generates code to do the comparison. If this code ends up always giving the same result (such as comparing a char expression to 4000), the code will still perform the test. Default = displayed Constant/Reference member 'member' in class without constructors Compiler message A class that contains constant or reference members (or both) must have at least one user-defined constructor. Otherwise, there would be no way to ever initialize such members. Constant/Reference variable 'variable' must be initialized Compiler message This C++ object is declared constant or as a reference, but is not initialized. It must be initialized at the point of declaration. Constructor cannot have a return type specification Compiler message C++ constructors have an implicit return type used by the compiler, but you can't declare a return type or return a value. Constructor initializer list ignored Compiler message An error has occurred while using the command-line utility H2ASH. See the online file . "tsm_utiLtxt" for further information about this utility. Constructor/Destructor cannot be declared 'const' or 'volatile' Compiler message A constructor or destructor has been declared as const or volatile. This is not allowed. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 533 'constructor' is not an unambiguous base class of 'class' Compiler message A C++ class constructor is trying to call a base class constructor 'constructor.' This error , can also occur if you try to change the access rights of 'class::constructor.' Check your declarations. Continuation character \ found in II comment Compiler message This warning message is issued when a C++ / / comment is continued onto the next line with backslash line continuation. The intention is to warn about cases where lines containing source code unintentionally become part of a comment because that comment happened to end in a backslash. If you get this warning, check carefully whether you intend the line after the / / comment to be part of the comment. If you don't, either remove the backslash or put some other character after it. If you do, it's probably better coding style to start the next comment line with / / also. The warning can be disabled altogether by #pragma warn -com. Conversion may lose significant digits Compiler message (Command-line equivalent for displaying this warning = -wsig) For an assignment operator or some other circumstance, your source file requires a conversion from long or unsigned long to int or unsigned int type. Because int type and long type variables don't have the same size, this kind of conversion might alter the behavior of a program. Default = not displayed Conversion of near pointer not allowed Compiler message A near pointer cannot be converted to a far pointer in the expression evaluation box when a program is not currently running. This is because the conversion needs the current value of DS in the user program, which doesn't exist. Conversion operator cannot have a return type specification Compiler message This C++ type conversion member function specifies a return type different from the type itself. A declaration for conversion function operator can't specify any return type. Conversion to 'type' will fail for members of virtual base 'class' Compiler message This warning is issued only if the -Vv option or Options IProject IC++ Options IC++ Compatibility IDeep Virtual Bases option is in use. The warning may be issued when a member pointer to one type is cast to a member pointer of another type and the class of the converted member pointer has virtual bases. Encountering this warning means that at run time, if the member pointer conversion cannot be completed, the result of the cast will be a NULL member pointer. Conversions of class to itself or base class not allowed Compiler message You tried to define a conversion operator to the same class or a base class. Could not allocate memory for per module data The librarian has run out of memory. 534 ett User's Guide Librarian message Could not create list file 'filename' Librarian message The librarian could not create a list file for the library. This could be due to lack of disk space. Could not create swapfile Linker message This error message refers to an UNDOCUMENTED optimization feature. Could not find a match for argument(s) Compiler message No C++ function could be found with parameters matching the supplied arguments. Check parameters passed to function or overload function for parameters that are being passed. Could not find file 'filename' Compiler message The compiler is unable to find the file supplied on the command line. Could not write output Librarian message The librarian could not write the output file. Couldn't build command line to RLlNK.EXE Linker message The command line that was generated by the command-line linker was linger than 128 bytes. RLINK.EXE was not run on the EXE. Shorten the file names passed in the .RES file list, put in fewer .RES files, or run RLINK separately. Couldn't exec RLlNK.EXE Linker message The command-line linker could not spawn RLINK.EXE to bind resources. Check to make sure that RLINK.EXE is on your path. Couldn't get lEiLIDATA record buffer Librarian message Command-line error. The librarian is attempting to read a record of data from the object module, but it cannot get a large enough block of memory. If the module being added has a large data segment or segments, try adding this module before other modules. Couldn't get procedure address from Dll'dll' Linker message The linker was not able to get a procedure from the specified DLL. Check to make sure that you have the correct version of the DLL. Couldn't load Dll'dll' Linker message The linker was not able to load the specified pLL. Check to make sure that the DLL is on your path. Cycle in include files: 'filename' MAKE message This error message is issued if a makefile includes itself in the make script. Debug info switch ignored for COM files Linker message Borland C++ does not include debug information for .COM files. See the description of the Iv option. Debug information enabled, but no debug information found in OBJs Linker message No part of the application was compiled ~ith debug information, but you requested that debug information be turned on in the link. Appendix A, Error mess~ges and warnings 535 Debug information in module 'module' will be ignored Linker message Object files compiled with debug information now have a version record. The version of this record is inconsistent with what the linker currently supports. The linker did not generate debug information for the module in question. Recompile with the current compiler to generate correct debug information. Debugging information overflow; try fewer modules with debug info Linker message Too many modules containing debugging information are included in the link. This message is generated when you have more than 64K of types or symbols in a single .OBJ file, or if you get more than 64K modules, source files (including.h files), scopes, logical debug segments, classes, or optimized variables in the link. Recompile your program with fewer modules marked for debug information. Declaration does not specify a tag or an identifier Compiler message This declaration doesn't declare anything. This may be a struct or union without a tag or a variable in the declaration. C++ requires that something be declared. For example: struct int a }; Iino tag or identifier Declaration ignored Compiler message An error has occurred while using the command-:-line utility H2ASH. See the online file "tsm_utiLtxt" for further information about this utility. Declaration is not allowed here Compiler message Declarations can't be used as the control statement for while, for, do, if, or switch statements. Declaration missing; Compiler message Your source file contained a struct or union field declaration that was not followed by a semicolon. Check previous lines for a missing semicolon. Declaration of static function '(...)' ignored Compiler message An error has occurred while usiRg the command-line utility H2ASH. See the online file "tsm_utiLtxt" for further information about this utility. Declaration syntax error Compiler message Your source file contained a declaration that was missing a symbol or had an extra symbol added to it. Check for a missing semicolon or parenthesis on that line or on previous lines. Declaration terminated incorrectly Compiler message A declaration has an extra or incorrect termination symbot such as a semicolon, placed after a function body. 536 c++ User's Guide A C++ member function declared in a class with a semicolon between the header and the opening left brace also generates this error. Declaration was expected Compiler message A declaration was expected here but not found. This is usually caused by a missing delimiter such as a comma, semicolon, right parenthesis, or right brace. Declare operator delete (void*) or (void*, sizeJ) Declare operator deleteD (void*) or (void*, size_t) Compiler messages Declare the operator delete with one of the following: • A single void* parameter, or • A second parameter of type size_t If you use the second version, it will be used in preference to the first version. The global operator delete can only be declared using the single-parameter form. Declare type 'type' prior to use in prototype Compiler message (Command-line equivalent for displaying this warning = -wdpu) When a function prototype refers to a structure type that has not previously been declared, the declaration inside the prototype is not the same as a declaration outside the prototype. For example, int func(struct s *ps); struct s /* ... */ ; Because there is no "struct s" in scope at the prototype for func, the type of parameter ps is pointer to undefined struct s, and is not the same as the "struct s" that is later declared. This will result in later warning and error messages about incompatible types, which would be very mysterious without this warning message. To fix the problem, you can move the declaration for "struct s" ahead of any prototype that references it, or add the incomplete type declaration "struct s;" ahead of any prototype that references "structs". If the function parameter is a struet, rather than a pointer to struct, the incomplete declaration is not sufficient. You must then place the struet declaration ahead of the prototype. Default = displayed .DEF file stack/heap reserve size < 64K; 1MB default will be used Linker message The reserve size for either the STACK or the HEAP specified in the .DEF file is less than 64K. The linker emits this warning to inform you that it will use the default of 1MB instead of the value specified. Default argument value redeclared Compiler message When a parameter of a C++ function is declared to have a default value, this value can't be changed, redeclared, or omitted in any other declaration for the same function. Appendix A, Error messages and warnings 537 Default argument value redeclared for parameter 'parameter' Compiler message When a parameter of a C++ function is declared to have a default value, this value can't be changed, redeclared, or omitted in any other declaration for the same function. Default expression may not use local variables Compiler message A default argument expression is not allowed to use any local variables or other parameters. Default outside of switch Compiler message The compiler encountered a default statement outside a switch statement. This is most commonly caused by mismatched braces. Default value missing Compiler message When a C++ function declares a parameter with a default value, all of the following parameters must also have default values. In this declaration, a parameter with a default value was followed by a parameter without a default value. Default value missing following parameter 'parameter' Compiler message All parameters following the first parameter with a default value must also have defaults specified. Define directive needs an identifier Compiler message The first non-whitespace character after a #define must be an identifier. The compiler found some other character. Destructor cannot have a return type specification Compiler message C++ destructors never return a value, and you can't declare a return type or return a value. Destructor for 'class' required in conditional expression Compiler message If the compiler must create a temporary local variable in a conditional expression, it has no good place to call the destructor because the variable might or might not have been initialized. The temporary can be explicitly created, as with classname(val, val), or implicitly created by some other code. You should recast your code to eliminate this temporary value. Destructor for class is not accessible Compiler message The destructor for this C++ class is protected or private, and can't be accessed here to destroy the class. If a class destructor is private, the class can't be destroyed, and thus can never be used. This is probably an error. A protected destructor can be accessed only from derived classes. This is a useful way to ensure that no instance of a base class is ever created, but only classes derived from it. Destructor name must match the class name Compiler message In a C++ class, the tilde (~) introduces a declaration for the class destructor. The name of the destructor must be same as the class name. In your source file, the ~ preceded some other name. Disable Group checked but no value entered IDE Debugger message You checked the Disable Group check box, but forgot to specify a group name. Divide error You tried to divide an integer by zero, which is illegal. 538 c++ User's Guide Run-time message Division by zero Compiler message Your source file contains a divide or remainder in a constant expression with a zero divisor. Division by zero Compiler message (Command-line equivalent for displaying this warning = -wzdi) A divide or remainder expression had a literal zero as a divisor. Default = displayed Division by zero MAKE message A division or remainder operator in an!if statement has a zero divisor. do statement must have while Compiler message Your source file contained a do statement that was missing the closing while keyword. do-while statement missing OR For statement missing ; Compiler message In a do or for statement, the compiler found no semicolon after the right parenthesis. DOS error, ax = 'decimal number' Linker message This occurs if a DOS call returned an unexpected error. The ax value printed is the resulting error code. This could indicate a linker internal error or a DOS error. The only DOS calls the linker makes where this error could occur are read, write, seek, and close. Make sure that there are no zero length .OBJ files included in the link. DOSSEG directive ignored Linker message This warning indicates that the linker no longer supports the DOSSEG directive. DPMI programs must use the large memory model Compiler message DPMI programs can only use large memory model. Tiny, Small, Medium, Compact, and Huge memory models are not allowed. Duplicate case Compiler message Each case of a switch statement must have a unique constant expression value. Duplicate file 'filename' in list, not added! Librarian message When building a library module, you specified an object file more than once. Duplicatehandler for 'type1', already had 'type2' It is not legal to specify two handlers for the same type. Duplicate ordinal 'number' in exports Compiler message Linker message The linker encountered two exports with the same ordinal value. Check the module definition file to ensure that there are no duplicate ordinal values specified in the EXPORTS section. If not, you are linking with modules that specify exports by ordinals and one of two things happened: • Two export records specify the same ordinal, or • The exports section in the module definition file duplicates an ordinal in an export record. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 539 Duplicate ordinal for exports: 'string' ('ordval1 ') and 'string' ('ordvaI2') Linker message Two exports share the same ordinal. The linker cannot resolve which export should get which ordinal. Earlier declaration of 'identifier' Compiler message This error message only shows up after the messages "Multiple declaration for 'identifier'" and "Type mismatch in redeclaration of 'identifier"'. It tells you where the previous definition of the identifier in question was found by the compiler, so you, don't have to search for it. . Empty LEDATA record in module 'module' Linker message This warning can happen if the translator emits a data record containing data. If this should happen, report the occurrence to the translator vendor. There should be no bad side effects from the record. . Enable Group checked but no value entered IDE Debugger message You checked the Enable Group check box, but forgot to specify a group name. End of system input buffer encountered Linker message The input line you typed is too long. Instead of typing all you're object and library files on the command line, put them into a response file. Ensuring executable is up to date IDE Debugger message The IDE Debugger is checking to be sure that the executable file is up to date, recompiling, if necessary. Enum syntax error Compiler message An enum declaration did not contain a properly formed list of identifiers. Error changing file buffer size Librarian message The librarian is attempting to adjust the size of a buffer used while reading or writing a file, but there is not enough memory. You'll need to free up a lot of system memory to resolve this error. Error creating file. Resource Linker message An error occurred when the resource linker tried to create a file. This error occurs if the work disk is full or write-protected. It can also occur if the output directory does not exist. Solutions: • If the disk is full, try deleting unneeded files and restarting the resource link. • If the disk is write-protected, direct the output to a writeable disk and restart the resource link. Error creating temporary file in directory. Resource Linker message An error occurred when the resource linker tried to create a temporary file. This error occurs if the work disk is full or write-protected. It can also occur if the output directory does not exist. Solutions: • If the disk is full, try deleting unneeded files and restarting the resource link. • If the disk is write-protected, direct the output to a writeable disk and restart the resource link. 540 c++ User's Guide Error deleting file. Resource Linker message An error occurred when the resource linker tried to delete a file. This error occurs if the file is marked as read-only or does not exist. If the disk is read-only, change its attributes so that it can be deleted. Error directive: 'message' Compiler message This message is issued when an #error directive is processed in the source file. 'message' is the text of the #error directive. Error directive: 'message' MAKE message MAKE has processed an #error directive in the source file, and the text of the directive is displayed in the message. Error in CURSDIR. Cannot find CURS. Resource Linker message An entry was found in the cursor directory that had no corresponding cursor resource. The resource file is probably corrupted. Error in EXE's resource table format. Resource Linker message There is invalid information in the executable files resource table. The executable file might contain invalid resource information or be corrupt. Error in FONTDIR. Cannot find FONT. Resource Linker message An entry was found in the font directory that had no corresponding font resource. The resource file is probably corrupted. Error in ICONDIR. Cannot find ICON. Resource Linker message An entry was found in the icon directory that had no corresponding icon resource. The resource file is probably corrupted. Error in RES format. Resource Linker message There is invalid information in the binary resource file. The resource file might contain invalid resource information or be corrupt. Try recompiling the resources and restart the resource link. Error in RES format. Cannot find NAMEDIR resource. Resource Linker message An entry was found in the name-table that had no corresponding resource. Verify that you have included the appropriate resource in your resource script. Name-tables are not used for Windows version 3.1 or greater. Error in resource binary length (bad format?). Resource Linker message There is an error in the size of a binary resource. The format of the resource might be invalid or the resource has been corrupted. Error in packing preload area. Turn off preload packing. Resource Linker message An error occurred while the resource linker was trying to optimize how resources and segments are arranged in the executable file. (This error only occurs for 16-bit resources. ) To correct this error, tum off the Pack Fastload Area option in the Resources Options. Error opening file. Resource Linker message An error occurred when the resource linker tried to open a file. This error occurs if the file does not exist, another process has denied access to the file, the path or filename is incorrect, or there are no more available file handles. Appendix A, Error messages and warnings 541 Error opening 'filename' Librarian message The librarian cannot open the specified file. Error opening 'filename' for output Librarian message The librarian cannot open the specified file for output. Error positioning file. Resource Linker message An error occurred trying to seek to a location in a file. This file could be truncated or corrupted. Try verifying the disk integrity using CHKDSK or recompile the resource files and restart the resource link. Error reading file. Resource Linker message An error occurred when the resource linker tried to read a file. This error typically occurs when there is a disk error while the file is being read. Error renaming file. Resource Linker message An error occurred when the resource linker tried to rename a file. This error occurs if the file is marked as read-only or does not exist or a file already exists having the name that the resource linker is trying to use. Solutions: • If the disk is read-only, change its attributes so that it can be deleted. • If a file having the name already exists you can either delete that file or choose another name. Error renaming 'filename' to 'filename' Librarian message This error occurs when the librarian is building a temporary library file and renaming the temporary file to the target library file name. The error indicates that the target file is read only. Error seeking point in file. Resource Linker message An error occurred trying to seek to a location in a file. This file could be truncated or corrupted. Try compiling the resource files and restart the resource link. Error sizing file. Error getting size of file. Resource Linker messages _ A disk error occurred when trying to determine the file size. Error trying to change value IDE Debugger message You tried to change a value of an object being inspected, but the debugger was unable to change the value. Error writing file. Resource Linker message An error occurred when the resource linker tried to write to a file. This error occurs if the work disk is full or write-protected. Solutions: • If the disk is full, try deleting unneeded files and restarting the resource link. • If the disk is write-protected, direct the output to a writeable disk and restart the resource link. Error writing output file Compiler message A DOS error that prevents the C++ IDE from writing an .OB], .EXE, or temporary file. 542 c++ User's Guide Solutions: • Make sure that the Output directory in the Directories dialog box is a valid directory. • Check that there is enough free disk space. Error. EXE alignment too small for packing resources too. Resource Linker message You have pre-packing turned on and the resources will not fit with the current image alignment. Try increasing the alignment, re-link, and restart the resource link. Error. Expecting RES file, not EXE. File: Resource Linker message The resource linker was expecting a compiled resource (.RES) file, but found an executable (.EXE) instead. Verify that you have the correct node and file types specified. Error: File not specified IDE Debugger message You forgot to specify a filename in the Run To dialog. Error: Line not specified IDE Debugger message You forgot to specify a line number in the Run To dialog. Error. Missing NAME resource. RES not for Windows 3. Resource Linker message The binary resource file is missing the NAME resource. The resource file is probably not a Windows 3 resource file. Eval Expr checked but no value entered IDE Debugger message You checked the Eval Expr check box, but forgot to specify an expression. Example for "Temporary used ..." error messages Compiler message In this example, function f requires a reference to an int, and c is a char: f (int&) ; char c; f(c) ; Instead of calling f with the address of c, the compiler generates code equivalent to the C++ source code: int x = c , f (X) ; '_except' or '_finally' expected following '_try' Compiler message In C, a '_try block' must be followed by a '_except' or '_finally' handler block. Exception handling not enabled A 'try' block was found with the exception handling disabled. Compiler message Excep~ion handling variable may not be used here Compiler message An attempt has been made to use one of the exception handling values that are restricted to particular exception handling constructs, such as GetExceptionCode(). Exception specification not allowed here Compiler message Function pointer type declarations are not allowed to contain exception specifications. Explicit stacks are ignored for PE images Linker message Win32 apps are PE format applications, which do not have explicit stacks. The stack segment will be linked into the image, but it will not be used as the application stack. Instead, the stack size parameter will be used to set the stack size, and the operating system will allocate a stack for the application. Appendix A, Error messages and warnings 543 Export 'symbol' has multiple ordinal values: 'value1' and 'value2' Linker message The linker encountered one symbol with multiple ordinal values. The linker cannot resolve which value to export, and will use the first value. Check the EXPORTS section of the module definition file and make sure that the export name applies only once. Export 'symbol' is duplicated Linker message This warning will occur if two different functions with the same name are exported by the use of _export. The linker cannot resolve which definition to export, and will use the first symbol. Expr True check but no value entered IDE Debugger message You checked the Expr True check box, but forgot to provide an expression; Expression expected Compiler message An expression was expected here, but the current symbol can't begin an expression. This message might occur where the controlling expression of an if or while clause is expected or where a variable is being initialized. This message is often due to a symbol that is missing or has been added. Expression of scalar type expected The !, ++, and -- operators require an expression of scalar type. Compiler message Only these types are allowed: • • • • • • • • • char short int long enum float double long double pointer Expression syntax Compiler message This is a catch-all error message when the compiler parses an expression and encounters a serious error. Possible Causes: This is most commonly caused by one of the following: • Two consecutive operators • Mismatched or missing parentheses • A missing semicolon on the previous statement. Solutions: • If the line where the error occurred looks syntactically correct, look at the line directly ,above for errors. • Try moving the line with the error to a different location in the file and recompiling. 544 c++ User's Guide • If the error still occurs at the moved statement, the syntax error is occurring somewhere in that statement. • If the error occurred in another statement, the syntax error is probably in the surrounding code. Expression syntax error in !if statement MAKE message The expression in an !if statement is badly formed-it contains a mismatched parenthesis, an extra or missing operator, or a missing or extra constant. Extended dictionary not found in library 'library': extended dictionaries ignored Linker message When you specify that extended dictionaries be used, all libraries must have extended dictionaries. In this case, a library was encountered that did not have an extended dictionary, thus aborting the link. Use the TLIB IE option to generate an extended dictionary for the library in question. 'reason' . extended dictionary not created Librarian message Library contains COMDEF records - extended dictionary not created If the Library contains COMDEF records message is displayed, an object record being added to a library contains a COMDEF record. This is not compatible with the extended dictionary option. Extern 'symbol' was not qualified with _import in module 'module' Linker message Win32 applications which make reference to imported symbols need to make indirections to get to the data. For calls, this is handled automatically by the linker. For references to imported DATA, the compiler must generate an indirection, or the application will function incorrectly. The compiler knows to generate the indirection when the symbol is qualified with _import. If the linker sees a segment relative reference to a symbol which is imported, and if the symbol was not qualified with _import, you will get this message. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the Iw-inq command-line option. Extern variable cannot be initialized Compiler message The storage class extern applied to a variable means that the variable is being declared but not defined here--no storage is being allocated for it. Therefore, you can't initialize the variable as part of the declaration. Extra argument in template class name 'template' Compiler message A template class name specified too many actual values for its formal parameters. Extra parameter in call Compiler message A call to a function, via a pointer defined with a prototype, had too many arguments. Extra parameter in call to function. Compiler message A call to the named function (which was defined with a prototype) had too many arguments given in the calL Failed read from 'filename' Linker message The linker was unable to read from the file. Appendix A, Error messages and warnings 545 Failed write to 'filename' Linker message The linker was unable to write to the file. Far COMDEFs are not supported Linker message The linker encountered an object file with an incompatible .OBJ file format. This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a ~ompile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. FATAL ERROR: GP FAULT MAKE message Your program caused a general protection fault and exited fatally. This type of error is caused by various reasons such as attempting to access or write to out of bound memory. For best results, use CodeGuard to locate the error. File 'filename' does not exist IDE Debugger message You tried to bring up a source view on an address, and the associated file does not exist. This problem can usually be fixed by setting the appropriate source path on the debugger option page. File 'filename' does not exist (trying to load it anyway...) IDE Debugger message The debugger tried to load an executable that does not exist. Check to make sure that the executable exists and that the path to the executable was correctly specified. File must contain at least one external declaration Compiler message This compilation unit was logically empty, containing no external declarations. ANSI C and C++ require that something be declared in the compilation unit. 'filename' ('linenum'): Duplicate external name in exports Linker message Two export functions listed in the EXPORTS section of a module definition file defined the same external name. For example: EXPORTS AnyProc=MyProcl AnyProc=MyProc2 'filename' ('linenum'): Duplicate internal name in exports Linker message Two export functions listed in the EXPORTS section of the module definition file defined the same internal name. 'filename' ('linenum'): Duplicate internal name in imports Linker message Two import functions listed in the IMPORTS section of the module definition file defined the same internal name. 'filename' ('linenum'): File read error Linker message A DOS error occurred while attempting to read the specified file. This usually means that a premature end of file occurred. Check for a length files. 'filename' ('linenum'): Incompatible attribute Linker message The linker encountered incompatible segment attributes in a CODE or DATA statement. For instance, both PRELOAD and LOADONCALL can't be attributes for the same segment. 546 C++ Use r 's Gu ide 'filename' ('linenum'): Missing internal name Linker message In the IMPORTS section of the module definition file, there was a reference to an entry specified via module name and ordinal number. When an entry is specified by ordinal number, an internal name must be assigned to this import definition. It is this internal name that your program uses to refer to the imported definition. The syntax in the module definition file should be: = . 'filename' ('linenum'): Syntax error Linker message The linker found a syntax error in the module definition file. The file name and line number tell you where the syntax error occurred. 'filename' couldn't be created, original won't be changed Librarian message You tried to extract an object, but the librarian cannot create the object file into which to extract the module. Either the object already exists and is read only, or the disk is full. 'filename' does not exist: don't know how to make it MAKE message The build sequence includes a nonexistent file name, and no rule exists that would allow the file name to be built. 'filename' file not found Librarian message Command-line error. The command-line librarian attempted to add a nonexisting object but created the library anyway. 'filename' file not found Librarian message The IDE creates the library by removing the existing library and rebuilding it. If any of the specified objects do not exist, the library is incomplete and this error is generated. If the IDE reports that an object does not exist, either the source module has not been compiled or there were errOrs during compilation. Using either the Project I Make All or Project I Build All commands should resolve the problem or indicate where the errors occurred. 'filename' is not a valid library Linker message This error happens when the first record in a library file is not the LIBSTART record. This can happen when something that is not a library is passed as a library file to the linker, or if the library file was corrupted. . 'filename' not a MAKE MAKE message The file you specified with the -f option is not a makefile. File name not specified IDE Debugger message You tried to add a source breakpoint using the IDE Debugger but you omitted a file name. Enter the name of the file into which you want to insert the breakpoint in the Add Breakpoint dialog box. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 547 File name too long Compiler message The file name given in an #include directive was too long for the compiler to process. File names in DOS must be no more than 79 characters long. Filename too long MAKE message The path name in an !include directive overflowed MAKE's internal buffer (512 bytes). Fixup overflow at 'address,' target ='address' Fixup overflow at 'address,' target ='symbol' in module 'module' Linker messages Either of these messages indicates an incorrect data or code reference in an object file that the linker must fix up at link time. These messages are most often caused by a mismatch of memory models. A near call to a function in a different code segment is the most likely cause. These errors can also occur if you generate a near call to a data variable or a data reference to a function. In either case, the symbol named as the target in the error message is the referenced variable or function. The reference is in the named module, so look in the source file of that module for the offending reference. Rebuild the entire program to ensure that all modules have been compiled with in the same memory model. Checked that linked libraries were also compiled in the same memory module. If this technique does not identify the cause of the failure, or if you are programming in assembly language or a high-level language besides C or C++, there might be other possible causes for this message. Even in C++, this message could be generated if you are using different segment or group names than the default values for a given memory model. Fixup to zero length segment in module 'module' Linker message A reference has been made past the end of an image segment. This reference would end up accessing an invalid address, and has been flagged as an error. Fixups found for an LlDATA record Linker message The linker encountered an object file with an incompatible .OBJ file format. This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Floating point error: Divide by 0 Floating point error: Domain Floating point error: Overflow Run-time messages These fatal errors result from a floating-point operation for which the result is not finite: • Divide by 0 means the result is + INF or - INF exactly, such as 1 . 0/0 . o. • Domain means the result is NAN (not a number), like 0 . 0/0 . o. 548 c++ User's Guide Overflow means the result is + INF (infinity) or - INF with complete loss of precision, such as assigning 1e200*le200 to a double. Floating point error: Partial loss of precision Floating point error: Underflow Run-time messages These exceptions are masked by default, because underflows are converted to zero and losses of precision are ignored. Floating point error: Stack fault Run-time message The floating-point stack has been overrun. This error may be due to assembly code using too many registers or due to a misdeclaration of a floating-point function. The program prints the error message and calls abort and _exit. These floating-point errors can be avoided by masking the exception so that it doesn't occur, or by catching the exception with signaL FONTDIR resource too big to link. FONTDIR too large to handle. Resource Linker messages The directory of fonts table size has been exceeded. Try splitting your fonts into multiple FON files. Compiler message Friends must be functions or classes A friend of a C++ class must be a function or another class. Function 'function' cannot be static Compiler message Only ordinary member functions and the operators new and delete can be declared static. Constructors, destructors and other operators must not be static. Function body ignored Compiler message An error has occurred while using the command-line utility H2ASH. See the online file "tsm_util.txt" for further information about this utility. Function call missing) Compiler message The function call argument list had some sort of syntax error, such as a missing or mismatched right parenthesis. Function call terminated by unhandled exception IDE Debugger message This message is emitted when an expression you are evaluating while debugging includes a function call that terminates with an unhandled exception. For example, if in the debugger's evaluate dialog, you request an evaluation of the expression foo () +1 and the execution of the function foo () causes a GP fault, this evaluation produces the above error message. You may also see this message in the watches window because it also displays the results of evaluating an expression. Function defined inline after use as extern Compiler message Functions can't become inline after they have already been used. Either move the inline definition forward in the file or delete it entirely. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 549 The compiler encountered something like: myex() ; twoex() { myex(); } inline myex() { return 2; } II error and already used the function as an extern before it saw that it was specified as inline. This would be correct: myex() ; inline myex() { return 2; twoex() { myex(); } or better: inline myex ( ) ; inline myex() { re~urn 2; } twoex() { myex(); } Function definition cannot be a typedef'ed declaration Compiler message In ANSI C, a function body cannot be defined using a typedef with a function Type. Redefine the function body. 'function' must be declared with no parameters Compiler message This C++ operator function was incorrectly declared with parameters. 'function' must be declared with one parameter Compiler message This C++ operator function was incorrectly declared with more than one parameter. 'function' must be declared with two parameters Compiler message This C++ operator function was incorrectly declared with other than two parameters. Function should return a value Compiler message (Command-line equivalent for displaying this warning = -wrvl) Your source me declared the current function to return some type other than int or void, but the compiler encountered a return with no value. The compiler found a return statement without a return value, or it reached the end of the function without finding a return statement. Either return a value or change the function declaration to return void. Default = displayed 'function' was previously declared with the language 'language' Compiler message Only one language modifier (cdecl pascal) can be given for a function. This function has been declared with different language modifiers in two locations. Functions are not expanded inline Compiler message Exception specifications are not expanded inline: Check your inline code for lines containing exception specification. Functions taking class-by-value argument(s) are not expanded inline: When exception handling is enabled, functions that take class arguments by value cannot be expanded inline. 550 c++ User's Guide Note: Functions taking class parameters by reference are not subject to this restriction. Functions cannot return arrays or functions Compiler message A function was defined to return an array or a function. Check to see if either the intended return was a pointer to an array or function (and perhaps the * is missing) or if the function definition contained a request for an incorrect data type. Functions containing reserved words are not expanded inline Functions containing local destructors are not expanded inline in function 'function' Compiler messages (Command-line equivalent for displaying this warning = -winl) Reserved words Functions containing any of these reserved words can't be expanded inline, even when specified as inline: • • • • • • • • break case continue do for goto switch while The function is still perfectly legal, but will be treated as an ordinary static (not global) function. A copy of the function will appear in each compilation unit where it is called. Local destructors You've created an inline function for which the compiler turns off inlining. You can ignore this warning; the function will be generated out of line. Default = displayed Functions 'function1' and 'function2' both use the same dispatch number Compiler message This error indicates a dynamically dispatched virtual table (DDVT) problem. Functions may not be part of a struct or union Compiler message This C struct or union field was declared to be of type function rather than pointer to function. Functions as fields are allowed only in C++. 'function1' cannofbe distinguished from 'function2' Compiler message The parameter type lists in the declarations of these two functions do not differ enough to tell them apart. Try changing the order of parameters or the type of a parameter in one declaration. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 551 'function 1, hides virtual function 'function2' Compiler message (Command-line equivalent for displaying this warning = -whid) A virtual function in a base class is usually overridden by a declaration in a derived class. In this case, a declaration with the same name but different argument types makes the virtual functions inaccessible to further derived classes. Default = displayed General error General error in library file 'filename' in module 'module' near module file offset 'Oxyyyyyyyy' General error in module 'module' near module file offset 'Oxyyyyyyyy' Linker messages The linker gives as much information as possible about what processing was happening at the time of the unhandled exception. Call Borland Technical Support with information about the .OBJ or .LIB files. General error in module 'module' Linker message TLink32 emits a General Error and crashes if the user specifies a map file that cannot be opened. This usually occurs when the directory (or drive) for the command-line specified map file doesn't exist. This linker is trying to emit the following message to the map file: Fatal: cannot open mapfile ... Make sure that the map file destination drive and directory is correct. Global anonymous union not static .Compiler message In C++, a global anonymous union at the file level must be static. Goto bypasses initialization of a local variable Compiler message In C++ it is illegal to bypass the initialization of a local variable. This error indicates a goto statement that can transfer control past this local variable. Goto into an exception handler is not allowed Compiler message It is not legal to jump into a try block, or an exception handler that is attached to a try block. Goto statement missing label Compiler message The goto keyword must be followed by an identifier. Group 'group' exceeds 64K , Linker message This message occurs when there was too much data to fit in the available data segments. To resolve the problem, you can try the following: 1 Switch to a memory model with multiple data segments (small, compact, or huge). 2 Put large global variables in far data. This is called Automatic Far Data & Far Data Threshold in the IDE (Options I Compiler I Advanced CG) and Far Global Variables (-Ff=size) on the command line. 3 Use the far keyword to force data objects into far data. 552 C++ Use r 's G u ide 4 Allocate variables dynamically (off the heap) instead of statically. 5 If using c++ virtual tables, enable Far Virtual Tables (Options I Compiler I C++ Options in the IDE; -Vf on the command line). Group 'group1' overlaps group 'group2' Linker message The linker encountered nested groups. This warning occurs only when overlays are used. Group overflowed maximum size: 'name' Compiler message The total size of the segments in a group (for example, DGROUP) exceeded 64K. Handler for 'type1' hidden by previous handler for 'type2' Compiler message This warning is issued when a handler for a type 'D' that is derived from type 'B' is specified after a handler for B', since the handler for 'D' will never be invoked. Heap size is less than 1000h. It has been reset to 1000h Linker message The minimum allowable heap size is 1000h. When the linker detects that the heap size is less than this value, the linker automatically resets the size to 1000h and issues this message. To eliminate this message, you need to change the HEAPSIZE specification in the DEF file to 1000h or greater. Hexadecimal value contains more than three digits Compiler message (Command-line equivalent for displaying this warning = -wbig) Under older versions of C, a hexadecimal escape sequence could contain no more than three digits. The ANSI standard allows any number of digits to appear as long as the value fits in a byte. This warning results when you have a long hexadecimal escape sequence with many leading zero digits (such as \x00045). Older versions of C would interpret such a string differently. Default = displayed Identifier expected An identifier was expected here, but not found. Compiler message In C, an identifier is expected in the following situations: • In a list of parameters in an old-style function header • After the reserved words struct or union when the braces are not present, and • As the name of a member in a structure or union (except for bit fields of width 0). In C++, an identifier is also expected in these situations: • In a list of base classes from which another class is derived, following a double colon (::). • After the reserved word operator" when no operator symbol is present. 1/ Appendix A, Error messages and warnings 553 'identifier' cannot be declared in an anonymous union Compiler message The compiler found a declqration for a member function or static member in an anonymous union. Such unions can only contain data members. 'identifier' cannot start a parameter declaration Compiler message An undefined 'identifier' was found at the start of an argument in a function declarator. Often the type name is misspelled or the type declaration is missing. This is usually caused by not including the appropriate header file. Identifier 'identifier' cannot have a type qualifier Compiler message A C++ qualifier class::identifier can't be applied here. A qualifier is not allowed on the following: • • • • typedef names function declarations (except definitions at the file level) on local variables or parameters of functions on a class member--except to use its own class as a qualifier (redundant but legal). 'identifier' is assigned a value that is never used Compiler message (Command-line equivalent for displaying this warning = -waus) The variable appears in an assignment, but is never used anywhere else in the function just ending. The warning is indicated only when the compiler encounters the closing brace. Default = displayed 'identifier' is declared as both external and static Compiler message (Command-line equivalent for displaying this warning = -wext) This identifier appeared in a declaration that implicitly or explicitly marked it as global or external, and also in a static declaration. The identifier is taken as static. You should review all declarations for this identifier. Default = displayed 'identifier' is declared but never used Compiler message (Command-line equivalent for displaying this warning = -wuse) This message can occur in the case of either local or static variables. It occurs when the source file declares the named local or static variable as part of the block just ending, but the variable was never used. In the case of local variables, this warning occurs when the compiler encounters the closing brace of the compound statement or function. In the case of static variables, this warning occurs when the compiler encounters the end of the source file. Default = not displayed 'identifier' is not a member of 'struct' Compiler message You are trying to reference 'identifier' as a member of 'struct', but it is not a member. Check your declarations. 554 C++ Use r 's Gu ide 'identifier' is not a non-static member and can't be initialized here Compiler message Only data members can be initialized in the initializers of a constructor. This message means that the list includes a static member or function member. Static members must be initialized outside of the class, for example: class A { static int i; }; int A: : i = -1; 'identifier' is not a parameter Compiler message In the parameter declaration section of an old-style function definition, 'identifier' is declared t not listed as a parameter. Either remove the declaration or add 'identifier' as a parameter. 'identifier' is not a public base class of 'classtype' Compiler message The right operand of a .*, ->*, or ::operator was not a pointer to a member of a class that is either identical to (or an unambiguous accessible base class of) the left operand's class type. 'identifier' is obsolete Compiler message Issues a warning upon usage for any "C" linkage function that has been specified. This will warn about functions that are" obsolete". Here's an example of its usage: #ifdef __cplusplus extern "e" { #endif void my_func(void); #ifdef __cplusplus } #endif #pragma obsolete my_func main() my_func(); II Generates warning about obsolete function 'identifier' must be a member function Compiler message Most C++ operator functions can be members of classes or ordinary non-member functions, but these are required to be members of classes: • • • • operator = operator-> operator ( ) type conversions This operator function is not a member function but should be. 'identifier' must be a member function or have a parameter of class type Compiler message Most C++ operator functions must have an implicit or explicit parameter of class type. This operator function was declared outside a class and does not have an explicit parameter of class type. Appendix AI Error messages and warnings 555 'identifier' must be a previously defined class or struct Compiler message You are attempting to declare 'identifier' to be a base class, but either it is not a class or it has not yet been fully defined. Correct the name or rearrange the declarations. 'identifier' must be a previously defined enumeration tag Compiler message This declaration is attempting to reference 'ident' as the tag of an enum type, but it has not been so declared. Correct the name, or rearrange the declarations. 'identifier' specifies multiple or duplicate access Compiler message A base class can be declared public or private, but not both. This access specifier can appear no more than once for a base class. If statement too long An If statement has exceeded 4,096 characters. MAKE message Ifdef statement too long An Ifdef statement has exceeded 4,096 characters. MAKE message Ifndef statement too long An Ifndef statement has exceeded 4,096 characters. MAKE message Ignored 'module', path is too long Librarian message 'The path to a specified .OBJ or .LIB file is greater than 64 characters. 'The maximum path to a file for the librarian is 64 characters. lII·formed pragma Compiler message (Command-line equivalent for displaying this warning = -will) A pragma does not match one of the pragmas expected by the compiler. Default = displayed Illegal ACBP byte in SEGDEF in module 'module' Linker message 'This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. 'This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Illegal character 'character' (Ox'value') Compiler message 'The compiler encountered some invalid character in the input file. 'The hexadecimal value of the offending character is printed. 'This can also be caused by extra parameters passed to a function macro. Illegal character in constant expression 'expression' MAKE message MAKE encountered a character not allowed in a constant expression. If the character is a letter, this probably indicates a misspelled identifier. 556 C++ Use r 's G u ide Illegal component to GRPDEF in module 'module' Linker message This error generally occurs due to an incompatible .OBI file format. If you're linking .OBI files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Illegal group definition: 'group' in module 'module' Linker message This error results from an invalid GRPDEF record in an .OBJfile. This could also result from custom-built .OBI files or a bug in the translator used to generate the .OBI file. If this occurs in a file created by a Borland compiler, recompile the file. If the error persists, contact Borland Technical Support. Illegal initialization Compiler message Initializations must be one of the following: • Constant expressions • Address of a global extern or static variable plus or minus a constant Illegal local public in 'module' Linker message This message occurs when the linker sees an LPUBDEF record with an offset of zero for a VIRDEF that resides in an overlay segment. This can happen if you are trying to use structured exception support in an application that uses overlays. Illegal octal digit Compiler message The compiler found an octal constant containing a non-octal digit (8 or 9). Illegal octal digit MAKE message An octal constant containing a digit of 8 or 9 was found. Illegal parameter to __emit_ _ Compiler message There are some restrictions on inserting literal values directly into your code with the _emit_ function. For example, you cannot give a local variable as a parameter to _emit_. Illegal pointer subtraction Compiler message This is caused by attempting to subtract a pointer from a non-pointer. Illegal structure operation Compiler message Structures can only be used with dot (.), address-of (&) or assignment (=) operators, or be passed to or from a function as parameters. The compiler encountered a structure being used with some other operator. Illegal to take address of bit field Compiler message It is not legal to take the address of a bit field, although you can take the address of other kinds of fields. A Ppen d i x A, Err 0 r me s sag e san d . war n i n 9 s 557 Illegal type of entry pOint Linker message The linker encountered an object file with an incompatible .OBJ file format. This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Illegal use of floating point Compiler message Floating-point operands are not allowed in these operators • • • • • Shift (SHL, SHR) Bitwise Boolean (AND, OR, XOR, NOT) Conditional (? :) Indirection (*) Certain others The compiler found a floating-point operand with one of these prohibited operators. Illegal use of member pointer Compiler message Pointers to class members can only be passed as arguments to functions, or used with the following operators: • assignment • comparison • * • ->* • ?: • && • II • The compiler has encountered a member pointer being used with a different operator. To call a member function pointer, one must supply an instance of the class for it to call upon. For example: class A { public: myex() i }i typedef int (A:: *Amfptr) () i myex() { Amfptr mmyex (*mmyex) (): 558 ett Useri·s Guide = &A:: myex i //error This will compile: class A { public: myex() ; }; typedef int foo() (A:: *Amfptr) () ; { A a; Amfptr nrrnyex (a. *nrrnyex) 90; &A: :myex; Illegal use of pointer Compiler message Pointers can only be used with these operators: • • • • • • addition ( + ) subtraction ( - ) assignment ( = ) comparison ( = = ) indirection ( * ) arrow (-» Your source file used a pointer with some other operator. Example: int main (void) char *p; p /= 7; /* ERROR: Illegal Use of Pointer */ return 0; Illegal/invalid option in CMDSWITCHES directive 'option' MAKE message The !CMDSWITCHES preprocessing directive turns on or off one or more commandline options. Specify an operator, either a plus sign (+) to tum options on, or a minus sign (-) to tum options off, followed by one or more letters specifying options. An invalid or illegal option is specified in the !CMDSWITCHES directive. Image base address must be a multiple of Ox10000 Linker message Based images must be aligned on 64K boundaries. Image linked as EXE, but with DLL extension Linker message The linker generates this warning when an executable file has been generated and stored in a file with a .DLL extension. This usually occurs when you intended to build a .DLL but forgot to specify a .DLL target with the IT linker option (or you forgot the IT option altogether) on the command line. If you want to generate a DLL as a target, use the appropriate IT option. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 559 Images fixed at specific addresses typically will not run under Win32s Linker message Windows 32s loads all applications in a single address space. It's possible to predict where your application is going to be loaded, because other 32-bit applications might have been loaded before yours. Implicit conversion of 'type1' to 'type2' not allowed Compiler message When a member function of a class is called using a pointer to a derived class, the pointer value mustbe implicitly converted to point to the appropriate base class. In this case, such an implicit conversion is illegal. Import library 'library' encountered in obj list Linker message Import libraries (import.lib) cannot be listed in a response file as OBJ files. They must always appear in the LIB file list. Import record does not match previous definition Linker message This warning usually occurs if an IMPDEF record appears in an import library when the import in question is also imported from a .DEF file. If the description of the imports differ in internal name or ordinal, this warning appears, and the first definition is used. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the Iw-imt command-line option. Import 'symbol' in module 'module' clashes with prior module Librarian message An import symbol can appear only once in a library file. A module that is being added to the library contains an import that is already in a module of the library and it cannot be added again. Improper use of typedef 'identifier' Compiler message Your source file used a typedef symbol where a variable should appear in an expression. Check for the declaration of the symbol and possible misspellings. Include files nested too deep Compiler message This message flags (directly or indirectly) recursive #include directives. Incompatible type conversion Compiler message The cast requested can't be done. Incorrect command line argument: 'argument' MAKE message You've used incorrect command-line arguments. Reenter the command and arguments. Incorrect number format Compiler message The compiler encountered a decimal point in a hexadecimal number. Incorrect option: Compiler message An error has occurred in either the configuration file or a command-line option. The compiler may not have recognized the configuration file parameter as legal; check for a preceding hyphen (-), or the compiler may not have recognized the command-line parameter as legal. This error can also occur if you use a #pragma option in your code with an invalid option. 560 c++ User's Guide Incorrect use of default Compiler message The compiler found no colon after the default keyword. Incorrect version of RLlNK32.DLL Linker message You don't have a the right version of RLINK32.DLL. Check to make sure that you have the correct version of the DLL. If not, delete that DLL and reinstall Borland C++. Initialization is only partially bracketed Compiler message (Command-line equivalent for displaying this warning = -wpin) When structures are initialized, braces can be used to mark the initialization of each member of the structure. If a member itself'is an array or structure, nested pairs of braces can be used. This ensures that the compiler's idea and your idea of what value goes with which member are the same. When some of the optional braces are omitted, the compiler issues this warning. Default = not displayed Initializer for object 'x' ignored Compiler message An error has occurred while using the command-line utility H2ASH. See the online file "tsm_util.txt" for further information about this utility. Initializing 'identifier' with 'identifier' Compiler message (Command-line equivalent for displaying this warning = -wbei) You're trying to initialize an enum variable to a different type. For example, the following initialization will result in this warning, because 2 is of type int, not type enum count: enum count zero, one, two x = 2; It is better programming practice to use an enum identifier instead of a literal integer when assigning to or initializing enum types. This is an error, but is reduced to a warning to give existing programs a chance to work. Initializing enumeration with type . Compiler message You're trying to initialize an enum variable to a different type. For example, enum count { zero, one, two} x = 2; will result in this warning, because 2 is of type int, not type enum count. It is better programming practice to use an enum identifier instead of a literal integer when assigning to or initializing enum types. This is an error, but is reduced to a warning to give existing programs a chance to work. Inline assembly not allowed Compiler message Your source file contains inline assembly language statements and you are compiling it from within the integrated environment. You must use the BCC command to compile this source file from the DOS command line. Inline assembly not allowed in inline and template functions Compiler message The compiler can't handle inline assembly statements in a C++ inline or template function. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 561 You could eliminate the inline assembly code or, in the case of an inline function, make this a macro, and remove the inline storage class. Int and string types compared MAKE message You tried to compare an integer operand with a string operand in an !if or !eli£ expression. Internal code generator error Compiler message An error has occurred in the internal logic of the code generator. Contact Borland Technical Support. Internal compiler error Compiler message An error occurred in the internal logic of the compiler. This error shouldn't occur in practice, but it could be generated if a more specific error message is not available. Internal linker error 'errorcode' Linker message An error occurred in the internal logic of the linker. This error shouldn't occur, but it could be generated if a more specific error message is not available. If this error persists, write down the errorcode number and contact Borland Technical Support. Internal software error! Resource Linker message The resource linker encountered unexpected data. Restart the resource link. If the error persists, contact Borland Technical Support. Invalid 'expression' in scope override CompHer message The evaluator issues this message when there is an error in a scope override in an expression you are watching or inspecting. You can specify a symbol table, a compilation unit, a source file name, etc. as the scope of the expression, and the message will appear whenever the compiler cannot access the symbol table, compilation unit, or whatever. Invalid combination of opcode and operands Compiler message The ~uilt-in assembler does not accept this combination of operands. Possible Causes: • There are too many or too few operands for this assembler opcode. • The number of operands is correct, but their types or order do not match theopcode. Invalid entry at 'segment:xxxxh' Linker message This error indicates that a necessary entry was missing from the entry table of a Windows executable file. The application may not work in real mode unless you fix the code and the data. Invalid entry point offset Linker message This message occurs when modules with 32-bit records are linked. It usually means that the initial program entry point offset exceeds the DOS limit of 64K. Sample code that could produce this is: _TEXT main: 562 segment public 'CODE' C++ Use r' 5 G u ide _TEXT ends end main In this case, the linker is trying to apply the fixup contained in the record for main, but there is no code. Invalid exe filename: 'filename' Linker message The .EXE file name has an incorrect extension such as .OBJ, .MAP,.LIB, .DEF, or .RES. Invalid extended dictionary in library 'library': extended dictionaries ignored Linker message An extended dictionary in the library in question was generated with an outdated version of TLIB. Rebuild the library with a current version of TLIB, specifying that an extended dictionary be created. Invalid file/object alignment value 'value' Linker message You specified an incorrect value for file or object alignment in the 32-bit lillker options. The value must be a number (either decimal or hex) that is a power of 2. The smallest allowable file alignment value is 16. The smallest allowable object alignment value is 4096. Invalid function call Compiler message A requested function call failed because the function is not available in the program, a parameter cannot be evaluated, and so on. The eval~ator issues this message. Invalid indirection Compiler message The indirection operator (*) requires a non-void pointer as the operand. Example int main (void) void *p; *p = 10; return 0; /* ERROR: Invalid Indirection */ } Invalid initial stack offset Linker message This message occurs only when modules with 32-bit records are linked. It means that the initial stack pointer value exceeds the DOS limit of 64K. Invalid macro argument separator Compiler message In a macro definition, arguments must be separated by commas. The compiler encountered some other character after an argument name. This is correct: #define tri_add(a, b, c) ((a) + (b) + (c)) This is incorrect: #define tri_add(a Invalid map filename: 'filename' b. c) ((a) + (b) + (c)) Linker message The map file name had an incorrect extension, such as .OBJ, .EXE, .DLL, .LIB, .DEF, or .RES. Appendix A, Error messages and warnings 563 Invalid overlay switch specification Linker message You specified an overlay option but omitted the file name or names. Delete the switches or add the names of the files containing the overlays. Invalid page size value ignored Librarian message The librarian encountered an invalid page size. The page size must be an integer that is a power of 2. Invalid Pass Count value entered IDE Debugger message The Pass Count value you gave was invalid. Valid values for Pass Count are from 0 to 4294967295. Invalid pathname for executable IDE Debugger message The debugger was unable to find the executable you tried to load. Invalid pointer addition Compiler message Your source file attempted to add two pointers together. Invalid process id IDE Debugger message You specified a process ID that does not match the ID of any active process. Invalid register combination (e.g., [BP+BX]) Compiler message The built-in assembler detected an illegal combination of registers in an instruction. These are valid index register combinations: • • • • • • • • [BX] [BP] [51] [DI] [BX+SI] [BX+DI] [BP+SI] [BP+DI] Other index register combinations are not allowed. Invalid segment definition in module 'module' Linker message This error results from an invalid GRPDEF record in an .OBJ file. This could result from custom-built .OBJ files or a bug in the translator used to generate the .OBJ file. If this occurs in a file created by a Borland compiler, recompile the file. If the error persists, contact Borland Technical Support. Invalid size specified for segment alignment Linker message This error occurs if an invalid value is specified for the Segment Alignment setting. The value specified must be an integral multiple of 2 and less than 64K. Common values are 16 and 512. This error only occurs when linking Windows applications. Invalid size specified for segment packing Linker message A non-decimal number was provided on the command line for the segment packing size limit. 564 c++ User's Guide Invalid stack reserve/commit size 'size' Linker message The heap or stack commit size specified is not valid. The default and minimum values for reserve and commit sizes are shown here. Stack Heap Commit Stack Heap 1Mb 4K 1Mb Default Millimum 8K 4K 4K OK OK Change the stack and heap reserve or commit sizes by changing the 32-bit linker values in the IDE or by changing HEAPSIZE and STACKSIZE in the module definition file. Invalid target rr 'target' Linker message The command-line linker found an invalid target. Valid targets are 'w' and 'd.' Invalid template argument list Compiler message This error indicates that an illegal template argument list was found. In a template declaration, the keyword template must be followed by a list of formal arguments enclosed within < and> delimiters. Invalid template member definition Compiler message After the declarator of a template member, either a semicolon, an initialization, or a body was expected, but some other, illegal token was found. This message appears when a template member is declared outside of the template, but the syntax was wrong. Invalid template qualified name 'template::name' CQmpiler message When defining a template class member, the actual arguments in the template class name used as the left operand for the :: operator must match the formal arguments of the template class. Invalid Thread Id entered . IDE Debugger message The Thread ID value you gave was invalid. Valid values for Thread Id are from 0 to 4294967295. Invalid use of dot An identifier must immediately follow a period operator (.). Compiler message Example struct faa int Xi int Yi }p = O,Oi int main (void) p.X++i /* Correct */ p. /* Error: Invalid use of dot */ Y++; return Oi Appendix A, Error messages and warnings 565 Invalid use of namespace 'identifier' Compiler message A namespace identifier was used in an illegal way, for example, in an expression. Invalid use of template 'template' Compiler message You can only use a template class name without specifying its actual arguments inside a template definition. Using a template class name without specifying its actual arguments outside a template definition is illegal. Irreducible expression tree Compiler message This is a sign of some form of compiler error. An expression on the indicated line of the source file caused the code generator to be unable to generate code. The expression should be avoided. Notify Borland if an expression can consistently . reproduce this error. Last parameter of 'operator' must have type 'int' Compiler message When a postfix operator ++ or operator--is overloaded, the last parameter must be . declared with the type int. Library too large, restart with library page size 'size' Librarian message The library being created could not be built with the current library page size. You can set the library page size with the Library Page Size option. Limit of 254 segments for new executable file exceeded Linker message You have reached the limit of segments that can be specified by the executable file format. Only 254 segments can be represented in Windows EXEs and DLLs. Usually one of two things causes this problem. If the application is a large model, the code segment packing size could be so small that there are too many code segments. To reduce the total number of segments to below 254, tum on the Pack Code Segments option. The other possibility is that you have a lot of far data segments with only a few bytes of data in them. Examine the map file. It should tell you if this is happening. In this case, reduce the number of far data, segments. Linkage specification not allowed Compiler message Linkage specifications such as extern "C" are only allowed at the file level. Move this function declaration out to the file level. Linker stack overflow Linker message The linker uses a recursive procedure for marking modules to be included in an executable image from libraries. This procedure can cause stack overflows in extreme circumstances. If you get this error message, remove some modules from libraries, include them with the object files in the link, and try again. Loading: 'programname' The debugger is loading the specified program. 566 c++ User's Guide IDE Debugger message Local data exceeds segment size limit Compiler message The local variables in the currenffunction take up more than 64K. Due to limitations of the processor, this is illegal in 16-bit programs. Log Expr checked but no value entered IDE Debugger message You checked the Log Expr check box, but forgot to specify an expression. Log Msg checked but no value entered IDE Debugger message You checked the Log Msg check box, but forgot to specify a message. Lvalue required Compiler message The left side of an assignment operator must be an addressable expression. Addressable expressions include the following: • Numeric or pointer variables • Structure field references or indirection through a pointer • Subscripted array element Macro argument syntax error An argument in a macro definition must be an identifier. Compiler message The compiler encountered some non-identifier character where an argument was expected. . Macro definition ignored Compiler message An error has occurred while using the command-line utility H2ASH. See the online file "tsm_util.txt" for further information about this utility. Compiler message Macro expansion too long A macro can't expand to more than 4,096 characters. Macro expansion too long MAKE message A macro cannot expand to more than 4,096 characters. This error often occurs if a macro recursively expands itself. A macro cannot legally expand to itself. Macro replace text 'string' is too long MAKE message The macro replacement text string overflowed MAKE's internal buffer of 512 bytes. Macro substitute text 'string' is too long MAKE message The macro substitution text string overflowed MAKE's internal buffer of 512 bytes. 'macroname' . ')' missing in macro invocation MAKE message The macro you entered is missing a right parenthesis. Main must have a return type of int Compiler message In C++, function main has special requirements, one of which is that it cannot be declared with any return type other than int. Make failed IDE Debugger message The make spawned by the debugger to try to bring the current target up to date failed. Check the Build Time tab in the Message view to see the reason for the failure. APpen d i x A, Err 0 r me 5 5 age 5 and war n i n 9 5 567 Make the modified code? IDE Debugger message You had a process loaded in the integrated debugger and then you modified the source code for the process. You should. probably build the new code instead of continuing to debug the old executable. Malformed command-line Linker message You specified an invalid entry on the command line. Check the command you entered. Matching base class function 'function' has different dispatch number Compiler message If a DDVT function is declared in a derived class, the matching base class function must have the same dispatch number as the derived function. Matching base class function 'function' is not dynamic Compiler message If a DDVT function is declared in a derived class, the matching base class function must also be dynamic. Maximum precision used for member pointer type 'type' Compiler message When a member pointer type is declared, its class has not been fully defined, and the Vmd option has been used, the compiler has to use the most general (and the least efficient) representation for that member pointer typ~. This can cause less efficient code to be generated (and make the member pointer type unnecessarily large), and can also cause problems with separate compilation; see the -Vm compiler switch for details. Member 'member' cannot be used without an object Compiler message This means that you have written class::member, where 'member' is an ordinary (nonstatic) member, and there is no class to associate with that member. For example, it is legal to write this: obj.class::member but not to write this: class: : member Member 'member' has the same name as its class Compiler message A static data member, enumerator, member of an anonymous union, or nested type cannot have the same name as its class. Only a member function or a non-static member can have a name that is identical to its class. Member 'member' is initialized more than once Compiler message In a C++ class constructor, the list of initializatioris following the constructor header includes the same member name more than once. Member function must be called or its address taken Compiler message A reference to a member function must be called, or its address must be taken with & operator. In this case, a member function has been used in an illegal context For example: class A void (A:: * infptr) (void) ; public; A(); 568 c++ User's Guide void myex(void) ; }; A: :A() { infptr infptr = myex; //illegal - call = A::& myex; //correct myex or take address? Member identifier expected Compiler message The name of a structure or C++ class member was expected here, but not found. The right side a dot (.) or arrow (-» operator must be the name of a member in the structure or class on the left of the operator. Member is ambiguous: 'member1' and 'member2' Compiler message You must qualify the member reference with the appropriate base class name. In C++ class 'Class', member 'member' canbe found in more than one base class, and it was not qualified to indicate which one you meant. This applies only in multiple inheritance, where the member name in each base class is not hidden by the same member name in a derived class on the same path. The C++ language rules require that this test for ambiguity be made before checking for access rights (private, protected, public). It is possible to get this message even though only one (or none) of the members can be accessed. 'member' is not a valid template type member Compiler message A member of a template with some actual arguments that depend on the formal . arguments of an enclosing template was found not to be a member of the specified template in a particular instance. 'member' is not accessible Compiler message You are trying to reference C++ class member 'member,' but it is private or protected and can't be referenced from this function. This sometimes happens when you attempt to call one accessible overloaded member function (or constructor), but the arguments match an inaccessible function. The check for overload resolution is always made before checking for accessibility. If this is the problem, try an explicit cast of one or more parameters to select the desired accessible function. Virtual base class constructors must be accessible within the scope of the most derived class. This is because C++ always constructs virtual base classes first, no matter how far down the hierarchy they are. For example: class A { public: A(); }; class B private virtual A {}; APpen d i X A, Err 0 r me s sag e san d war n i n 9 s 569 class C public: private B { C() ; }; C: : C () {} / / error I A:: A () is not accessible Since A is private to B, which is private to C, it makes A's constructor not accessible to C. However, the constructor for C must be able to call the constructors for its virtual base class, A. If B inherits A publicly, the above example would compile. Member pointer required on right side of.* or ->* Compiler message The right side of a C++ dot-star (.*) or an arrow star (->*) operator must be declared as a pointer to a member of the class specified by the left side of the operator. In this case, the right side is not a member pointer. Memory full listing truncated! Librarian message The librarian ran out of memory while creating a library listing file. An incomplete list file will be created. Memory reference expected Compiler message The built-in assembler requires a memory reference. You probably forgot to put square brackets around an index register operand. Misplaced break Compiler message The compiler encountered a break statement outside a switch or looping construct. You can only use break statements inside of switch statements or loops. Misplaced continue Compiler message The compiler encountered a continue statement outside a looping construct. Misplaced decimal point Compiler message The compiler encountered a decimal point in a floating-point constant as part of the exponent. Misplaced elif directive Compiler message The compiler encountered an #elif directive without any matching #if, #ifdef, or #ifndef directive. Misplaced elif statement An !elif directive is missing a matching !if directive. Misplaced else MAKE message Compiler message The compiler encountered an else statement without a matching if statement. Possible Causes: • An extra" else" statement • An extra semicolon • Missing braces • Some syntax error in a previous "if" statement 570 C++ Use r 's G u ide Misplaced else directive Compiler message The compiler encountered an #else directive without any matching #if, #ifdef, or #ifndef directive. Misplaced else statement MAKE message An !else directive is missing a matching !if directive. Misplaced endif directive Compiler message The compiler encountered an #endif directive without any matching #if, #ifdef, or ' #ifndef directive. Misplaced endif statement MAKE message An !endif directive is missing a matching !if directive. Missing 'identifier' in scope override Compiler message The syntax of a scope override is somehow incomplete. The evaluator issues this message. missing] Compiler message This error is generated if any of the following occur: • Your source file declared an array in which the array bounds were not terminated by a right bracket. • The array specifier in an operator is missing a right bracket. • The operator ~ ] was declared as operator [. • A right bracket is missing from a subscripting expression. Add the bracket or fix the declaration. Check for a missing or extra operator or mismatched parentheses. Mixed common types in module 'module'. Cannot mix COMDEFs and VIRDEFs. Linker message You cannot mix both COMDEFs and VIRDEFs. Tum off the -Fc switch to stop generating COMDEFs, or turn on the -Vs switch to stop generating VIRDEFs. Mixing pointers to different 'char' types Compiler message (Command-line equivalent for displaying this warning = -wucp) You converted a signed char pointer to an unsigned char pointer, or vice versa, without using an explicit cast. (Strictly speaking, this is incorrect, but it is often harmless.) Default = not displayed 'module' already in LIB, not changed! Librarian message This warning indicates that you attempted to use the + action on the library, but an object with the same name already exists in the library. To update the module, the action should be +-. The library was not modified. 'module' not found in library Librarian message An attempt to perform either a remove (-) or an extract (*) on a library has occurred and the indicated object does not exist in the library. Multiple base classes not supported Compiler message An error has occurred while using the command-line utility H2ASH. See the online file "tsm_util.txt" for further information about this utility. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 571 Multiple base classes require explicit class names Compiler message In Ii C++ class constructor, if there is more than one immediate base class, each base class constructor call in the constructor header must include the base class name. Multiple declaration for 'identifier' Compiler message This identifier was improperly declared more than once. This might be caused by conflicting declarations such as: • • • • int a; double a; a function declared two different ways, or a label repeated in the same function, or some declaration repeated other than an extern function or a simple variable This can also happen by inadvertently including the same header file twice. For example, given: //a.h struct A { int ai }i / /b.h #include "a.h" //myprog.cpp #include "a.h" #include "b.h" myprog.cpp will get two declarations for the struct A. To protect against this, one would write the a.h header file as: //a.h #ifndef _A_H #define _A_H struct A { int ai }i #endif This will allow one to safely include a.h several times in the same source code file. Multiple entry pOints defined Linker message Multiple entry points were defined for the application. This can happen if you have specified the startup code twice, or if you are making use of assembler code which defines a starting address for the application. Multiple public definitions for symbol 'symbol' in module 'module;' link case sensitively Linker message The specified symbol was encountered twice in the same module. This is usually caused by the use of case-sensitive symbols. Try linking case sensitively. Multiple stack segments found. The most recent one will be used. Linker message This warning occurs when two stack segments of different names are defined in the object modules. The startup code defines a stack segment for the application. You can suppress this warning with the Iw-msk command-line option. 572 C++ Use r' s G u ide Must take address of a memory location Compiler message Your source file used the address-of operator (&) with an expression that can't be used that way; for example, a register variable. NAMEDIR resource too big to link. Resource Linker message The name-table maximum size has been exceeded. Name-table entries are not used in Windows 3.1 or later. Namespace member 'identifier' declared outside its namespace Compiler message Namespace members must be declared inside their namespace. You can only use explicit qualification to define a namespace member (for example, to give a body for a function declared in a namespace). The declaration itself must be inside the namespace. Namespace name expected Compiler message The name of a namespace symbol was expected. Need an identifier to declare Compiler message In this context, an identifier was expected to complete the declaration. This might be a typedef with no name, or an extra semicolor:t at file level. In C++, it might be a class name improperly used as another kind of identifier. 'new' and 'delete' not supported Compiler message The integrated debugger does not support the evaluation of the new and delete operators. New executable header overflowed 64K Linker message Industry standards require that headers be no larger than 64K in size. If you encounter this message, check to see if the resident name table is increasing the size of the header so that it exceeds this limit. No : following the? Compiler message The question mark (?) and colon (:) operators do not match in this expression. The colon might have been omitted, or parentheses might be improperly nested or missing. No automatic data segment Linker message No group named DGROUP was found. Because the Borland initialization files define DGROUP, you will only see this error if you don't link with an initialization file and your program doesn't define DGROUP. Windows uses DGROUP to find the local data segment. The DGROUP is required for Windows applications (but not DLLs) unless DATA NONE is specified in the module definition file. No base class to initialize Compiler message This C++ class constructor is trying to implicitly call a base class constructor, but this class was declared with no base classes. Check your declarations. No closing quote MAKE message A string expression is missing a closing quote in an !if or !elif expression. No declaration for function 'function' Compiler message (Command-line equivalent for displaying this warning = -wnod) A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 573 This message is given if you call a function without first declaring that function. In C, you can declare a function without presenting a prototype, as in int funC()i In C++, every function declaration is also a prototype; this example is equivalent to int func (void) i The declaration can be either classic or modem (prototype) style. Default = not displayed No expression specified IDE Debugger message You forgot to specify an expression in the Add Watch dialog. No file corresponds to this item IDE Debugger message You tried to bring up a source view on an address, and there is no source file for the address. No file line specified IDE Debugger message You tried to add a Source breakpoint using the IDE Debugger but did not include the line number. Specify the line in the file where you want the breakpoint to occur in the Add Breakpoint dialog box. No file name ending Compiler message The file name in an #include statement was missing the correct closing quote or angle bracket. No file names given Compiler message The command line of the Borland C++ command-line compiler (BCC) contained no file names. You must specify a source file name. No filename ending MAKE message The file name in an !include statement is missing the correct closing quote or angle bracket. No internal name for IMPORT in .DEF file Linker message The .DEF file has a semantic error. You typed an illegal import sequence or forgot to put the internal name for an import before the module name. For example: IMPORTS _foo.l Here, _foo was to be the function to be imported, but the proper syntax is: IMPORTS _foo=rnydll.l No line corresponds to this item IDE Debugger message You tried to bring up a source view on an address, and there is no line number for the address. No macro before = You must name a macro before you can assign it a value; 574 C++ Use r 's G u ide MAKE message No match found for wildcard 'expression' MAKE message No files match the wildcard expression that you want MAKE to expand. For example, the following causes MAKE to send this error message if there are no files with the extension .OBI in the current directory: No module definition file specified: using defaults Linker message This warning occurs when you do not specify a .DEF file for the link. The following defaults are assumed: CODE PRELOAD MOVEABLE DrSCARDABLE DATA PRELOAD MOVEABLE MULTIPLE (if an .EXE) DATA PRELOAD MOVEABLE SINGLE (if a .DLL) HEAPSIZE 1048576 1048576 STACKSIZE You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the Iw-def command-line option. No module name specified IDE Debugger message You tried to add a module breakpoint using the IDE Debugger but you omitted the module name. Specify the module name where you want to insert the breakpoint in the Add Breakpoint dialog box. No module specified IDE Debugger message You tried to add an Address breakpoint using the IDE Debugger but you omitted the module. Specify the module where you want to insert the breakpoint in the Add Breakpoint dialog box. No object specified IDE Debugger message You tried to add an Address breakpoint using the IDE Debugger but you omitted the object. Specify the name of the object into which you want to insert the breakpoint in the Add Breakpoint dialog box. No offset specified IDE Debugger message You tried to add an Address breakpoint using the IDE Debugger but you omitted the offset that indicates where you want to insert the breakpoint. Specify the offset in the Add Breakpoint dialog box. No output file specified Linker message You did not specify an output file. No process selected IDE Debugger m,essage You pressed the Attach button on the debugger's Attach dialog when there was no process selected in the process list. No process to load IDE Debugger message You left the Program Name field blank on the Load Program dialog. No process to reset IDE Debugger message You tried to reset a process but there was no process running. A Ppen d i x A, Err 0 r m e s sag e san d war n i n 9 s 575 No process to stop IDE Debugger message You tried to pause a process but there was no process running. No process to terminate IDE Debugger message You tried to terminate processes but there was no process running at the time. No program entry point Linker message This message appears if no starting execution point was defined in the application. This usually happens if you forget to link in the startup code. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the Iw-ent command-line option. No program starting address defined Linker message This warning means that no module defined the initial starting address of the program. You probably forgot to link in the initialization module COx.OBJ. This warning should not occur when linking a Windows DLL. No resources. Resource Linker message This warning message occurs if the resource linker is given a resource file that contains no resources. No stack Linker message This warning is issued if no stack segment is defined in any of the object files or in any of the libraries included in the link. Except for DLLs, this indicates an error. If a Borland C++ program produces this message, make sure you are using the correct COx startup object files. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the Ik (16-bit) or Iw-srf (32-bit) command-line option. No stub for fixup at 'address' in module 'module' Linker message This error occurs when the target for a fixup is in an overlay segment, but no stub is found for a target external. This is usually the result of not making public a symbol in an overlay that is referenced from the same module. No terminator specified for in-line file operator MAKE message The makefile contains either the && or« command-line operators to start an inline file, but the file is not terminated. No thread 10 specified IDE Debugger message You tried to add a thread breakpoint using the IDE Debugger but you omitted the thread ID. Type the ID number of the thread you want to monitor in the Add Breakpoint dialog box. No type information Compiler message The integrated debugger has no type information for this variable. Ensure that you've compiled the module with debug information. If it has, the module may have been compiled by another compiler or assembler. 576 C++ Use r' s Gu ide No type specified IDE Debugger message You tried to add a C++ exception breakpoint using the IDE Debugger. You must specify a type in the Add Breakpoint dialog box to set this- type of breakpoint. No watch address specified IDE Debugger message You specified a data watch breakpoint using the IDE Debugger but you omitted the watch address. You need to specify both a memory address and the number of bytes to w~ , No watch length specified IDE Debugger message You specified a data watch breakpoint using the IDE Debugger but you omitted the watch length. You need to specify both a memory address and the number of bytes to watch. Non-ANSI keyword used: 'keyword' Compiler message A non-ANSI keyword (such as '_fastcall') was used when strict ANSI conformance was requested via the -A option. Non-const function 'function' called for const object Compiler message (Command-line equivalent for displaying this warning = -wncf) A non-const member function was called for a const object. (This is an error, but was reduced to a warning to give existing programs a chance to work.) Default = displayed Non-existent segment 'segment' in SEGMENTS section of .DEF file Linker message You specified a segment name in the SEGMENTS section of the .DEF file which doesn't exist in any of the object files or library files included in the link. Non-portable pointer comparison Compiler message (Command-line equivalent for displaying this warning = -wcpt) Your source file compared a pointer to a non-pointer other than the c~nstant O. You should use a cast to suppress this warning if the comparison is proper. Default = displayed Non-portable pointer conversion Compiler message (Command-line equivalent for controlling display = -wrpt) An implicit conversion between a pointer and an integral type is required, but the types are not the same size. This can't be done without an explicit cast. This conversion might not make any sense, so be sure this is what you want to do. Non-virtual function 'function' declared pure Compiler message Only virtual functions can be declared pure, because derived classes must be able to override them. Non-volatile function 'function' called for volatile object Compiler message In C++, a class member function was called for a volatile object of the class type, but the function was not declared with volatile following the function header. Only a volatile member function can be called for a volatile object. Appendix A ,E r r 0 r messages and warnings 577 For example; if you have class c public: f () volatile; g() ; }; volatile c vcvar; it is legal to call vcvar . f ( ) , but not to call vcvar . g ( ) . Nonportable pointer conversion Compiler message (Command-line equivalent for displaying this warning = -wrpt) A nonzero integral value is used in a context where a pointer is needed or where an integral value is needed; the sizes of the integral type and pointer are the same. Use an explicit cast if this is what you really meant to do. Default = displayed Nonresident Name Table is greater than 64K Linker message Industry standards require that nomesident name tables be no larger than 64K in size. If you encounter this message and do not require the nomesident name table to remain intact, you can discard it by linking with the IGn linker option. If you do require that the nomesident name table remain intact, you must restructure your program, so that names are shorter or explicitly use the resident name table for a portion of the defines. Nontype template argument must be of scalar type Compiler message A nontype formal template argument must have scalar type; it can have an integral, enumeration, or pointer type. Not a valid expression format type Compiler message Invalid format specifier following expression in the debug evaluate or watch window. A valid format specifier is an optional repeat value followed by a format character (c, d, f[n], h, x, m, p, r, or s). Not a Windows format EXE file. Resource Linker message The executable file you· tried to bind resources to is not a valid Windows or Win32 executable file. Not all breakpoints were valid IDE Debugger message You set breakpoints in yO~lr program but they were not all valid. Check the breakpoint view to see which breakpoints were invalid. Not an allowed type Compiler message Your source file declared some sort of forbidden type; for example, a function returning a function or array. Not enough memory MAKE message All of your working storage has been exhausted. Not enough memory for command-line buffer This error occurs when the librarian runs out of memory. 578 C++ Use r 's G u ide Librarian message Not enough memory to run application Linker message There is not enough memory to run the linker. Try closing one or more applications, then run the linker again. Null pointer assignment Run-time message When a small or medium memory model program exits, a check is made to determine if the contents of the first few bytes within the program's data segment have changed. These bytes would never be altered by a working program. If they have been changed, this message is displayed to inform you that (most likely) a value was stored to an uninitialized pointer. The program might appear to work properly in all other respects; however, this is a serious bug which should be attended to immediately. Failure to correct an uninitialized pointer can lead to unpredictable behavior (including locking the computer up in the large, compact, and huge memory models). You can use the integrated debugger to track down null pointers. Numeric constant too large Compiler message String and character escape sequences larger than hexadecimal or octal 77 can't be generated. Two-byte character constants can be specified by using a second backslash. For example, \\ represents a two-byte constant. A numeric literal following an escape sequence should be broken up like this: printf(n" "12345"); This prints a carriage return followed by 12345. Object module 'filename' is invalid Librarian message The librarian could not understand the header record of the object module being added to the library. The librarian assumes that it is an invalid module. Objects of type 'type' cannot be initialized with {} Compiler message Ordinary C structures can be initialized with a set of values inside braces. C++ classes can onlybe initialized with constructors if the class has constructors, private members, functions, or base classes that are virtual. Old debug information in module 'module' will be ignored Linker message Debug information in the OBJ is incompatible with this linker, and will be ignored. Only «KEEP or «NOKEEP MAKE message You specified something besides KEEP or NOKEEP when closing a temporary inline file. Only member functions may be 'const' or 'volatile' Compiler message Something other than a class member function has been declared const or volatile. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 579 Only one of a set of overloaded functions can be "e" Compiler message C++ functions are by default overloaded, and the compiler assigns a new name to each function. If you wish to override the compiler's assigning a new name by declaring the function extern "C", you can do this for only one of a set of functions with the same name. (Otherwise the linker would find more than one global function with the same name.) Operand of 'delete' must be non-const pointer Compiler message It is illegal to delete a variable that is not a pointer. It is also illegal to delete a pointer to a constant. For example: canst int x=10; canst int * a = &X; int * canst b = new inti int &c = *b; delete a; I/illegal - deleting pointer to constant delete b; Illegal delete c; Ilillegal - operand not of pointer type //should use 'delete&c' instead operator -> must return a pointer or a class Compiler message The C++ operator -> function must be declared· to either return a class or a pointer to a class (or struct or"union). In either case, it must be something to which the -> operator can be applied. operator delete must return void Compiler messages This C++ overloaded operator delete was declared in some other way. Declare the operator delete with one of the following: 1 A single void* parameter, or 2 A second parameter of type size_t If you use the second version, it will be used in preference to the first version. The global operator delete can only be declared using the single-parameter form. Operator must be declared as function Compiler message An overloaded operator was declared with something other than function type. For example: class A A& operator +; .. note missing parenthesis }; In the example, the function operator '0' is missing, so the operator does not have function type and generates this error. 'operator' must be declared with one or no parameters Compiler message When operator ++ or operator--is declared as a member function, it must be declared to take either: 580 C++ Use r 's G u ide • No parameters (for the prefix version of the operator), or • One parameter of type int (for the postfix version) 'operator' must be declared with one or two parameters Compiler message When operator ++ or operator--is declared as a non-member function, it must be declared to take either: • one parameter (for the prefix version of the operator), or • two parameters (for the postfix version) operator new must have an initial parameter of type sizeJ Compiler messages Operator new can be declared with an arbitrary number of parameters. It must always have at least one, the amount of space to allocate. Operator new must return an object of type void * Operator newD must return an object of type void * Compiler messages This C++ overloaded operator new was declared in some other way. Operators may not have default argument values It is illegal for overloaded operators to have default argument values. Optimizer: Error Reading Input File Compiler message Linker message The hardware error "read failed" occurred. Optimizer: Error Writing Output File Linker message The disk is either full, or the hardware error "write failed" occurred. Optimizer: File is not new exe (NE format), optimization request ignored Linker message The 16-bit lOx linker switches are valid for only 16-bit Windows and DPMI executables. Optimizer: Out of Memory Linker message Not enough memory available to perform optimizations. OS exception number not specified IDE Debugger message You tried to add an as exception breakpoint using the IDE Debugger. You must include an as exception number if you want to add a breakpoint when a particular as exception occurs. Select one of the exceptions in the list box next to the Exception # field or enter a user-defined exception number. Out of memory Librarian message For any number of reasons, the librarian or the C++ IDE ran out of memory while building the library. For many specific cases, a more detailed message is reported. Close one or more applications. Out of memory Compiler message The total working storage is exhausted. This error can occur under the following circumstances: Not enough virtual memory is available for compiling a particular file. In this case, shut down any other concurrent applications. You may also try to reconfigure your machine for more available virtual memory, or break up the source file being compiled into smaller separate components. You can also compile the file on a system with more available RAM. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 581 The compiler has encountered an exceedingly complex or long expression at the line indicated and has insufficient reserves to parse it. Break the expression down into separate statements. Out of memory Linker message The linker has run out of dynamically allocated memory needed during the link process. The total working storage is exhausted. This error is a catchall for running into a limit on memory usage. This usually means that too many modules, externals, groups, or segments have been defined by the object files being linked together. Solutions: • You can try reducing size of active RAM disks and/ or disk caches. • Close one or more applications to free memory. Out of memory! Resource Linker message Not enough memory is available for compiling a particular file. In this case, shut down any other concurrent applications. You may also try to re-configure your machine for more available memory, or break up the source file being compiled into smaller separate components. You can also compile the file on a system with more available RAM. Out of memory at library 'library': extended dictionaries ignored Linker message The linker has run out of dynamically allocated memory needed during the link process. The total working storage is exhausted. This error is a catchall for running into a limit on memory usage. Solutions: • You can try reducing size of active RAM disks and/ or disk caches. • Close one or more applications to free up memory. Out of memory creating extended dictionary Librarian message The librarian ran out of memory while creating an extended dictionary for a library. The library is created but will not have an extended dictionary. Out of memory for block 'block' Linker message The linker ran out of memory. Try reducing the size of disk caches and/or RAM drives. Out of memory reading LE/LIDATA record from object module Librarian message The librarian is attempting to read a record of data from the object module, but it cannot get a large enough block of memory. If the module being added has a large data segment or segments, try adding this module before other modules. Out of space allocating per module debug struct Librarian message The librarian ran out of memory while allocating space for the debug information associated with a particular object module. Try removing debugging information from the modules being added to the library to resolve the problem. Output device is full Librarian message The output device is full. This error usually means that there is no space left on the disk. 582 C++ Use r '5 G U ide Overlays generated and no overlay manager included Linker message This warning is issued if overlays are created but the symbol __OVRTRAP__ is not defined in any of the object modules or libraries linked in. The standard overlay library (OVERLAY. LIB) defines this symbol. Overlays ignored in new executable image Linker message This error occurs if you attempt to link a Windows program with the 10 option on. Windows executables can't be overlaid, although, with discardable code segments, you should be able to achieve a similar effect. Overlays only supported in medium, large, and huge memory models Compiler message Only programs using the medium, large, or huge memory models can be overlaid. Overload is now unnecessary and obsolete Compiler message (Command-line equivalent for displaying this warning = -wovl) Early versions of C++ required the reserved word "overload" to mark overloaded function names. C++ now uses a "type-safe linkage" scheme, whereby all functions are assumed overloaded unless marked otherwise. The use of "overload" should be discontinued. Default = displayed Overloadable operator expected Compiler message Almost all C++ operators can be overloaded. These are the only ones that can't be overloaded: • • • • the field -selection dot ( • ) dot-star ( • *) double colon (: :) conditional expression (? : ) The preprocessor operators (# and ##) are not C or C++ language operators and thus can't be overloaded. Other non-operator punctuation, such as semicolon (;), can't be overloaded. Overloaded 'function name' ambiguous in this context Compiler message The only time an overloaded function name can be used or assigned without actually calling the function is when a vClriable or parameter of the correct function pointer type is initialized or assigned the address of the overload function. In this case, an overloaded function name has been used in some other context, for example, the following code will generate this error: elass A{ A() {myex;} void myex(int) {} void myex(float) {} Ilealling the function Ilor taking its address? }; Appendix A, Error messages and warnings 583 Overloaded function resolution not supported Compiler message In integrated debugger expression evaluation, resolution 'of overloaded functions or operators is not supported, not even to take an address. Overloaded prefix operator 'operator' used as a postfix operator Compiler message (Command-line equivalent for displaying this warning = -wpre) With the latest C++ specification, it is now possible to overload both the prefix and postfix versions of the ++ and -- operators. Whenever the prefix operator is overloaded, but is used in a postfix context, the compiler uses the prefix operator and issues this warning. This allows older code to compile. Default = not displayed Parameter 'number' missing name Compiler message In a function definition header, this parameter consisted only of a type specifier 'number' with no parameter name. This is not legal in C. (It is allowed in C++, but there's no way to refer to the parameter in the function.) Parameter 'parameter' is never used Compiler message (Command-line equivalent for displaying this warning = -wpar) The named parameter, declared in the function, was never used in the body of the function. This might or might not be an error and is often caused by misspelling the parameter. This warning can also occur if the identifier is redeclared as an automatic (local) variable in the body of the function. The parameter is masked by the automatic variable and remains unused. Default = displayed Parameter names are used only with a function body Compiler message When declaring a function (not defining it with a function body), you must use either. e:rp.pty parentheses or a function prototype. A list of' parameter names only is not allowed. Example declarations int int int int func(); /* func(int, int); /* func(int i, int j); /* func(i, j); /* Pass Count checked but no value entered declaration without prototype -- OK */ declaration with prototype -- OK */ parameter names in Prototype -- OK */ parameter names only -- ILLEGAL */ IDE Debugger message You checked the Pass Count check box, but forgot to provide a pass count. You need to specify a valid pass count. 'path' - path is too long Ubrarian message This error occurs when the length of any of the library file or module file's 'path' is greater then 64. 584 C++ Use r 's G u ide Pointer to structure required on left side of -> or ->* Compiler message Nothing but a pointer is allowed on the left side of the arrow (->) in C or C++. In C++ a -> operator is allowed. Linker message Possible reference to undefined extern xxxx::i Static data member has been declared but not defined in application. This warning occurs by itself (i.e., without an accompanying 'undefined symbol' error) whenever code declares a static data member that is not defined anywhere, and then that symbol is not actually referenced (it is then 'idle' code). Possible unresolved external 'symbol' referenced from module 'module' Linker message This warning appears only for static data members of classes that have been declared but not defined. Compiler message Possible use of 'identifier' before definition (Command-line equivalent for displaying this warning = -wdef) Your source file used the variable 'identifier' in an expression before it was assigned a value. The compiler uses a simple scan of the program to determine this condition. If the use of a variable occurs physically before any assignment, this warning will be generated. Of course, the actual flow of the program can assign the value before the program uses it. Default = not displayed Compiler message Possibly incorrect assignment (Command-line equivalent for displaying this warning = -wpia) This warning is generated when the compiler encounters an assignment operator as the main operator of a conditional expression (part of an if, while, or do-while statement). This is usually a typographical error for the equality operator. If you want to suppress this warning, enclose the assignri1ent in parentheses and compare the whole thing to zero explicitly. For example, this code i f (a = b) ... should be rewritten as i f ((a = b) ! = 0) Default = displayed Printf/Scanf floating-point formats not linked Run-time message Floating-point formats contain formatting information that is used to manipulate floating-point numbers in certain run-time library functions, such as scanfO and atofO. Typically, you should avoid linking the floating-point formats (which take up about lK) unless they are required by your application. However, you must explicitly link the floating-point formats for programs that manipulate fields in a limited and specific way. Appendix A, Error messages and warnings 585 Refer to the following list of potential causes (listed from most common to least common) to determine how to resolve this error: Cause: Floating point set to None. You set the floating-point option to None when it should be set to either Fast or Normal. Fix: Set Floating Point to Fast or Normal. Cause: Either the compiler is over-optimizing or the floating-point formats really do need to be linked. You need the floating-point formats if your program manipulates floats in a limited and specific way. Under certain conditions, the compiler will ignore floating-point usage inscanfO. For example, this may occur when trying to read data into a float variable that is part of an array contained in a structure. Fix: Add the following code to one source module: extern _floatconvert; #pragma extref _floatconvert Cause: You forgot to put the address operator & on the scanf variable expression. For example: float foo; scanf ("%f" I foo); Fix: Change the code so the & operator is used where needed. For example, change the above code to the following: float foo; scanf ("%f" I &foo); Process Created: 'processname' The process specified in the message has been created. IDE Debugger message Process 'processname' (Ox%X) is already being debugged You tried to attach to a process that is already being debugged. IDE Debugger message Process 'processname' (Ox%X) is the IDE IDE Debugger message You tried to attach to the IDE. This is not allowed. Specify another process. Process Stopped: 'processname' The process specified in the message was stopped. IDE Debugger message Process terminated: 'programname' The specified process has been terminated. IDE Debugger message Program entry point may not reside in an overlay Linker message Although almost all of an application can be overlaid, the initial starting address cannot reside in an overlay. This error usually means that an attempt was made to overlay the initialization module COx.OBJ, for instance, by specifying the /0 option"before the startup module. Public 'symbol' in module 'module1' clashes with prior module 'module2' Librarian message A public symbol can only appear once in a library file. A module, which is being added to the library, contains a public 'symbol' that is already in a module of the library and cannot be added. The command-line message reports the module2 name. 586 C++ Use r 's G u ide Public symbol 'symbol' defined in both module 'module1' and 'module2' Linker message There is a conflict between two public symbols. This usually means that a symbol is defined in two modules. • An error occurs if both are encountered in the .OBJ file(s), because TLINK doesn't know which is valid. • A warning results if TLINK finds one of the duplicated symbols in a library and finds the other in an .OBJ file; in this case, TLINK uses the one in the .OBJ file. Pure virtual function called Run-time message This is a run-time error. It is generated if the body of a pure virtual function was never generated and somehow the compiler tried to call it. Qualifier 'identifier' is not a class or namespace name Compiler message The C++ qualifier in the construction qual::identifier is not the name of a struct or class. Record kind 'num' found, expected theadr or Iheadr in module 'filename' Librarian message The librarian could not understand the header record of the object module being added to the library and has a~sumed that it is an invalid module. Record length 'len' exceeds available buffer in module 'module' Librarian message This error occurs when the record length 'len' exceeds the available buffer to load the buffer in module 'module'. This occurs when the librarian runs out of dynamic memory. Record type 'type' found, expected theadr or Iheadr in 'module' Librarian message The librarian encountered an unexpected type instead of the expected THEADR or LHEADER record in the specified module. Recursive template function: '" instantiated" Compiler message The compiler has detected a recursive template function instance. For example: template void f(T x) { f((T*)O); II recursive template function! void main() f (0); The compiler will issue one message per each nesting of the recursive instantiation, so it is usually quite obvious where the recursion has occurred. To fix a recursive template, either change the dependencies, or provide a specialized version that will stop the recursion. For example, adding the following function definition to the above program will remove the endless recursion: void f(int **) Compiler message Redefinition of 'macro' is not identical (Command-line equivalent for displaying this warning = -wdup) Appendix A, Error messages and warnings 587 Your source file redefined the macro 'ident' using text that was not exactly the same as the first definition of the macro. The new text replaces the old. Default = displayed Redefinition of target 'filename' MAKE message The named file occurs on the left side of more than one explicit rule. Reference initialized with 'type1', needs Ivalue of type 'type2' Compiler message A reference variable that is not declared constant must be initialized with an lvalue of the appropriate type. In this case, the initializer either wasn't an lvalue, or its type didn't match the reference being initialized. Reference member 'member' initialized with a non-reference parameter Compiler message An attempt has been made to bind a reference member to a constructor parameter. Since the paramete:r will cease to exist the moment the constructor returns to its caller, this will not work correctly. Reference member 'member' is not initialized Compiler message References must always be initialized, in the construGtor for the class. A class member of reference type must have an initializer provided in all constructors for that class. This means you can't depend on the compiler to generate constructors for such a class, because it has no way of knowing how to initialize the references. Reference member 'member' needs a temporary for initialization Compiler message You provided an initial value for a reference type that was not an lvalue of the referenced type. This requires the compiler to create a temporary for the initialization. Because there is no obvious place to store this temporary, the initialization is illegaL Register allocation failure . Compiler message This is a compiler error. An expression on the indicated line of the source file was so complicated that the code generator could not generate code for it. Simplify the expression. If this does not solve the problem, avoid the expression. Notify Borland if an expression can consistently reproduce this error. Relocation item exceeds 1 Meg DOS limit Linker message The DOS executable file format doesn't support relocation items for locations exceeding 1 MB. Although DOS could never load an image this big, DOS extenders can, and thus TLINK supports generating images greater than DOS could load. Even if the image is loaded with a DOS extender, the DOS executable file format is limited to describing relocation items in the first 1MB of the image. Relocation offset overflow Linker message This error only occurs for 32-bit object modules and indicates a relocation (segment fixup) offset greater than the DOS limit of 64K. Relocation table overflow Linker message This error only occurs for 32-bit object modules. The file being linked contains more base fixups than the standard DOS relocation table can hold (base fixups are created mostly by calls to far functions). 588 C++ Use r 's G u ide Repeat count needs an Ivalue Compiler message The expression before the comma (,) in the Watch or Evaluate window must be an accessible region of storage. For example, expressions like this one are not valid: i++,lOd x = y, 10m Reporting error. Resource Linker message The resource linker encountered a problem while trying to report an error. Resetting IDE Debugger message The process is being reset to its initial condition. Resident Name Table is greater than 64K Linker message Exports too great for 64K limit. When this error is encountered, break exports up or make some exported by name and some by ordinal number. Another possible fix is to have the linker transfer the resident name table to the nonresident name table and discard the nonresident name table. (TLINK options IGr IGn, IDE options on 16-bit linker page.) Resource binding failed Linker message While you were linking from the command l~e, RLINK.EXE reported an error when binding resources to your image. Resource format not recognized in file. Resource Linker message The format of a .RES file that you are attempting to use contains a resource with an unknown format. This is normally due to a corrupt resource file. Make sure that you are binding a legitimate resource file, and rebuild the .RES file, if necessary. Restarting compile using assembly Compiler message The compiler encountered anasm with no accompanying or #pragma inline statement. The compile restarts using assembly language capabilities. Results are safe in file 'filename' Librarian message The librarian has successfully built the library into a temporary file, but it cannot rename the file to the desired library name. The temporary file will not be removed (so that the library can be preserved). RTTI not available for expression evaluation Compiler message Expressions requiring RTTI are not supported by the expression evaluator in the integrated debugger. This error message is only issued by the expression evaluator (if you try to Inspect, Watch, or Evaluate), not by the compiler. Rule line too long MAKE message An implicit or explicit rule was longer than 4,096 characters. Running IDE Debugger message The process is running. Segment 'segment' exceeds 64K Linker message Industry standards require that segments be no larger than 64K in size. If you encounter this message, the segment in question has exceeded this limit. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 589 Segment 'segment' is in two groups: 'group1' and 'group2' Linker message The linker found conflicting claims by the two named groups. Usually, this happens only in assembly language programs. It means that two modules assigned the segment to two different groups. Segment 'segment' relocation data exceeds 64K Linker message 16-bit Windows programs have a limit of 64K of relocation data per segment. It is unlikely that this limit will ever be exceeded, but can be if a particular module contains extremely large jump tables or virtual tables in the code segment itself. If you get this message, try breaking the associated code module into two pieces, as this may reduce the total number of relocations per segment to below 64K. Segment alignment factor too small Linker message Segment alignment factor is too small to allow access to segments. If you encounter this error, use the fA linker option and try a larger alignment factor, like 1024. The fA option defaults to 512. Segment too large for segment table Linker message Industry standards require that segments be no larger than 64K in size. If you encounter this message, the segment in question has exceeded this limit. Self relative fixup overflowed in module 'module' Linker message This message appears if a self-relative reference (a call or ajump) is made from one physical segment to another. This often happens when employing assembler code, but can occur if you use the segment-naming options in the compiler. If the reference is from one code segment to another, you are safe. If, however, the reference is from a code segment to a data segment, you have probably made a mistake in some assembler code. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the fw-srf command-line option. Side effects are not allowed Compiler message Side effects such as assignments, ++, or -- are not allowed in the debugger watch window. A common error is to use x = y (not allowed) instead of x == Yto test the equality of x and y. Size of 'identifier' is unknown or zero Compiler message This identifier was used in a context where its size was needed. A struct tag.might only be declared (the struct not defined yet), or an extern array might be declared without a size. It's illegal then to have some references to such an item (like sizeD£) or to dereference a pointer to this type. Rearrange your declaration so that the size of 'identifier' is available. Size of the type 'identifier' is unknown or zero Compiler message This type was used in a context where its size was needed. For example, a struct tag might only be declared (the struct not defined yet). It's illegal then to have some references to such an item (like sizeo£) or to dereference a pointer to this type. Rearrange your declarations so that the size of this type is available. Size of the type is unknown or zero Compiler message This error message indicates that an array of Unspecified dimension nested within another structure is initialized and the -A (ANSI) switch is on. For example: 590 C++ Use r 's G u ide struct char all; //Size of 'a' is unknown or zero b = { "hello" }; //Size of the type is / /unknown or zero sizeof may not be applied to a bit field Compiler message sizeof retums the size of a data object in bytes, which does not apply to a bit field. sizeof may not be applied to a function Compiler message sizeof can be applied only to data objects, not functions. You can request the size of a pointer to a function. Specialization after first use of template Compiler message A new ANSI C++ rule requires that a specialization for a function template be declared before its first use. This error message is only issued when the ANSI conformance option (-A) is active. 'specifier' has already been included Compiler message This type specifier occurs more than once in this declaration. Delete or change one of the occurrences. Stack overflow Run-time message This error is reported when you compile a function with the Test Stack Overflow option on, but there is not enough stack space to allocate the function's local variables. This error can also be caused by the following: • Infinite recursion • An assembly language procedure that does not maintain the stack project • A large array in a function Stack size is less than 1400h.lt has been reset to 1400h Linker message The minimum allowable stack size is 1400h. When the linker detects that the stack size is less than this value, the linker automatically resets the size to 1400h and issues this message. To eliminate this message, you need to change the STACKSIZE specification in the .DEF file to 1400h or greater. The size of the stack added to the size of the Automatic Data Segment (ADS) must not exceed 64K. If it does, you won't get any linker errors regarding stack size or the message" Automatic data segment exceeds 64K." However, the Windows loader will not be able to load the .EXE at run time. STACK/HEAP commit 'size' greater than reserve 'size' Linker message The heap or stack commit size has to be less than or equal to the stack or heap reserve size. Change the stack and heap reserve or commit sizes by changing the 32-bit linker values in the IDE or by changing HEAPSIZE and STACKSIZE in the module definition file. statement missing ( Compiler message In a do, for, if, switch, or while statement, the compiler found no left parenthesis after the while keyword or test expression. A PPen d i x A, Err 0 r me s sag e san d war n i n 9 s 591 statement missing) Compiler message In a do, for, if, switch, or while statement, the compiler found no right parenthesis after the while keyword or test expression. Statement missing; Compiler message The compiler encountered an expression statement without a semicolon following it. Stopping IDE Debugger message The process is stopping. Storage class 'storage class' is not allowed here Compiler message The given storage class is not allowed here. Probably two storage classes were specified, and only one can be given. String literal not allowed in this context Compiler message This error message is issued by the evaluator when a string literal appears in a context other than a function call. String type not allowed with this operand MAKE message You tried to use an operand that is not allowed for comparing string types. Valid operands are ==, !=, <, >, <=, and >=. Structure packing size has changed Compiler message This warning message is issued when the structure alignment is different after including a file than it was before including that file. The intention is to warn you about cases where an include file changes structure packing, but by mistake doesn't restore the original setting at the end. If this is intentional, you can give a #pragma nopackwarning directive at the end of an include file to disable the warning for this file. The warning can be disabled altogether by #pragma warn -pck. Structure passed by value Compiler message (Command-line equivalent for displaying this warning = -wstv) This warning is generated any time a structure is passed by value as an argument. It is a frequent programming mistake to leave an address-of operator (&) off a structure when passing it as an argument. Because structures can be passed by value, this omission is acceptable. This warning provides a way for the compiler to warn you of this mistake. Default = not displayed Structure required on left side of. or.* Compiler message The left side of a dot (.) operator (or C++ dot-star operator, .*) must evaluate to a structure type. In this case it did not. This error can occur when you create an instance of a class using empty parentheses, and then try to access a member of that 'object'. Structure size too large Compiler message Your source file declared a structure larger than 64K. Stub program exceeds 64K Linker message This errors occurs if a DOS stub program written for a Windows application exceeds 64K. 592 C++ Use r ' s G u ide Stub programs are specified via the STUB module definition file statement. The linker only supports stub programs of 64K or smaller. Style of function definition is now obsolete Compiler message (Command-line equivalent for displaying this warning = -wofp) In C++, this old C style of function definition is illegal: int fune(pI, p2) int pI, p2; { /* ... */ } This practice might not be allowed by other C++ compilers. Default = displayed Superfluous &with function Compiler message (Command-line equivalent for displaying this warning = -wamp) An address-of operator (&) is not needed with function name; any such operators are discarded. Default = not displayed Suspicious pointer conversion Compiler message (Command-line equivalent for displaying this warning = -wsus) The compiler encountered some conversion of a pointer that caused the pointer to point to a different type. You should use a cast to suppress t~s warning if the conversion is proper. A common cause of this warning is when the C compiler converts a function pointer of one type to another (the C++ compiler generates an error when asked to do that). It can be suppressed by doing a typecast. Here is a common occurrence of it for Window programmers: #define STRICT #inelude LPARAM _export WridProe ( HWND , UINT , WPARAM , LPARAM ); test () { WNDCLASS we; we.lpfnWndProe = wndProe; //warning It is suppressed by making the assignment to lpfnWndProc as follows: we.lpfnWndProe = ( WNDPROC ) WndProe; Default = displayed Switch selection expression must be of integral type Compiler message The selection expression in parentheses in a switch statement must evaluate to an integral type (char, short, int, long, enum). You might be able to use an explicit cast to satisfy this requirement. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 593 'symbol' conflicts with module 'module' Linker message This indicates an inconsistency in the definition of 'symboL' It means that either the linker found one virtual function and one common definition with the same name. 'symbol' defined in module 'module' is duplicated in module 'module' Linker message This message results from a conflict between two symbols (either public or communal). It usually means that a symbol is defined in two modules. An error occurs if both are encountered in the .OBJ file(s), because the linker doesn't know which is valid. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the /w-dup command-line option. 'symbol' defined in module 'module1' is duplicated in module 'module2' Linker message There is a conflict between two symbols (either public or communal). This usually means that a symbol is defined in more than one object or library file. The linker issues a warning because the symbol exists in more than one object file. The linker will use the first instance of the symbol that is encountered. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the /d (16-bit) or /w-dpl (32-bit) command-line option. T3 and n fixups not allowed (module 'module') Linker message The linker encountered an object file with an incompatible .OBJ file format. This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Table limit exceeded Linker message This message results from one of the linker's internal tables overflowing. This usually means that the programs being linked have exceeded the linker's capacity for public symbols, external symbols, or logical segment definitions. Each instance of a distinct segment name in an object file counts as a logical segment; if two object files define this segment, then this results in two logical segments. When the table limit is exceeded, try linking with extended dictionaries. Target index of FIXUP is 0 in Module 'module' Linker message This is a translator error. Template argument must be a constant expression Compiler message A non-type template class argument must be a constant expression of the appropriate type. This includes constant integral expressions and addresses of objects or functions with external linkage or members. 594 C++ Use r 's G u ide Compiler message Template class nesting too deep: 'class' The compiler imposes a certain limit on the level of template class nesting. This limit is usually only exceeded through a recursive template class dependency. When this nesting limit is exceeded, the compiler issues this error message for all of the nested template classes. This usually makes it easy to spot the recursion. This error message is always followed by the fatal error "Out of memory". Template function argument 'argument' not used in argument types Compiler message The given argument was not used in the argument list of the function. The argument list of a template function must use all of the template formal arguments; otherwise, there is no way to generate a template function instance based on actual argument types. Compiler message Template functions may only have 'type-arguments' A function template was declared with a non-type argument. This is not allowed with a template function, as there is no way to specify the value when calling it. Templates and overloaded operators cannot have C linkage Compiler message You tried to use a linkage specification with a template or overloaded operator. The most common cause for this error message is having the declaration wrapped in an extern "c" {linkage specification. Templates can only be declared at file level Compiler message Templates cannot be declared inside classes or functions. They are only allowed in the global scope, or file level. For example: template void foo(Ta,Tb) { II error U is not used Templates must be classes or functions Compiler message The declaration in a template declaration must specify either a class type or a function. Templates not supported Compiler message An error has occurred while using the command-line utility H2ASH. See the online file "tsm_util.txt" for further information about this utility. Temporary used for parameter '???' Compiler message In C++, a variable or parameter of reference type must be assigned a reference to an object of the same type. If the types do not match, the actual value is assigned to a temporary of the correct type, and the address of the temporary is assigned to the reference variable or parameter. The warning means that the reference variable or parameter does not refer to what you expect, but to a temporary variable, otherwise unus~d. APpen d j x A, Err 0 r me s sag e san d war n'j ng s 595 In the following example, function f requires a reference to an int, and c is a char: f (int &) i char Ci f(c) i . Instead of calling f with the address of c, the compiler generates code equivalent to the C++ source code: int X = c, f (X) i Temporary used for parameter 'parameter' Temporary used for parameter 'parameter' in call to 'function' Temporary used for parameter 'number' Temporary used for parameter 'number' in call to 'function' Compiler messages Command-line equivalent for displaying this warning = -wlvc) In C++, a variable or parameter of.reference type must be assigned a reference to an object of the same type. If the types do not match, the actual value is assigned to a temporary of the correct type, and the address of the temporary is assigned to the reference variable or parameter. The warning means that the reference variable or parameter does not refer to what you expect, but to a temporary variable, otherwise unused. Default = displayed Temporary used for parameter 2 in call to '???' Compiler message In C++, a variable or parameter of reference type must be assigned a reference to an object of the same type. If the types do not match, the actual value is assigned to a temporary of the correct type, and the address of the temporary is assigned to the ref~rence variable or parameter. The warning means that the reference variable or parameter does not refer to what you expect, but to a temporary variable, otherwise unused. In the following example, function f requires a reference to an int, and c is a char: . f (int &) i char Ci f (c) i Instead of calling f with the address of c, the compiler generates code equivalent to the C++ source code: int X = c, f (X) i Temporary used to initialize 'identifier' Compiler message (Command-line equivalent for displaying this warnirig = -wlin) In C++, a variable or parameter of reference type must be assigned a reference to an object of the same type. If the types do not match, the actual value is assigned to a temporary of the correct type, and the address of the temporary is assigned to the reference variable or parameter. 596 C++ Use r 's Gu ide The warning means that the reference variable or parameter does not refer to what you expect, but to a temporary variable, otherwise unused. Default = displayed Terminated by user Linker message You cancelled the link (that is, a Ctrl+Break was detected). Terminating IDE Debugger message The process is terminating. The '...' handler must be last Compiler message In a list of catch handlers, if the '.. .' handler is present, it must be the last handler in the list (i.e., it can not be followed by any more catch handlers). The combinations '+*' or '*+' are not allowed Librarian message It is not legal to add and extract an object module from a library in one action. The constant member 'identifier' is not initialized Compiler message (Command-line equivalent for displaying this warning = -wnci) This C++ class contains a constant member 'member' that doesn't have an initialization. Note that constant members can be initialized only; they can't be assigned to. Default = displayed The constructor 'constructor' is not allowed Compiler message Constructors of the form X:: (X) are not allowed. This is the correct way to write a copy constructor: x:: (canst X&) • The expression cannot be modified. IDE Debugger message This is an integrated debugger error. You entered an expression in the Evaluator dialog box and clicked on Modify but the expression cannot be modified. The expression you entered could not be evaluated. IDE Debugger message This is an integrated debugger error. The integrated debugger could not interpret the expression you entered in the Evaluator dialog box. The function 'function' is not available Compiler message You tried to call a function that is known to the evaluator, but which was not present in the program being debugged-for example, an inline function. The value for 'identifier' is not within the range of an int Compiler message All enumerators must have values that can be represented as an integer. You have attempted to assign a value that is out of the range of an integer. If you need a constant of this value, use a canst integer. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 597 There is no code for 'file', line 'linenumber' IDE Debugger messag& You tried to view the disassembly for the given line of source code. The specified line of the file has no code associated with it. There is no expression to evaluate IDE Debugger message This is an integrated debugger error. You forgot to enter an expression in the Evaluator dialog box and no program is loaded. There is no expression to evaluate and no process is loaded IDE Debugger message This is an integrated debugger error. You forgot to enter an expression in the Evaluator dialog box and no program is loaded. 'this' can only be used within a member function Compiler message In C++, "this" is a reserved word that can be used only within class member functions. This operation not supported for 16 bit executables IDE Debugger message You tried to use a command (such as Reset or Pause) in the integrated debugger while the project was set to produce a 16-bit executable. The integrated debugger does not support 16-bit executables except to run or terminate them. THREAD fixup found in module 'module' Linker message The linker encountered an object file with an incompatible .OBJ file format. This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Thread stopped 'programname' 'reason' IDE Debugger message A thread in the specified program has stopped running for the reason listed. Too few arguments in template class name 'template' Compiler message A template class name was missing actual values for some of its formal parameters. Too few parameters in call Compiler message This error message occurs when a call to a function with a prototype (via a function pointer) had too few arguments. Prototypes require that all parameters be given. Make certain that your call to a function has the same parameters as the function prototype. Too few parameters in call to 'function' Compiler message A call to the named function (declared using a prototype) has too few arguments. Make certain that the parameters in the call to the function match the parameters of the function prototype. Too many commas on command-line Linker message You specified an invalid entry on the command line. Check the command you entered. Too many decimal points Compiler message The compiler encountered a floating-point constant with more than one decimal point. Too many default cases Compiler message The compiler encountered more than one default statement in a single switch. 598 C++ Use r 's G u ide Too many default libraries Linker message The linker can handle a maximum of 128 default libraries. Too many error or warning messages Compiler message There were more errors or warnings than set in the Options I Settings I Compiler Messages. Too many error or warning messages Linker message The limit on the number of error messages or warnings to be displayed has been reached. Too many errors Linker message The linker got more errors than the maxImum number of errors specified by the user. Too many exponents Compiler message The compiler encountered more than one exponent in a floating-point constant. Too many file names Linker message This error occurs if the linker encounters more than 64K characters in the response file. The linker only handles response files up to 64K. You'll need to shorten the response file, shorten the pathnames, or chunk the .OBJs into a library. Too many files to open. Resource Linker message You have exceeded the resource linkers limit on files. Try combining some of your individual resource files into a single re§ource. Too many initializers Compiler message The compiler encountered more initializers than were allowed by the declaration being initialized. Linker message Too many LNAMEs TLINK32 supports up to 255 LNAMEs appearing in an OBJ file. Too many resources to handle. Resource Linker message You have too many resources for the resource linker to handle. Try reducing the total number of resources you are trying to link. Too many rules for target 'target' MAKE message MAKE can't determine which rules to follow when building a target because you've created too many rules for the target. For example, the following makefile generates this error message: abe.exe : a.obj bee -e a.e abe.exe b.obj abe.exe e.obj bee -e b.e e.e Too many storage classes in declaration Compiler message A declaration can never have more than one storage class, either Auto, Register, Static, or Extem. A Ppen d i x A, Err 0 r me s sag e san d war n i n 9 s 599 Too many STRINGTABLEs to link. Resource Linker message The resource linker (RLINK) should not generate this message. You have too many string tables for the resource linker to handle. Try reducing the total number of string tables in your resource. Too many suffixes in .SUFFIXES list MAKE message The suffixes list can include up to 255 suffixes. Too many types in declaration Compiler message A declaration can never have more than one of these basic types: • • • • • • • • • char class int float double struct union enum typedef name Too much global data defined in file Compiler message The sum of the global data declarations exceeds 64K bytes. This includes any data stored in the DGROUP (all global variables, literal strings, and static locals). Solutions: Check the declarations for any array that might be too large. You can also remove variables from the DGROUP. Here's how: • Declare the variables as automatic. This uses stack space. • Dynamically allocate memory from the heap using calloc, malloc, or farmalloc for the variables. This requires the use of pointers. Literal strings are also put in the DGROUP. Get the file farstr.zip from our BBS to extract literal strings into their own segment. Trying to derive a far class from the huge base 'base' Compiler message If a class is declared (or defaults to) huge, all derived classes must also be huge. Trying to derive a far class from the near base 'base' Compiler message If a class is declared (or defaults to) near, all derived classes must also be near. Trying to derive a huge class from the far base 'base' Compiler message If a class is declared (or defaults to) far, all derived classes must also be far. Trying to derive a huge class from the near base 'base' Compiler message If a class is declared (or defaults to) near, all derived classes must also be near. Trying to derive a,near class from the far base 'base' Compiler message If a class is declared (or defaults to) far, all derived classes must also be far. 600 c++ User's Guide ... Trying to derive a near class from the huge base 'base' Compiler message If a class is declared (or defaults to) far, all derived classes must also be far. Two consecutive dots Compiler message Because an ellipsis contains three dots (... ), and a decimal point or member selection operator uses one dot (.), two consecutive dots cannot legally occur in a C program. Two operands must evaluate to the same type Compiler message The types of the expressions on both sides of the colon in the conditional expression operator (? : ) must be the same, except for the usual conversions. Following are some examples of usual conversions: char to int float to double void* to a particular pointer In this expression, the two sides evaluate to different types that are not automatically converted. This might be an error or you might merely need to cast one side to the type of the other.. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. The other message is usually "Cannot convert 'typer to 'type2'" but the mismatch might be due to many other reasons. 'type' is not a polymorphic class type Compiler message This error is generated if the -RT compiler option (for run-time type information) is disabled and either • dynamic_cast was used with a pointer to a class, or • you tried to delete a pointer to an object of a class that has a virtual destructor Type mismatch in default argument value Compiler message The default parameter value given could not be converted to the type of the parameter. The message "Type mismatch in default argument value" is used when the parameter was not given a name. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. The other message is most often "Cannot convert 'typer- to 'type2'" but the mismatch could be due to another reason. Type mismatch in default value for parameter 'parameter' Compiler message The default parameter value given could not be converted to the type of the parameter. The message "Type mismatch in default argument value" isused when the parameter was not given a name . . When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. That other message is usually "Cannot convert 'typel' to 'type2'" but the mismatch might be due to many other reasons. . Appendix A, Error messages and warnings 601 Type mismatch in parameter 'number' Compiler message . The function called, via a function pointer, was d~clared with a prototype. However, the given parameter number (counting left to right from 1) could not be converted to the declared parameter type. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch .. The other message is usually "Cannot convert 'type1' to 'type2'" but the mismatch might be due to many other reasons. Type mismatch in parameter 'number' in call to 'function' Compiler message Your source file declared the named function with a prototype, and the given parameter number (counting left to right from 1) could not be converted to the declared parameter type. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. . That other message is usually "Cannot convert 'type1' to 'type2"', but the mismatch might be due to many other reasons. Type mismatch in parameter 'number' in template class name 'template' Compiler message The actual template argument value supplied for the given parameter did not exactly match the formal template parameter type. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. That other message is usually "Cannot convert 'type1, to 'type2'" but the mismatch might be due to many other reasons. Type mismatch in parameter 'parameter' Compiler message Your source file declared the function called via a function pointer with a prototype. However, the named parameter could not be converted to the declared parameter type. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. That other message is usually "Cannot convert 'type1' to 'type2'" but the mismatch might be due to many other reasons. Type mismatch in parameter 'parameter' in call to 'function' Compiler message . Your source file declared the named function with a prototype~ and the named parameter could not be converted to the declared parameter type. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. That other message is usuallyilCannot convert 'type1' to 'type2'" but the mismatch might be due to many other reasons. Type mismatch in parameter 'parameter' in template class name 'template' Compiler message The actual template argument value supplied for the given parameter did not exactly match the formal template parameter type. When compiling C++ programs, this message is always preceded by another message that explains the exact reason for the type mismatch. 602 C++ Use r 's G u ide That other message is usually "Cannot convert 'typel' to 'type2"' but the mismatch might be due to many other reasons. Type mismatch in redeclaration of 'identifier' Compiler message Your source file redeclared a variable with a different type than was originally declared for the variable. This can occur if a function is called and subsequently declared to return something other than an integer. Solution: If this happens, you must declare the function before the first call to it. Type name expected Compiler message One of these errors has occurred: • In declaring a file-level variable or a struct field, neither a type name nor a storage class was given. • In declaring a typedef, no type for the name was supplied. • In declaring a destructor for a C++ class, the destructor name was not a type name (it must be the same name as its class). In supplying a C++ base class name, the name was not the name of a class. Type 'type' is not a defined class with virtual functions Compiler message A dynamic_cast was used with a pointer to a class type that is either undefined, or doesn't have· any virtual member functions. Type 'typename' may not be defined here Compiler message Class and enumeration types may not be defined in a function return type, a function argument type, a conversion operator type, or the type specified in a cast. You must define the given type before using it in one of these contexts. Note This error message is often the result of a missing semicolon (; ) for a class declaration. You might want to verify that all the class declarations preceding the line on which the error occurred end with a semicolon. Unable to create output file 'filename' Compiler message This error occurs if the work disk is full or write protected. It also occurs if the output directory does not exist. Solutions: • If the disk is full, try deleting unneeded files and restarting the compilation. • If the disk is write-protected, move the source files.to a writeable disk and restart the compilation. Unable to create turboc.$ln Compiler message The compiler cannot create the temporary file TURBOC.$LN because it cannot access the disk or the disk is full. Unable to execute command 'command' Compiler message TLINK or TASM cannot be found, or possibly the disk is bad. Appendix A, Error messages and warnings 603 Unable to execute command: 'command' MAKE message A command failed to execute. This might be because the command file could not be found or was misspelled, there was no disk space left in the specified swap directory, the swap directory does not exist, or (less likely) the command itself exists but has been corrupted. Unable to load 16 bit compiler Unable to load 16 bit linker Unable to load 32 bit compiler Unable to load 32 bit linker Compiler messages For the 16-bit linker and compiler, the file BCWS16.DLL must be either in the directory where BCW.EXE resides or somewhere in your path. If the DLL is in the correct location and still will not load, you may not have enough memory for the DLL to load. BCW operates optimally when you have at least 12 MB of memory in any combination of physical RAM and virtual memory. Fqr the 32-bit linker and compiler, the same rules apply for BCWS32.EXE. In addition; you must have a system running that supplies the Win32 API. Check to make sure that you have properly installed either NT or Win32s on your Windows system by running another 32-bit application such as the FreeCell game which accompanies the operating system. Unable to open 'filename' Compiler message This error occurs if the specified file can't be opened. Make sure the file is on the specified disk or directory. Check Options I Settings I Directories and verify the proper paths are listed. If multiple paths are required, use a semicolon to separate them, like this: . C:\bc\include;c:\bc\include\owl Unable to open 'filename' for output Librarian message The librarian cannot open the specified output file. This is usually due to lack of disk space for the target library, or a listing file. Unable to open file 'filename' Linker message The named file can't be found, possibly because it does not exist or is misspelled, or it resides in a different directory than those being searched. If you are using the IDE, make sure you have set the appropriate directory paths in the Options I Directories dialog box. Unable to open file 'filename' MAKE message This error occurs if the named file does not exist or is misspelled. Unable to open include file 'filename' The compiler could not find the named file. Possible Causes: • The named file does not exist. • An #include file included itself. • You do not have FILES set in CONFIG.SYS on your root directory. 604 c++ User's Guide Compiler message Solutions: • Verify that the named file exists. • Set FILES = 20 in CONFIC.5YS. Unable to open include file 'filename' MAKE message The compiler could not find the named file. This error can also be caused if an !include file included itself, or if you do not have FILES set in CONFIC.5YS on your root directory (try FILES=2 0). Check whether the named file exists. Unable to open input file 'filename' Compiler message This error occurs if the source file can't be found. Check the spelling of the name. Make sure the file is on the specified disk or directory. . Check under Options I Settings I Directories and verify that the proper directory paths are listed. If multiple paths are required, use a semicolon to separate them, like this: C:\hc\libiC:\bc\owl\lib Unable to open makefile MAKE message The current directory does not contain a file named MAKEFILE or MAKEFILE.MAK, or it does not contain the file you specified with-f. Unable to process debug info, disable TASM Izi option Linker message Debug information is too complex. Disable the TASM Izi option. If C debug information is required, it should be obtained at the C source level. Unable to redirect input or output MAKE message MAKE was unable to open the temporary files necessary to redirect input or output. If you are on a network, make sure you have access rights to the current directory. Unable to rename 'filename1' to 'filename2' Librarian message The librarian builds a library into a temporary file (filenamel) and then renames the temporary file to the target library file name (filename2). This message appears if an error occurs during the renaming process, such as insufficient disk space. #undef directive ignored Compiler message An .error has occurred while using the command-line utility H2ASH. See the online file "tsm_util.txt" for further information about this utility. Undefined alias symbol 'symbol' Linker message The.symbol being aliased was undefined. This occurred either because of an invalid function name or the function itself was not included in the link. Compiler message Undefined label 'identifier' The named label has a goto in the function, but no label definition. Compiler message Undefined structure 'structure' (Command-line equivalent for displaying this warning = -wstu) The named structure was used in the source file, probably on a pointer to a structure, but had no definition in the source file. This is probably caused by a misspelled structure name or a missing declaration. Default = displayed Appendix A, Error messages and warnings 605 Undefined structure 'structure' Compiler message Your source file used the named structure on some line before where the error is indicated (probably on a pointer to a structure) but had no definition for the structure. This is probably caused by a misspelled structure name or a missing declaration. Undefined symbol 'identifier' Compiler message The named identifier has no declaration. Possible Causes: • actual declaration of identifier has been commented out. • misspelling, either at this point or at the declaration. • there was an error in the declaration of the identifier. Tools to help track down the problem: • CPP • GREP Undefined symbol 'symbol' in module 'module' Linker message The named symbol is referenced in the given module but is not defined anywhere in the set of object files and libraries included in the link. Check to make sure the symbol is spelled correctly. You will usually see this error from the linker for C or C++ symbols if any of the following occur: • You did not properly match a symbol's declarations of pascal and cdecl type in different source files. • You have omitted the name of an .OBJ file your program needs. • You did not link in the emulation library. If you are linking C++ code with C modules, you might have forgotten to wrap C external declarations in extern "C". You could also have a case mismatch between two symbols. Unexpected} Compiler message An extra right brace was encountered where none was expected. Check for a missing {. Useful Tip: The IDE has a mechanism for finding a matching curly brace. If you put the cursor on the '{' or T character, hold down control, hit 'Q' and then '{' or T, it will position the cursor on the matching brace. Unexpected char X in command line Librarian message The librarian encountered a syntactical error while parsing the command line. Unexpected end of file MAKE message The end of the makefile was reached before closing a temporary inline file. Unexpected end of file in comment started on 'line number' Compiler message The source file ended in the middle of a comment. This is normally caused by a missing close of comment (* j). 606 c++ User's Guide Unexpected end of file in conditional started at line 'line number' MAKE message The source file ended before MAKE encountered an !endif. The !endif was either missing or misspelled. Unexpected end of file in conditional started on 'line number' Compiler message The source file ended before the compiler (or MAKE) encountered an #endif. The #endif either was missing or misspelled. Every #if statement needs a matching #endif statement. Unexpected termination during compilation [Module Seg#:offset] Unexpected termination during linking [Module Seg#:offset] Compiler messages If either of these errors occur, it indicates a catastrophic failure of the Borland tools. You should contact Borland to report the problem and to find a potential work around for your specific case. By isolating the test case as well as possible, you will increase the chance for either Borland or yourself to find a work around for the problem. Commonly, compiler failures can be worked around by moving the source code that is currently being compiled. Simple cases might be switching the order of variable declarations, or functions within the source module. Moving the scope and storage of variables also helps in many cases. For linker failures, you can reduce the amount of debugging information that the linker has to work with. Try compiling only one or two modules with debug information instead of an entire project. Similarly, switching the order in which object modules are handed to the linker can work around the problem. The IDE hands objects to the linker in the order that they are listed in the project tree. Try moving a source up or down in the list. union cannot be a base type Compiler message A union can't be used as a base type for another class type. union cannot have a base type Compiler message In general, a C++ class can be of union type, but such a class can't be derived from any other class. Union member 'member' is of type class with constructor (or destructor, or operator =) Compiler message A union can't contain members that are of type class with user-defined constructors, destructors, or operator =. unions cannot have virtual member functions Compiler message A union can't have virtual functions as its members. Compiler message Unknown assembler instruction (Command-line equivalent for displaying this warning = -wasm) The compiler encountered an inline assembly statement with a disallowed opcode. Check the spelling of the opcode. Default = not displayed Appendix A, Error messages and warnings 607 Unknown CMDSWITCHES operator 'operator' MAKE message The !CMDSWITCHES directive is supposed to tum on command-line options using a plus sign (+) followed by the option and tum them off using a minus sign (-) followed by the option. An operator other than + or - is specified in the !CMDSWITCHES directive. Unknown command line switch 'X' ignored Librarian message A forward slash character (I) was encountered on the command line or in a response file without being followed by one of the allowed options. Linker message Unknown Goodie An unsupported option was supplied to the command-line linker. Compiler message Unknown language, must be C or C++ In the C++ construction extern "name" type func( /* ... */ )i the given "name" must be "c" or "C++" (use the quotes); other language names are not recognized. You can declare an external Pascal function without the compiler's renaming like this: extern "e" int pascal func( /* ... */ )i To declare a (possibly overloaded) C++ function as Pascal and allow the usual compiler renaming (to allow overloading), you can do this: extern int pascal func( /* ... */ ) i Unknown Optimization Linker message This error message refers to an UNDOCUMENTED optimization feature. Unknown option 'option' Linker message A forward slash character (I), hyphen (-), or DOS switch character was encountered on the command line or in a response file without being followed by one of the allowable options. You might have used the wrong case to specify an option. Unknown preprocessor directive: 'identifier' Compiler message The compiler encountered a # character at the beginning of a line. The directive name that followed the # was not one of the following: • • • • • • • • • define else endif if ifdef ifndef include line undef Unknown preprocessor statement MAKE message A ! character was encountered at the beginning of a line, and the statement name following it was not error, undef, if; elif, include, else, or endif. 608 c++ User's Guide Compiler message Unreachable code (Command-line equivalent for displaying this warning = -wrch) A break, continue, goto, or return statement was not followed by a label or the end of a loop or function. The compiler checks while, do" and for loops with a constant test condition, and attempts to recognize loops that can't fall through. Default = not displayed Unresolved external 'symbol' referenced from module 'module' Linker message The named symbol is referenced in the given module but is not defined anywhere in the set of object files and libraries included in the link. Check to make sure the symbol is spelled correctly. You will usually see this errol' from the linker for C or C++ symbols if any of the following occur: • You did not properly match a symbol's declarations of pascal and cdecl type in different source files. • You omitted the name of an .OBJ file your program needs. • You did not link in the em~lation library. If you are linking C++ code with C modules, you might have forgotten to wrap C external declarations in extern "C" { ... } . You could also have a case mismatch between two symbols. Unsupported COMENT OMF extension 'extension' Linker message The linker encountered an object file with an incompatible .OBJ file format. This error generally occurs due to an incompatible .OBJ file format. If you're linking .OBJ files compiled using another compiler, these files may be incompatible with TLINK32. You'll need to recompile all modules using one of the Borland C++ compilers. This can also occur if the machine was rebooted during a compile, or if a compiler did not delete its output object file when Ctrl+Break was pressed. Recompile. If the error persists, call Borland Technical Support. Unsupported EXE RC version. Resource Linker message The executable you are attempting to link the resources to already has resources attached. The version number of these resources is not recognized by this resource linker. Try removing the resources or relinking. Unsupported option 'string' Linker message You specified an unknown option on the command line. Unterminated string or character constant Compiler message The compiler found no terminating quote after the beginning of a string or character constant. Appendix A, Error messages and warnings 609 Use '> >' for nested templates Instead of '»' Compiler message Whitespace is required to separate the closing ">" in a nested template name, but since it is an extremely common mistake to leave out the space, the compiler accepts a"»" . with this warning. Use. or -> to call 'member', or & to take its address Compiler message A reference to a non-static class member without an object was encountered; Such a member can't be used without an object, or its address must be taken with the & operator. Use. or -> to call function Compiler messageYou attempted to call a member function without providing anobject. This is required to call a member function. class X { member func() {} }; X x; X*xp = new X; X.memberfunc(); Xp-> memberfunc(); Use Ie with TLiNK to obtain debug information from library Librarian message The library was built with an extended dictionary and also includes debugging information. TLINK cannot extract debugging information if it links using an extended dictionary. To obtain debugging information in an executable from this library, use the Ie switch to cause the linker to ignore the extended dictionary. Note: The IDE linker does not support extended dictionaries; therefore, no settings need to be altered in the IDE. Use :: to take the address of a member function If f is a member function of class c, you take its address with the syntax Compiler message &c: :f Note the use of the class type name (not the name of an object) and the:: separating the class name from the function name. (Member function pointers are not true pointer types, arid do not refer to any particular instance of a class.) Use of: and :: dependents for target 'target' MAKE message You tried to use the target in both single and multiple description blocks (using both the : and :: operators). . Examples: filea: fileb filea:: filec Use qualified name to access member type 'identifier' (Command-line equivalent for displaying this warning = -wnst) 610 C++ Use r' s G u ide Compiler message In previous versions of the C++ specification, typedef and tag names declared inside classes were directly visible in the global scope. In the latest specification of C++, these names must be prefixed with class:: qualifier if they are to be used outside of their class scope. The compiler issues this warning whenever a name is uniquely defined in a single class. The compiler permits this usage without c 1 as s : : . This allows older versions of code to compile. Default = displayed User break Compiler message You typed a Ctrl+Break while compiling in the IDE. (This is not an error, just a confirmation. ) User break, library aborted Librarian message , You pressed Cancel while compiling in the IDE. The library was not created. (This is not an error, just a confirmation.) User-defined message Compiler l71essage The error nlessage,on which you have requested Help, is a user-defined warning. In Borland C++ code, user-defined messages are introduced by using the #pragma message compiler syntax. Note: In addition to messages that you introduce with the #pragma message compiler syntax, user-defined warnings can be introduced by third party libraries. Should you require Help about a third party warning, please contact the vendor of the header file that issued the warning. Using based linking for DLLs may cause the DLL to malfunction Linker message This warning occurs if you use the IB switch when linking a DLL. In almost every case, this is an error that will prevent the application from running. You can suppress this warning from the Linker I Warnings page of the Project options dialog box or with the I w-bdl command-line option. Value of type void is not allowed Compiler message A value of type void is really not a value at all, so it can't appear in any context where an actual value is required. Such contexts include the following: • the right side of an assignment • an argument of a function • the controlling expression of an if, for, or while statement. Variable 'identifier' is once Compiler message This variable has more than one initialization. It is legal to declare a file level variable more than once, but it can have only one initialization (even if twoare the same). 'variable' requires run-ti l11e initialization/finalization Compiler message This message is issued when a global variable that is declared as _thread (a Win32-only feature) or astatic data member of a template class is initialized with a non-constant initial value. ' A Ppen di x A, Err 0 r me s sag e san d war n i n 9 s 611 This message is also issued when a global variable that is declared as _thread (a Win32only feature) or a static data member of a template class has the type class with constructor or destructor. I Variable 'variable' has been optimized and is not available Compiler message You have tried to inspect, watch, or otherwise access a variable which the optimizer removed. This variable is never assigned a value and has no stack location. VIRDEF name conflict for: 'function' Compiler message The compiler must truncate mangled names to a certain length because of a name length limit that is imposed by the linker. This truncation may (in very rare cases) cause two names to mangle to the same linker name. If these names happen to both be VIRDEF names, the compiler issues this error message. The simplest workaround for this problem is to change the name of 'function' so that the conflict is avoided. Virtual base classes not supported Compiler message An error has occurred while using the command-line utility H2ASH. See the online file "tsm_util.txt" for further informc;ltion about this utility. 'virtual' can only be used with member functions Compiler message A data member has been declared with the virtual specifier. Only member functions can be declared virtual. For example: class myclass { public: virtual int a; //error }; Virtual function 'function1' conflicts with base class 'base' Compiler message A virtual function has the same argument types as one in a base class, but a different return type. This is illegal. virtual specified more than once Compiler message The C++ reserved word "virtual" can appear only once in one member function declaration. void & is not a valid type Compiler message A reference always refers to an object, but an object cannot have the type void. Thus, the type void is not allowed. Void 'function' cannot return a value Compiler message A function with a return type void contains a return statement .that returns a value; for example, an int. Default = displayed 612 C++ Use r 's G u ide Void functions may not return a value Compiler message Your source file declared the current function as returning void, but the compiler encountered a return statement with a value. The value of the return statement will be ignored. Warning. Duplicate resources. Resource Linker message If multiple resource files are linked in to the image, the user could have duplicate resources in the resource files. For example, you might have the same ICON in two different RES files. The resource linker flags this and the second resource is removed. Note:The resources must have the same type and identifier to be declared duplicates. Windows version is set to Win32, but target type is Win16. Resource Linker message The version for your resources is set to Win32, but the target type for your project is for a 16-bit Windows application. 16-bit Windows applications cannot use 32-bit resources. Either change the version for your resources to Windows 3.1 or change the target type for your application to Win32. Write error on file 'filename' MAKE message MAKE couldn't open or write to the file specified in the makefile. Check to ensure that there's enough space left on your disk, and that you have write access to the disk. Write failed, disk full? Linker message Writing to the specified disk failed. Check to see if the disk is fulL Wrong number of arguments in call of macro 'macro' Compiler message Your source file called the named macro with an incorrect number of arguments. Appendix A, Error messages and warnings 613 614 c++ User's Guide Index Symbols Numerics ! operator (MAKE) 333 != operator (MAKE) 334 $& macro 330 $* macro 323, 330 $** macro 330 $: macro 330 $< macro 330 $? macro 330 $@macro 330 % operator (MAKE) 333 & operator (MAKE) 327, 333 && operator (MAKE) 328, 333 * (search wildcard) 391 * operator (MAKE) 333 + (plus sign) . Environment Options dialog box 13 Project Manager 22 operator (MAKE) 333 .APX Database file 152 .TFA files 389, 434 / (slash) command-line options 199 MAKE options 321 operator (MAKE) 333 : (colon), makefiles 324 :: operator (MAKE) 325 < operator (MAKE) 328, 334 «operator (MAKE) 328,333 <= operator (MAKE) 334 == operator (MAKE) 334 > operator (MAKE) 328, 334 >= operator (MAKE) 333 »operator (MAKE) 328,333· ? (search wildcard) 391 -? MAKE option 320,322,461 ?: operator (MAKE) 333 @ prefix (MAKE) 327 \ (backslash), makefiles 325 1\ operator (MAKE) 333 I operator (MAKE) 333 I I operator (MAKE) 334 ~ operator (MAKE) 333 - (hyphen) command-line options 199 Environment Options dialog box 13 makefiles 321, 327 Project Manager 22 operator (MAKE) 333 16-bit command-line switches 113,115 compiler options 45,102 linker options 84 optimizations 86 resource options 110 resources, 110, 266 32-bit command-line switches 113,117 compiler options 57, 102 linker options 87 processing option 84 resources 112,266 80186 option, 16-bit compilers 52 80286 option, 16-bit compilers 53 80386 option, 16-bit compilers 53 8086 option, 16-bit compilers 53 8514 graphics adapter 473 A -a MAKE option 321 video adapters See Enhanced Graphics Adapter; Video Graphics Array Adapter About Turbo Profiler command 386 accelerators 303-304 Accumulation option 438 Acer 1100 and NMI 471 active analysis See also passive analysis See also profiling, analysis modes area markers 442 disk I/O and 443 passive analysis, compared 442 setting 441 active windows See windows, active adapters, video, See video adapters Add Areas command 406 Add command 403 Add Node option 27 Address option 396 addresses exceptions 355 jumping to Disassembly (CPU) window 410 Module window 391 Advanced Options dialog box adding tools 34 specifying source nodes 27 Airbrush tool Graphics editor 261 Graphics tool 256 algorithms analyzing 439 multipass 450 All Callers option 394, 407 All command 397 All Routines 392-394 All Windows command (Messages menu) 347 alternative translators 34 Always Build option 60 Always option, 16-bit compilers 49 Animation tool, Dialog editor 290 ANSI Violations options 97 AppExpert 151 applications 21 creating 33 testing 33,162 Arc tool, Graphics editor 260 area files, automatic saving 389 area markers See also areas active analysis and 442 defined 436 function entry 392 lines 392 modules 392 normal 456 operation 393 program execution speed 443 routine-entry 456 routines add all 392 add current 392 available for profiling 389 single lines, removing 398 symbols 392 Area Options dialog box 407 areas 436, 451 See also area markers adding 406 current changing 454 disassembled source code as 389 settings for 392 specifying profiling action 392 statistics 447 default 435 defined 436 execution counts and times 455 function-entry markers 392 inspecting 407 maximum 419 measuring efficiency 376 names 406 normal markers 456 I nd ex 615 profiler behavior when entering 455 program size and 436 removing 407 settings 434-437 statistics, default 436 Areas command (Routines window) 409 Areas radio buttons 394 Areas window 399-408 Callers option and 399 local menu 406 arguments 195,505 arrays accessing for optimimum speed 448-450 debugging .183, 187 inspecting 188 sorting 448 viewing 188 ASCII characters, printing high 374,471 codes, watches 186 assembly language assessing value of 409 integrated debugger 159, 166 Assume SS equals DS option, 16-bit compilers 49 asterisk (*) search wildcard 391 attributes project nodes 28-33 syntax highlighting 14 autodependency information 22,96 directives 332 MAKE 322,332 nodes 22 Project Manager 22 Automatic Far Data option, 16-bit compilers 49 automatic file linkage 22 B -B MAKE option 321, 460 background colors Graphics editor 244 syntax highlighting 14 backslash (\), makefiles 325 batch files 322 batch mode profiling 460 BCCONFIG.BCW 16 BCWDEF.DSW 16 beep on error, setting 470 Beep on Error check box (TFINST) 470 Bentley, John 367,380 binary files, Resource Workshop 264 binary resource (.RES) files 221 bitmaps 616 C++ Use r' 5 G u ide attributes, changing 231 creating 229 editing 230 programming, OWL 231 resources deleting 231 saving as files 268 standalone bitmap files, creating 230 testing 231 Windows API, programming 232 boards, debugger 471 Borland compilers, Turbo Profiler 435 Both option Disassembly (CPU) window local menu 411 Display Options dialog box 396 Both Time and Calls command 404 Bottoms tool, Dialog editor 297 BRC32 resource shell 337, 340-342 BRCC32 resource compiler 337 Break Make On options 96 breakpoints 167-175 conditional breakpoints, creating 169 debugging with 167 integrated debugger features 175 setting 166, 168 Breakpoints window 174 Browser 153 customizing 157 filters 156 letter symbols 156 objects, browsing 154 starting 154 brush shapes, Graphics editor, selecting 247 bubble sort, quicksort 448 buffers"data 449 Build Attributes options, project options 60 Build When Out of Date option, Build Attributes 60 BUILDSYM.EXE utility 361 BUILTINS.MAK 320-322 buttons, IDE SpeedBars 7,14-15 BWCC Check Box tool, Dialog editor 294 BWCC Group Box tool, Dialog editor 294 BWCC Horizontal Line tool, Dialog editor 294 BWCC page, Control palette, Dialog editor 293 BWCC Push Button tool, Dialog editor 293 BWCC Radio Button tool, Dialog editor 295 BWCC Static Text tool, Dialog editor 295 BWCC Vertical Line tool, Dialog editor 295 Byte Alignment option, 16-bit compilers 53 c C option, 16-bit compilers 46 -c option (load configuration file) 322,461 problems 500 TPROFW 491 C++ See also object-oriented programs compatibility options 61 expressions, problems 500 project options 60 cables, null modem, remote profiling 478 call history, dynamic 439-440 call paths 398 example 400 recording 394 sorting 401 Call Stack command 195,437 Call Stack window 195 call stacks active routines 456 setting 437 size of 394 Called option 399,401 Callers command 393,417 Areas window 399 call paths, logging 457 call stacks 437 Routines window local menu 409 Callers radio buttons 407 Callers window 400-401, 446 local menu 401 restructuring programs and 400 Calling Convention options, project options 45 calls overhead 453 passive analysis 443 Calls command 404 Can't Build option 60 captions, dialog boxes, adding 273 case and switch statements, verifying 440 case-sensitivity 462 enabling 471 Library option 83 MAKE 321, 329-330 changes, source code, undoing 8 characters line continuation, makefiles 325 printing graphic 374 high versus standard ASCII 471 strings, searchIDg for 412, 498 Check Box tool, Dialog editor 287 children windows, displaying 346 CKB files 13 Class List view, WinSight 343-345 classes custom classes, dialog boxes 274 deleting, Rescan 150 importing, AppExpert 151 messages, tracing 345 moving, Rescan 151 ClassExpert 143-145 clocks 393, 438 Clock Speed option 419 close boxes· 383 code 7 defining color and font attributes 14 editing 7,195 IDE options 25 symbols, browsing 155 undoing changes 8 Code class option, 16-bit compilers 54 Code group option, 16-bit compilers 54 Code option, 16-bit compilers 54 Code segment option, 16-bit compilers 54 CODE statement 206 collapsing lists dialog boxes 13 Project Manager 22 Collection command 403,405,447 colon (:), makefiles 324 color monitors, customizing 467 Color palette, Graphics editor 244246 color tables 466 colors customizing, Graphics editor 246 filling areas, Graphics editor 249 syntax highlighting and 14 Colors menu (TFINST) 466 Combo Box tool, Dialog editor 288 command line arguments 505 options batch mode (b) 460 configuration file (-c) 461 display update (-d) 461 help (-h and -?) 461 mouse support (p) 462 overriding 474 remote profiling (r) 462,481 saving 465 SOlJIce code and symbols (s) 462 syntax 459 TFINST475 TFREMOTE 479 toggling 459 TPROFW 491 video hardware (v) 463 WREMOTE 484 command-line compilers 197,319 default settings 198 defaults 199 directories 200 linkers 204 syntax 198 TLINK syntax 201 command-line options 113,198 disabling 199 functions 118 integrated debugger and 162 linkers 201 MAKE 319,321-323 overriding 331 setting as defaults 322 suppressing display 322 overriding 199 command-line resource tools 337 commands See also specific command names choosing 382 Compiler menu, Debugging 368 Cursor menu, Set Hot Spot 234 Edit menu Redo 222 Undo 222 File menu Open 222, 230 Quit 368 Linker menu, General 368 MAKE 326-328 Message menu All Windows 347 Options 347 Messages menu Selected Classes 345 Selected Windows 347 Trace Off 343 Options menu Environment 157 Project 368 prompts 497 Resource menu, New 230 Spy menu Exit 344 Find Window 346 Open Detail 344 comments logging 354 placing scripts 310 communications, remote systems 472, 486 Compact option, 16-bit compilers 51 compilation 21 debugger and 161-162 fatal errors 507 large modules 322 nodes in Source Pools 33 profiling 435 project options 37, 43 specific files only 319 warnings 508 Compile command (Project) 12 Compiler menu commands, Debugging command 368 Compiler Output page 73 compilers command-line compilers 197 configuration files 199 errors 508 error messages 508 Help systems 25,510 project options, 69 warnings, ignoring 11 compile-time errors, fixing 44 COMSPEC environment variable (DOS) 500 conditional breakpoints 168-169 conditional directives 333-336 conditional expressions 333 conditional statements 440 configuration files compilers 199 creating 376 default name, changing 473 directory paths, setting 469 loading 461 problems with 500 saving 473,501 TFCONFIG 491 TLINK 203 TPROFW 490-491 configuring Turbo Profiler 465 WinSight 343 continuation characters, . makefiles 325 C~mtrol Key check box (TFINST) 470 Control palette, Dialog editor 285286 control points, problems 506 control-key shortcuts, enabling 470 controls, dialog boxes 276 adding 276 aligning multiple 279 custom controls 277 duplicating 278 editing properties 282 grouping 281 moving 278 reordering 281 resizing 278 resizing multiple 280 selecting multiple 279 tab stops 282 conversions, project files to makefiles 31 I nd ex 617 copying icon images 239 project nodes 30-31 copyright information 386 Count option 402 Counts option 396 Coverage Display dialog box 414 Coverage mode blocks selected· 413 coverage count, setting 419 Coverage window 414-416,446 CPP files 8 CPU, WREMOTE 486 CPU window See Disassembly (CPU) window Create Extended Dictionary option 83 creating program files 8-10 projects 24-27 Source Pools 33 Current command 397 current instruction pointer, returning to 410 Current Routine command (Add Areas menu) 392 cursors 232 attributes, changing 236 creating 233 deleting 234 designing 234 editing 233 hot spots, setting 234 moving 391 position, Edit window 7 programming 236-237 resources, adding images 235 testing 235 custom classes, dialog boxes, assigning 274 Custom page, Control palette, Dialog editor 295 customizing Turbo Profiler 474 CWH.HLP file 25 o -D MAKE option 322 $d MAKE macro 323,336 -d MAKE option 322 -d option Turbo Profiler 461 WREMOTE 484 data caching 449 evaluation order 449 IDE options 25 inspecting 188 sets, size and profiling 434 structures, optimizing 448 values, changing 187-188 618 C++ Use r 's G u ide Data Access page, Control palette, Dialog editor 295 Data Alignment options, 16-bit compilers 53 Data Aware page, Control palette, Dialog editor 295 data objects 160 DATA statement 207 date stamps (MAKE) 320-322 Debug command (IDE) 6 Debug menu 159 debugger 159. accessing 159 compiler options 162 evaluating expressions 186-188 execution point 163, 196 flickering screens, eliminating 162 inspecting data elements 188 multiple statements 162 program execution, controlling 167 restarting programs 167 running programs 161-162, 166 setting breakpoints 166 starting 160 stepping over code 166 stopping programs 166 symbolic debug information 161 tracing into code 165,195 watching expressions 182-186 debugger boards, nonmaskable interrupts 471 debugging 32-bit executables 159 arrays 183,187 assembly code 159, 166 breakpoints 167 bugs, types 159-160 DFA utility 359 expressions 181-188 external programs 166 hxnctions 164-166,195 global symbols 408 information, adding to modules 387 makefiles 322, 328, 334 member hxnctions 166 postmortem debugging 353 profiling 435 sessions, beginning 161 statements 162 strategy 160-162 structures 187 UAEs (Umecoverable Application Errors) 353 variables 185 WinSpector 353 Debugging command (Compiler menu) 368 Debugging options, compilers 76 debugging tools 343, 353 decimal values, watches and 183, 186 Default Color Set command (TFINST) 467 default compiler options 199 default file names 8,24,202 Default for memory model option, 16-bit compilers 49 default project options 38 default settings 465 IDE SpeedBars 15 new projects 24 restoring 473 default translators 34 default viewers 34 Delete All command 403 Delete Node option 28-29 deleting bitmap resources 231 classes, Rescan 150 cursors 234 identifiers 307 menus, items 302 project nodes 28-29 resources 266 delimiters, makefiles 328 DESCRIPTION statement 207 desktop, windows, viewing 345-347 Detail command 405, 447 device drivers, WREMOTE.EXE 482 DFA utility 359-360 dialog boxes 271,385 See also specific dialog box Accept Color Set (TFINST) 467 captions, adding 273 collapsing lists 13 controls 276 adding 276 aligning multiple 279 custom controls 277 duplicating 278 editing properties 282 grouping 281 moving 278 reordering 281 resizing 278 resizing multiple 280 selecting multiple 279 tab stQps 282 creating 272 custom classes, assigning 274 customizing 466 Directories (TFINST) 469 Display Options (TFINST) 467 DLINIT resources 271 editing 272 escaping out of 497 expanding lists 13 fonts, specifying 274 frame styles, choosing 273 hot keys 383 menus, including 273 Message Trace Options 347 Miscellaneous Options (TFINST) 470 New Project 230 positions, setting 275 programming 275-276 prompts 499 searches 412 testing 275 windows, choosing 273 Dialog editor 283 Animation tool 290 Bottoms tool 297 BWCC Check Box tool 294 BWCC Group Box tool 294 BWCC Horizontal Line tool 294 BWCC Push Button tool 293 BWCC Radio Button tool 295 BWCC Static Text tool 295 BWCC Vertical Line tool 295 Check Box tool 287 Combo Box editor 288 Control palette 285 Group Box tool 289 Header tool 292 Horizontal Centers tool 296-297 Horizontal Scroll Bar tool 288 Horizontal Static Line tool 289 Hot Key tool 291 Left Sides tool 296 List Box tool 288 List View tool 291 Progress Bar tool 291 Property Inspector 283 Push Button tool 286 Radio Button tool 287 Rich Text Edittool 292 Right Sides tool 296 Selector tool 286 Space Horizontally Equal tool 297 Space Vertically Equal tool 297 Static Frame tool 289 Static Picture tool 290 Static Rectangle tool 289 Static Text tool 287 Status Window tool 292 Tab Control tool 290 Text Edittool 288 Tool Bar tool 292 Tops tool 297 Track Bar tool 292 Tree View tool 291 Up-Down tool 291 Vertical Center in Dialog tool 297 Vertical Centers tool 297 Vertical Scroll Bar tool 289 Vertical Static Line tool 289 Dialogs command (TFINST) 466 directives conditional 333-336 MAKE 323-336 directories changing 387 command-line compilers 200 default 469 how searched 435 paths problems with 504 setting 499 starting TPROFW directory 491-492 WREMOTE and 484 - source files 390, 394, 462 Directories dialog box (TFINST) 469 Directories options, project options 80 directory paths, MAKE 320,322,334 disabling command-line options 199 statistics collections 393 syntax highlighting 14 Disassembly (CPU) 356,410-411 disk drives, changing 387 disks, writing to, problems 500-501 dispatched messages 347 Display command 447 Execution Profile window local menu 396 Interrupt~ window local menu 404 Overlays window local menu 402 Display menu (TFINST) 467 display options 469 Display Options dialog box 426, 467 Display radio buttons 396, 405 Display Swapping radio buttons, TFINST 467 Display Warnings options 98 displaying Color palette Dialog editor 285 Graphics editor 246 messages, WinSight 343 project nodes 22 Property Inspector 284 Tool palette, Graphics editor 254 displays See also screens buffers, saving 468 colors 466,473 dual 389 modes' 466 defaults, setting 472 problems 506 options 467, 473 pages 469 problems 473 swapping 469 updating 468 DLGINIT resource, dialog boxes 271 DLLs (Dynamic Link Libraries) 264, 494-495,500 -do option, TPROFW 491 documentation, printing conventions 1 DOS applications, creating 9 command processor, . problems 500 COMSPEC environment variable 500 SHARE program 323 shelling to display swapping 469 wildcards choosing files 412 makefiles 319,321 DOS Shell command 388, 500 DOS Shell Swap Size input box (TFINST) 472 DOS_TEST.CPP 9 Double word (4-byte) option, 16-bit compilers 53 downward compatibility 338, 342 drawing, Graphics editor 248 drives, changing 387 -ds option (swap screens), TPROFW 491 DSW files 16 dual monitors 389 duplicate names, macros 329 duplicating controls, dialog boxes 278 Duration option 405 E -e MAKE option 322 Edit command 6, 500 Edit menu commands Redo 222 Undo 222 edit modes (IDE) 7 Edit Node Attributes option 28,34 Edit Source command 195 Edit window, Menu editor 300 Edit window (IDE) customizing 13 debugging programs 163-167 examining code 196 inspecting data elements 188 loading source files 23 opening 8 overview 7 SpeedMenu, activating 7 editing bitmaps 230 - code, Call Stack window 195 control properties, dialog boxes 282 cursors 233 dialog boxes 272, 282 icons 238 identifiers 306 menus 300-302 In d e x 619 node attributes 28-30 resources as text 268 . user-defined resources 315 editors 8, 197 installing 395 reconfiguring IDE 13 efficiency, measuring 376 !elif directive 333 Ellipse tool, Graphics editor 258 ellipsis mark (... ) 385 embedding resources project files 315 resource projects 225 empty frame tools, Graphics editor 258 enabling statistics collection 393 Enhanced Graphics Adapter (EGA) 468 Enter Program Name to Load dialog box 386 environment, saving IDE settings 16 Environment command (Options menu) 12, 157 Environment Options dialog box 12-13 expanding/ contracting lists 13 Project View options 31 environment variables, MAKE macros 322, 329 Eraser tool, Graphics editor 255 erasing areas, Graphics editor 250 error handling, MAKE 327, 332-333 error messages 507,512-607 beeps, enabling 470 compilers 508 fatal 507-510 Help compiler 510 logical 160 MAKE 332 makefiles 508 memory 477 run-time 159-160, 508 TFREMOTE 487 TLINK508 TPROFW 495 Turbo Profiler 506 Euclid's method, prime numbers, testing 368 Evaluate/Modify command 186 Events command 404 Ev~nts pane, ClassExpert 145 Every Line in Module command (Add Areas menu) 392 Exception handling/RTTI options 64 exceptions addresses 355 logging 355-359 620 C++ Use r 's G u ide reports, WinSpector 355 Exclude from Parent option, Build Attributes 60 excutable files, system files cre\;lting 161, 264,361 execution counts and times areas 455 default behavior 436 passive analysis and 443 program structure analysis 440 program testing and verification 439 resource monitoring and 440 Execution Profile window 398,446 description 370 local menu 395 Module window 395,398 execution timing, statistics for 440 EXEMAP.EXE 360-361 EXETYPE statement 207 Exit command (Spy menu) 344 exit status, MAKE, ignoring 322 exiting TFINST 474 Turbo Profiler 368,389 WinSight 344 expanding lists dialog boxes 13 Project Manager 22 EXPORTS statement 208 Expression Evaluator dialog box 185-186 expressions changing 185 conditional 333 current value, viewing 182 debugging 181-188 entering problems with 505 evaluating 186-188 inspecting 188 optimizing 450 external programs, debugging 166 Eye Dropper tool, Graphics editor 259 F -f MAKE option 322 Far 50 Far data class option 56 Far data group option 56 Far Data option 56 Far data segment option 56 Far Data Threshold option, 16-bit compilers 50 Far Virtual Tables, option, 16-bit compilers 50 Far virtual tables option 57 Fast huge pointers option, 16-bit compilers 50 Fast Screen Update check box (TFINST) 468 fatal errors 507-510 features 364 File command 6, 394-395 File Manager (Windows), adding source nodes 28 File menu commands, Open 222, 230 file names 8,24 file search algorithms 81 files access monitoring 437 profiling purposes 440 text files 389 tracking 389 activities, displaying 447 adding to projects 27 batch 322 disks, problems with 500-501 information 388 keyboard mapping 13 loading 377 log 354-359 needed for profiling 390 opening 386,412,504-506 Project Description Language (.PDL) files 40 searching 412 sources current routine 409 directories 394 inspecting 401 list of 394 loading 499, 502 options 462 searching for 435 setting directory path 469 statistics 375 viewing 396 swap 501 symbol tables 161 TDDEBUG.386 490 temporary, MAKE 322-323,328 text 389, 412 TFWHELP.TFH 490 TPROF.EXE 473 TPROFW program 490 tutorial, copying 217,317 viewing in IDE 22 WREMOTE.EXE 482 Files option 437 Files window 405,446 Filled Rectangle tool, Graphics editor 259 Filled Rounded Ellipse tool, Graphics editor 259 Filled Rounded Rectangle tool, Graphics editor 259 filled-in frame tools, Graphics editor 258 Filter command 397, 441, 447 filters 34, 156 Find Execution Point command 163 Find Window command (Spy menu) 346 finding windows, WinSight 346 flickering screens, eliminating 162 floating-point values, watches, 183, 186 Follow command 411 fonts dialog boxes, specifying 274 syntax highlighting 14 foreground color, Graphics editor 244 foreground colors, syntax highlighting 14 format specifiers 183, 186 formats messages 510 rich-text 510 formatting watches 183, 186 frame styles, dialog boxes, choosing 273 frequency collisions, solving 458 Frequency option 396, 401 Full Graphics Saving check box (TFINST) 468 function calls, viewing 195 functions command-line options 118 debugging 162-166, 195 inspecting 188 listing, WinSpector 356 EGA 468 Hercules 473 monochrome text-only 473 VGA 468 Graphics editor 243 areas aligning 251 copying 251 erasing 250 filling with color 249 moving 251 removing 252 resizing 251 selecting 250 background color 244 brush shapes, selecting 247 Color palette 244-246 colors, customizing 246 drawing 248-249 empty frame tools 258 filled-in frame tools 258 foreground color 244 graphics 252-253 inverted color area 245 lines, drawing 248 paint patterns, selecting 248 painting 248 pen styles, selecting 247 text, adding to graphics 249 Tool palette 253-254 transparent color area 245 graphs, file activity 405 Group Box tool, Dialog editor 289 grouping, controls, dialog boxes 281 G -h MAKE option 320-322 -h option TFREMOTE 479 Turbo Profiler 461 Hand tool, Graphics editor 260 hardware adapter display options, setting 468 profiling, required 490 requirements, TPROFW 489 header files, referencing 32 Header tool, Dialog editor 292 heaps, listing information, WinSpector 358 HEAPSIZE statement 209 help 461 accessing, problems 501-502 command-line options TFINST 475 Turbo Profiler 461 status line 385 Help command (IDE) 6 Help compiler 25, 510 Help systems 510 Help window 430 GDI (Graphics Device Interface) 313 General command (Linker menu) 368 General options 65 Generate List File option 83 Generate Makefile command (Project) 31 generating symbolic debug information 161 Get Info command 388 global symbols, listing 408 Goto command Disassembly (CPU) window local menu 410 Module window local menu 391 Graph option 405 graphics color tables 466 display buffer, saving 468 snow, problems 468 graphics adapters 472 display options 473 display pages 469 H Hercules graphics adapter 473 Hex Values option (WinSight) 347 hexadecimal values, watches 183, 186 hiding Color palette, Graphics editor 246 Control palette, Dialog editor 285 IDE SpeedBars 15 , Tool palette, Graphics editor 254 History List Length input box (TFINST) 470 History option 402 Horizontal Center in Dialog tool, Dialog editor 297 Horizontal Centers tool, Dialog editor 296 Horizontal Scroll Bar tool, Dialog editor 288 Horizontal Static Line tool, Dialog editor 289 Hot Key tool, Dialog editor 291 hot keys 383,470 hot spots, cursors, setting 234 Huge option, 16-bit compilers 51 hyphen(-) command-line options 199 makefiles 321,327 -I MAKE option 322 -i MAKE option 322, 333 I/O disk, active and passive analysis 443 keyboard,profiling 435 makefiles 328 options 469 i486 option, 16-bit compilers 53 IBM graphic characters, printing 374 IBM PC compatible, NMI 471 icons 237 attributes, changing 239 creating 237-238 editing 238 images, copying to new color format 239 program 5 programming 241 resources 239-240 testing 241 used in documentation 1 IDE 16 adding tools 34-35 customizing 12-16 debugging 32-bit executables 159 integrated debugger, starting 160 MAKE 319 menu 6 preferences 16 In de x 621 restoring defaults 15 fU1111illg programs 16, 161-162 saving settings 16 SpeedBars 7, 14-15 SpeedMenus 7 starting 5 viewing program status 7 windows 14 IDE debugger messages 510 identical SpeedBars 15 identifiers 305 creating 306 deleting 307 editing 306 listing 308 managing, Reesource Workshop 308 moving 307 resources, adding 306 Ignore Case of Symbol check box (TFINST) 471 ignoring warnings 11 Immediate Caller option Area Options dialog box 407 Stack Trace dialog box 394 IMPORTS statement 209 include files, MAKE 322 Inefficient C++ Coding options 99 Initialize Segments option 85 Initialized data class option 55 Initialized data group option 55 Initialized Data option 55 Initialized data segment option 55 input boxes (TFINST) DOS Shell Swap Size 472 Tab Size 468 Insert mode (IDE) 7 Inspect command 401-402, 407 Inspect Expression window 188 Inspect Object command 188 inspecting data 188 Inspection window, Browser 156 Inspector windows 188 installation TDDEBUG.386 490 TFREMOTE (remote profiling utility) 478 TPROFW 490 WREMOTE 482 instructions current pointer 410 displaying 411 pointer, address of 411 INT 3 instruction, problems 506 integers, watches 183, 186 integrated environment 431 Interpret Values option (WinSight) 347 622 C++ Use r 's G u ide interrupt key, setting 470 interrupts adding to statistics collection 403 amount of time in 403 display formatting options 404 execution timing and resource monitoring 440 MAKE 320 monitoring 437 names 403 NMI471 number of calls to 403 passive analysis 443 pick list 403 program, WREMOTE 484 removing from statistics collection 403 from window 447 statistics 403 subfunctions 403 Interrupts command 437 Interrupts window 403-404, 446 inverted color areas, Graphics editor 245 K·L -K MAKE option 322 keyboard choosing menu commands 382 input, profiling 435 keyboard mapping files 13 keyboard shortcuts, IDE windows 13 keys, cursor-movement (TFINST) 465 keystrokes, recording problems 505 labels, moving cursor to 391 Large option, 16-bit compilers 51 LCD screens 473 leaving Turbo Profiler 389 Left Sides tool, Dialog editor 296 letter symbols, Browser 156 librarian errors 510 Librarian options 83,111 libraries linking 200, 204 MAKE and 335 specifying 25 Library Page Size option 83 LIBRARY statement 210 Line command 391 line continuation characters, make files 325 line counts algorithm analysis 439-440 program verification and testing 440 line numbers, returning in Edit window 7 Line tool, Graphics editor 257 lines drawing, Graphics editor 248 jumping to 391 moving cursor to 391 numbers 498 Lines in Routine command (Add Areas menu) 392 links, remote, speed of 462 Link Speed radio buttons (TFINST) 472 linkage automatic 22 run-time libraries 204 Windows applications 199 linker errors 508-509 Linker menu commands, General 368 Linker options, project options 84 linkers, command-line compilers 204 linking resources 220, 225 List Box tool, Dialog editor 288 List View tool, Dialog editor 291 listing functions, WinSpector 356 identifiers 308 running modules 358 running programs 357 LoadLibrary, DLLs 495 local menus 389 Areas window 406 Callers window 401 Disassembly (CPU) window 410 Execution Profile window 395 Files window 405 Interrupt window 403 Module window 391 Overlays window 402 Routines window 408 Local Module command 409 local overrides, project options 41 local system, remote profiling 478 log files adding comments 354 tracking exceptions 355-359 logic errors 160 logical addresses 355 Longest option 396 loops, optimizing 448-449 M -m MAKE option 322 machine-dependent constructs 508 macro modifiers (MAKE) 331 macro substitution (MAKE) 330 macros expansion 329 recording,problems 503-505 MAKE 319 building files 319-323 commands 326-328 compatibility with NMAKE 323 date/time stamps 320-322 directives 323,331-336 conditional 333-336 nesting 334 table of 331 error handling 327, 332-333 explicit rules 319-320, 324-326 overriding 320,322 prefixes 327 file dependency 319-321,324,332 caching 322 setting 324,326 implicit rules 319-320,324,326 building 335 overriding 320,322 prefixes 327 viewing 322 macros 323,328-331,336 autoexecuting 320 defining 322,329-330 duplicate names 329 environment variables 322, 329 multiple 329 null 336 predefined 330-331 undefining 322,329, 335-336 viewing 322 multiple rules 325 online help 320 operators 325, 328, 333 options 319,321-323 overriding 331 setting as defaults 322 suppressing display 322 table of 321 problems with 321, 335 rebuilding files 321 search paths 320, 322, 334 starting 319 stopping 320 syntax 319, 321 macros 329-331 rules 324-326 temporary files 322-323, 328 MAKE macro 330 Make options, project options 96 MAKE.EXE 319, 323 MAKEDIR macro 330 MAKEFILE.MAK 319 makefiles 320 adding macros 329-330 adding text 334 building 323-324 converting project files 31 creating templates 329 debugging 322,328,334 dependents 324-327 errors 507-508 KEEP option 323 naming 322 NMAKE and 323 NOKEEP option 323 'targets 319,326 building 321, 323 multiple 324 recompiling 321 saving 335 symbolic 324 updating 325 viewing messages 334 wildcards and 319,321 MAKEFLAGS macro 330 MAKER 319, 322 Map File options 93 map files, creating 361 Maximum Areas option 419 Maximum Coverage Count option 419 Maximum Windows Messages option 419 Medium option, 16-bit compilers 51 member functions, debugging 166 Member Pointers options 66 memory 468 allocation, problems with 503 dump 186 error messages 477 location, watching 187 overlays 402 problems 503 resource options, specifying 266 stop and start points 438 swapping, MAKER 322 usage 388 memory addresses, pointers 187 Memory Model section, 16-bit compilers 48 memory models, specifying 25 Menu editor 300-301 menus 299 accelerators 303-304 accessing 381 arrows 382 bar, activating 382 creating 300 customizing 466 dialog boxes, including 273 editing 300 ellipsis marks (... ) 385 global 381 hot keys 383 IDE 6 ite~s, adding and editing 301-302 local 389 menu statements, moving and copying 301 opening 382 pop-up menus 302, 382 pull-down menus 382 separators, adding 301 shortcuts 382 System 385 testing 303 TFINST 465 View 389 Menus command (TFINST) 466 message classes 494 Message menu commands All Windows 347 Options 347 Message Queue section, WINSPCTR.LOG 357 Message Trace Options dialog box 347 Message Trace view, WinSight 343-344, 347 messages 512-607 dispatched 347 formats 510 Help compiler 510 makefiles 334 run-time errors 509 saving WinSight 347 symbols 511 tracing, WinSight 343-352 undocumented Windows messages 348 warning messages 509 Windows, logging 492 WinSight, configuring 343 Messages menu commands Selected Classes 345 Selected Windows 347 Trace Off 343 Messages options, project options 97 Microsoft Windows profiling programs 489 remote profiling 482 Windows Messages command 492 Miscellaneous Options dialog box (TFINST) 470 mistakes, undoing, Resource Workshop 221 Mixed command 411 modal Property Inspector 283 Mode for Display menu (TFINST) 472 Model option, 16-bit compilers 51 modeless Property Inspector 284 Modify command (TFINST) 473 Module (display option) 396 Module command Execution Profile window local menu 397 Filter menu 397 Module window local menu 394 Routines window local menu 409 In d ex 623 module definition files 205-206,214 Module window 395 Execution Profile window 395 Execution Profile window link 398 local menu 391 printing from 372 sourl=e code, inspecting 401 modules adding debug information 387 compiling large 322 current, statistics 447 debugging information 161 linking 200 listing running, WinSpector 358 loading 499 viewing . problems 502 source code in 498 Modules section, WINSPCTR.LOG 358 Modules with Source command (Add Areas menu) 392 mouse choosing menu commands 382 compatibility 381 support 381,462,470,491 Mouse Enabled check box (TFINST) 470 moving classes, Rescan 151 Control palette, Dialog editor 285 controls, dialog boxes 278 identifiers 307 resources 266 moving through source code 166 single stepping 164 __MSDOS__ macro 330 MULTITRG.lDE 29 N -N MAKE option 322-323 Name option 396 NAME statement 210 names duplicate 329 macros 329 symbolic targets 324 NEC MultiSpeed and NMI 471 NETBIOS, remote profiling 478 Never Build option, Build Attributes 60 Never option, 16-bit compilers 49 New command (Resource menu) 230 New Project command (Project) 24 New Project dialog box 230 New Target command (Project) 29 New Target dialog box 24 adding targets 29 624 C++ Use r 's G u ide setting target options 24-27 Next command error message generated by 502 Module window local menu 391 Text File window local menu 412 NMAKE vs. MAKE 323 NMI, systems using 471 NMI Intercept check box (TFINST) 471 Node Attributes dialog box 28 nodes, Stle Sheets, attaching 39 None option Area Options dialog box 407 Stack Trace dialog box 394 null macros, MAKE 336 null modem cable, remote profiling 478 -num prefix (MAKE) 327, 333 o object files 197,332 object search paths 113 object-oriented programs 445,500 objects 154, 160 ObjectScripting error messages 510 obsolete C++ options 100 online help command-line options 198 compiler messages 510 MAKE 320 Open command (File menu) 222, 230,386 Open Detail command (Spy menu) 344 Open Project command (Project) 27 opening files, Resource Workshop 264 resource projects 224 windows Call Stack 195 Edit 8 Project 27 Watch 182 Operation Module window command 392 Radio buttons Area window 407 Module window 392 operators conditional 333 MAKE 325,328,333 optimization, MAKE 322 Optimization options project options 102 settings 109 optimizers, profiling 364 options 469 customizing 465 defaults, restoring 473 display 467-469 input 469 projects, changing 31 Options command 6,407 Options command (Message menu) 347 Options menu TFINST 469 Turbo Profiler 429 Options menu commands Environment 157 Project 153,368 Origin command 410 output makefiles 334 testing 160 watching program 161 Output Directories options 82 output file, DFA utility 359 overhead, calculating 453 Overlay window 445 overlays buffer management, overlay event history 445 demonstration 402 execution timing and resource monitoring 440 history 402 memory and 402 monitoring 437 problems with 503 profiling tips and techniques 444 statistics 401-402 Overlays command 437, 447 Overlays window 402, 446 Overwrite mode (IDE) 7 p -p MAKE option 322,462, 491 Paint Can tool, Graphics editor 256 paint patterns, Graphics editor, selecting 248 Paintbrush tool, Graphics editor 256,262 Pascal, debugging programs 166 Pascal option, 16-bit compiler 46 passive analysis active analysis, compared 442 caller information 443 disk 1/ 0 and 443 execution counts 443 interrupts 443 program execution time 442 setting 441 paths calls logging 457 sorting 401 setting 462 Pattern style tool, Graphics editor 261 Pause Program command 166 pausing program execution 166 Pen style tool, Graphics editor· 261 pen styles, Graphics editor, selecting 247 Pen tool, Graphics editor 255 Per Call option 396 performance analyzer See Turbo Profiler Permit 43/50 Lines check box (TFINST) 468 Pick command 403 Pick Rectangle tool, Graphics editor 254 platforms, setting 24 PLOST.C and PLOSTPAS.PAS 453 pointers arrays 448-450 current instruction, returning to 410 instruction addresses of 411 memory addresses 187 pop-up menus, creating 302 Portability options 100 ports remote,setting 462 serial 472 Position command 398 postmortem debugging 353 precious directive 335 precompiled header files 78 predefined colors Project Manager 23 syntax highlighting 14 predefined Style Sheets' 38 preferences Resource Workshop 221 WinSpector, setting 354 preferences (IDE) 16 Preferences dialog box (WinSpector) 354 prefixes, MAKE commands 327 Previous command 410-411 PRIMED sample program 368 Printer Options radio buttons (TFINST) 471 printing high versus standard ASCII 471 Module window contents 372 WinSight messages 347 printing conventions (documentation) 1 Processor options, 16-bit compilers 52 Profile command 409 Profile mode radio buttons 418 Profile radio buttons 396 profile report windows See windows, profile report profiling 367 analysis modes active 418 choosing 439,441 coverage 419 current 388 default 418 passive 419 batch mode 460 defined 1,363 dynamic-link libraries 494-495 end results 439 large programs, display modes 468 object-oriented programs 445 optimizers 364 passes 419 preparing programs for 434 programspeed 443 programs 368· refining the process 441 remote 462, 487 commands 485 configuring Windows driver 483 defined 477 DOS applications 478-479 hardware requirements 478 LANlink 481 LAN system names 482 loading programs 485 local system 478 NETBIOS and 478 network compatibility 478 PS/2 and 480 remote DOS driver (TFREMOTE) 480 remote systems 472, 478 remote Windows driver (WREMOTE) 482 serial link 481 troubleshooting 486 user screen and 485 Windows link 484 Windows programs 482 saving profiles 439 slow programs 443 speeding up 443 steps 433 Turbo Profiler 368 Windows programs 489 Profiling Options 441 program execution, stopping 393 program files adding to Tool menu 34 creating new 8-10 default 8 status in Edit window 8 program group 5 Program Reset command 416 program source windows See windows, program source programs compiling for profiling 435 current 388 execution controlling 161, 166-167 pausing 166 terminating 167 execution speed, profiling 443 execution time, passive analysis 442 exit status, MAKE, ignoring 322 external 166 failing 159 file access, monitoring 437 implementation, problems 160 keyboard input profiling ,435 loading dynamic-link libraries 494-495 problems 502-504 optimizing 448 profiling 368 dynamic-link libraries 494 no debug symbol information 504 out-of-date debug symbol information 504 reloading, problems 501 restructuring, Callers window 400 runrling 11,16,161-162 nonmaskable interrupts 471 to breakpoints 166 to specific locations 163 single-source 12 size, areas 436 slow 443 source location 394 speed, statistics collection 439 stepping through 164-166 stopping during a profiling session 436 structure analysis, statistics for 440 swapping to disk, problems 500 testing 8, 160, 187, 439-440 timing, statistics for 440 Turbo Profiler, sample programs 368 types, setting 9,11 unfamiliar, studying 441 watching 161 Windows profiling 489 Progress Bar tool, Dialog editor 291 Project command (IDE) 6 Project command (Options menu) 153,368 Project command (View menu) 27 Project Description Language (.PDL) files 40 project files Index 625 compiling 319 converting to makefiles 31 including debug information 161 rearranging in IDE 30 targets adding 29 changing defaults 24 defining multiple 32 deleting 30 dependent files 22 setting options 24-27 updating 32 testing 8 viewing 22 Project Manager (IDE) 21-32 . adding files 27 creating projects 24-27 glyphs 23 setting target options 24-27 SpeedMenus 7 translators, specifying 29,33 project nodes (IDE) 22 project options 16-bit compiler options 45-56 32-bit compiler options 57 Build Attributes options 60 C++ options 60 Command-line only options 113 Compiler options 69· compile-time errors, fixing 44 compiling 37,42-43 default 38 Directories options 80 Librarian options 83 Linker options 84 local overrides 41 Make options 96 managing 37 Messages options 97 Optimization options 102 reference 45-125 Resources options 110 setting 37 specifying 37 Style Sheets 38 style sheets, sharing 40 . viewing 42 Project Tree 22-23 expanding/ contracting lists 22 nodes adding 27, 29 compiling 33 copying 30-31 deleting 28,30-31 editing 28, 30 moving 30 referencing 32 specifying 27 translating 28, 33 types, defined 22 viewing 31 Project View options 31 Project window customizing 31 626 C++ Use r 's G u ide generating symbolic debug information 161 opening 27 SpeedBar buttons 7 projects adding source files 27 creating new 24-27 managing 21 options, changing 31 sample . multi-targets 29 Source Pools 33 settingup 8 prompts commands and 497 dialog boxes 499 responding to 497 setting 469 Property Inspector 283-284 Purge Comment Records option 84 Push Button tool, Dialog editor 286 Q-R -q MAKE option 322 Quad word (8-byte) option, 16-bit compilers 54 question mark (?) search wildcard 391 quicksort, bubble sort, compared 448 Quit command 368,389,474 -r MAKE option 322 -r option (remote profiling) 462, 481 Radio Button topl, Dialog editor 287 -rc WREMOTE option (remote clock interrupts) 484 RCDATA resource type, user-defined resources 314 recompiling makefiles 321 reconfiguring the IDE 12-16 Rectangle tool, Graphics editor 258 recursive routines 450 Redo command (Edit menu) 222 references, browsing 156 Refresh Desktop command 385 Register option, 16-bit compiler 46 Register section, WINSPCTR.LOG 357 Remote Analyzing check box (TFINST) 472 remote debugging, configuring 387 REMOTE indicator 486 Remote Link Port radio buttons (TFINST) 472 remote links 472, 504 remote systems, remote profiling 478 remote Windows link, hardware requirements 478 Remove Areas command 407 Remove command 398,447 current areas 447 interrupts 447 Interrupts window local menu 403 renaming resources 265 repeat counts 183, 187 report windows 433 reports, exceptions, WinSpector 355 requirements, Turbo Profiler 435 Rescan 150-151 resizing controls, dialog boxes 278 multiple controls, dialog boxes 280 windows 375 resonance 444 resource (.RES) file 264 resource editors 265 Resource menu commands, New 230 Resource Project window 226,263 resource projects 223,227 creating 223 opening 224 resources 225 saving 224 resource script (.RC) files 264 resource scripts / data, entering 315 dialog boxes, creating 272 resources, saving 267 writing 310 Resource Workshop 264 identifiers, managing 308 Menu editor 300 mistakes, undoing 221 preferences, setting 221 starting 222 resources 219,263,269 16-bit resources 266 32-bit resources 266 binary resource (.RES) files 221 bitmapped resources saving as files 268 creating 263,310 deleting 266 DLGINIT resource, dialog boxes 271 editing as text 268 embedding 226,315 identifiers, adding 306 linking 200,220,226 memory options, specifying 266 monitored 363 moving 266 renaming 265 resource script (.RC) file 220 saving 267 statistics for monitoring 440 user-defined resources 313,316' Resources options, project options 110 response files 199 command-line linkers 203 MAKE 323 restarting programs (integrated debugger) 167 Restore Standard command 385 restoring defaults, IDE· SpeedBars 15 Rich Text Edit tool, Dialog editor 292 rich-text formats 510 Right Sides tool, Dialog editor 296 RLINK resource linker 339 RLINK.EXE resource linker 337 RLINK32 resource linker 339 RLINK32.DLL resource linker 337 Rounded Rectangle tool, Graphics editor 258 routines accessing, problems with 499 active, call stack 456 available for profiling 389 calling other routines~ tracking 437 combined clock 438 jumping to 391 optimizing 448,450 overhead 453 recursive 450 reducing calls to 378 timer data 438 Routines in Module command (Add Areas menu) 392 Routines window 408-409 RTF files 510 Run command 416 Run command (Debug) 11 Run Count option 419 Run To Cursor button 163 Run to Cursor command 163 running, TFINST 474 run-time errors 159-160,508-509 run-time libraries 204 run-time nodes (IDE) 22 s -S MAKE option 322 -s MAKE option 322 Save Configuration dialog box 376, 428 Save Configuration File command (TFINST) 473 Save menu (TFINST) 473 saving IDE settings 16 resource projects 224 resources 267 resource script files 267 window settings 16 -sc option (ignore case) TPROFW 491 Turbo Profiler 462 scalars, inspecting 188 Scissors tool, Graphics editor 254 Screen command (TFINST) 467 Screen Lines radio buttons, TFINST 468 screens background, customizing 467 color, customizing 467 dual 389 flickering, eliminating 162 LCD 473 lines per, setting 468 repainting 468 snow, problems with 468 swapping 467, 469 updating 469 scripts 309-310 scroll bars 383 -sd option (set source directories) TPROFW 491 Turbo Profiler 462 Search command Module window local menu 391 Text File window local menu 412 Search command (IDE) 6 searches 391 SECTIONS statement 211 Segment Names Code options, 16bit compilers 54 Segment Names Data options, 16-bit compilers 55 Segment Names Far Data options, 16-bit compilers 56 SEGMENTS statement 211 Selected Classes command (Messages menu) 345 Selected Windows command (Messages menu) 347 Selector tools, Dialog editor 286 separate clock, timer data 393 serial links, remote 472 Session button 386 Session radio buttons 387 session saving 387 Set Hot Spot command (Cursor menu) 234 Set Range command 188 settings breakpoints 166 project options 37 reconfiguring IDE 13-16 saving IDE 16 window 16 shapes, drawing, Graphics editor 249 SHARE command (DOS) 323 shortcuts, keyboard, IDE windows 13 shortcuts See hot keys Show Project Node option 22 single-source programs 12 slash (/) command-line options 199 MAKE options 321 Small option, 16-bit compilers 52 snow 468 Sort command Areas window local menu 408 Callers window local menu 401 Sort radio buttons 396,405 sort types compared 448 source code debuggbrrg 161-163,167,187,196 editing 195,309 machine-dependent constructs 508 moving through 164~166 viewing 161, 195 Source Directories options 80 source files 21 accessing 23 adding to projects 27 Edit window 23 rearranging in IDE 30 viewing 23 WinSpector reports 359 source modules choosing 394 search order 390 viewing 390 source nodes (IDE) 22 adding 27 attributes 28-29 deleting 28 referencing 32 specifying 27 translating 28 viewing 31 Source options 74 . Source Pools 32-33 Space Horizontally Equal tool, Dialog editor 297 Space Vertically Equal tool, Dialog editor 297 Special command (SpeedMenu) 34 SpeedBars (IDE) 7, 14-15 SpeedMenus ClassExpert 144 IDE 7,34-35 Spy menu commands Exit 344 Find Window 346 Open Detail 344 spying windows 347 SRCPOOL.IDE 33 In d ex 627 stack calls, size of 394 IDE options 25 tracing into 354 Stack radio buttons 394 Stack trace dialog box 394 Stack Trace section, WINSPCTR.LOG 356 STACKSIZE statement 212 standalone bitmap files, creating 230 standalone cursor files, creating 233 Standard Libraries options (IDE) 25 Start Time option 405 Start! command (WinSight) 344 starting Browsers 154 ClassExpert 143 MAKE 319 Resource Workshop 222 TOUCH 321 WinSight 343 WinSpector 353 statements checking 160 debugging 162 execution, verifying 440 Static Frame tool, Dialog editor 289 Static Picture tool, Dialog editor 290· Static Rectangle tool, Dialog editor 289 Static Text tool, Dialog editor 287 statistics accumulation, disabling 420 accuracy 443-444 areas 406 collection 436-437,447 automatic 388 disabling 393, 436 enabling 393 normal 393 options 407 program speed 439 type to collect 439 current area 447 removing 397 routine 409 default 436 displaying 370-371, 396, 439 erasing 398 file activity 404-405 files, writing to problems 501 filtering 397, 438, 441, 447 limiting 438 module 396 overlays 401-402 partial 438 printing 373 problems 501 program execution speed 443 removing 395-396 628 C. + + Use r 's G u ide sorting 395-396 start and stop points, maximum 438, time 396-397 types of 437 viewing 395 choices 395 number of passes 396 source code with 375 time 396 status bars, IDE 7 status line 384 Status Window tool, Dialog editor 292 Step Over button 166 Step Over command 166 stepping through programs 164-166 Stop option 405 Stop! command (WinSight) 344 stopping program execution 166 strings MAKE macros 322 searching for 412, 498 substitutions 330 structure analysis, statistics 440 structures 187":188 STUB statement 213 Style Sheets managing 38 nodes,attaching 39 project options 38-40 Sub functions command 403 SUBSYSTEM statement 213 suffixes directive 335 swapping memory, MAKER 322 SYM files 356,361 Symbol Declaration window, Browser 155 symbol names, problems 500 symbol tables 161,504 adding to files 161 dynamic-link libraries 494 invalid 504 symbolic debug information 161 symbols code, browsing 155 . disassembled 410 messages 511 problems 505 syntax command-line compilers 198 format specifiers, watches 183 MAKE 319,321 commands 326-328 explicit rules 324-326 implicit rules 326 macros 329-331 TOUCH 321 Syntax Highlighting option 14 System Information section, WINSPCTR. LOG 358 T -t option (starting directory) 491-492 Tab Control tool, Dialog editor 290 'Tab Size input box, TFINST 468 tabs, setting 468,506 . Tandy 1000 and NMI 471 target files 21 Target Model options (IDE) 25 target nodes (IDE) 22 adding 29 attributes 30 deleting 30 multiple 32 types, defined 29 updating 32 viewing 31 target platforms, setting 24 TargetExpert 25,30 TargetExpert dialog box 30 Tasks section, WINSPCTR.LOG 357 TDDEBUG.386 file 490 TDRF (remote file transfer utility) 478,486 templates, makefiles 329 Templates options 67 temporary files, MAKE 322-323, 328 Terminate Program command 167 terminating programs 167 testing applications 33, 162 bitmaps 231 cursors 235 dialog boxes 275 icons 241 menus 303 program setup 8 programs 160, 187 user-defined resources 316 text adding to graphics, Graphics editor 249 editors 469, 500 files searching 412 viewing 389 makefiles 334 resources, editing as 268 searching for 391, 505 Text Edit command (View menu) 23 Text Edit tool, Dialog editor 288 Text editor 8, 197,309-310 Text File window 413 text files, MAKE 323 Text tool, Graphics editor 257 TFCONFIG.TF 376 TFINST474 command-line options 475 exiting 474 main menu 465 options, saving 473 TPROFW, using with 491 TFREMOTE (remote profiling utility) configuring 479 customizing 479 error messages 487 installing 478 LANlink 480 loading 480 problems with 504 serial link 480 This Line command (Add Areas menu) 392 This Module option 394 This Routine option 394 time and counts profile listing 372 Time option Execution Profile window 396 Interrupt window 404 time stamps (MAKE) 320-322 timer combined clock 438 data grouping 438 inaccurate results 457 separate, combined clock, compared 393 setting 419 sound routines 457 Timer radio buttons 393,407 Tiny option, 16-bit compilers 52 title bars 383 TLINK 201 command-line syntax 201 configuration files 203 errors 508 file-name extensions 202 libraries 204 option~overriding 203 .TLINKCFG 200 TLINK32 201, 203 TLINK32.CFG 200 TMAPSYM.EXE utility 360-361 Tool Bar tool, Dialog editor 292 Tool commandiIDE) 6 Tool menu adding files 34 customizing 16 Tool palette, Graphics editor 253-254,296 TOOLHELP.DLL 353 tools 33-35 Tools command (Options) 34 Tools dialog box 34 Tops tool, Dialog editor 297 TOUCH utility 321 TPROF error messages 506 modifying with TFINST 473 TPROFW command-line options 491 configuring 490 dynamic-link libraries, profiling 494 error messages 495 installation 489-490 list of files 490 message classes 494 profiling Windows, programs 489 running 492 switching applications 492 Trace Into command 165 Trace Off command (Messages menu) 343 tracing messages WinSight 343-345 WinSign 347 tracing into code 165, 195 tracing messages (WinSight) 347 Track Bar tool, Dialog editor 292 transfer macros 34 translating 359 translating project nodes 28, 33 translators 29,33 transparent color area, Graphics editor 245 Tree View tool, Dialog editor 291 TSR programs, display swapping 469 Turbo Assembler 368 Turbo Debugger 159,359 Turbo language products 435 Turbo Profiler 368 tumingoff command-line options 199 syntax highlighting 14 tutorial 3,217,317,380 typographic conventions (documentation) 1 u -U MAKE option 322 UAEs (Unrecoverable Application Errors) 353 unconditional breakpoints, setting 168 undefining MAKE macros 322, 329, 335-336 Undo command (Edit menu) 8, 222 undocumented Windows messages 348 Uninitialized data (BSS class) option 56 Uninitialized data (BSS group) option 56 Uninitialized data (BSS segment) option 56 Uninitialized data option 55 unions, watching 187 updating targets 32 Up-Down tool, Dialog editor 291 Use Borland optimizing compiler option 57 Use Intel optimizing compiler option 57 USER and GDI heap section, WINSPCTRLOG 358 user interfaces, testing 160 user screen display buffer 468 remote profiling 485 updating 469 User Screen Updating radio buttons (TFINST) 469 user-defined resources 313-316 v -v option (video hardware) 463 values changing 185-188 checking 160-161,181 decimal watches 183, 186 expressions, viewing 182 floating-point, watches 183,186 hexadecimal, watches 183, 186 variables debugging 185 values changing 185,187 checking 160-161, 181 verbose stack trace 354 version number information 386 Vertical Center in Dialog tool, Dialog editor 297 Vertical Centers tool, Dialog editor 297 Vertical Scroll Bar tool, Dialog editor 289 Vertical Static Line tool, Dialog editor 289 video adapters 472 display pages 469 options 463 Video Graphics Array Adapter (VGA), line display 468 View command (IDE) 6 View menu 159, 389 View Source command 195,411 viewers 33 viewing arguments 195 compile-time errors 45 In d ex 629 current windows 345-346 expressions 182 function calls 195 project files 22 project nodes 31 project options 42 source code 161,195 . source files 23 windows, current 347 WinSpector reports 354 views, WinSight 343-344 Virtual table class option 57 Virtual table segment option 57 Virtual Tables options 68 w-z -W MAKE option 322 -w option (save option settings), TFREMOTE 479 warning beeps, enabling 470 warnings 508-509,512-607 ignoring 11 run-time errors 509 Warnings options 95-97 Watch command 182 Watch Properties dialog box, settings, losing 183 Watch window 182 watches 182-186 When Full command 405 whitespace, MAKE macros 329- 330 wildcards DOS 319,321,412,505-506 searches 391 WIN_TEST.IDE 10 Window command (IDE) 6 window messages logging to the TPROFW window 492 setting number tracked 419 Window Procedure Messages dialog box 493 Window procedures 396, 408 Window Tree view, WinSight 343345 Windows programs, exception addresses 355 system information, listing 358 windows activating 384 active, defined 383 Areas 399-408 . Callers 401 children 346 close box 383 closing 383 customizing 466 630 c++ User's Guide dialog boxes, choosing 273 Disassembly (CPU) 411 Execution Profile 395-398 files 405 Interrupts 404 linking 375 locating, WinSight 346 Module 390-395 moving 384 multiple 413 opening 383 Call Stack 195 Watch 182 Overlays 402 panes 383 problems 503 profile report 446 program source 445 properties 383 report 433 resizing 375,384 restoring 385 routines 409 saving settings 16, 376 scrolling 383 spying 347 viewing current 345-347 WinSight 343 zooming 383-384 Windows all functions exportable, 16-bit compilers 46 Windows API bitmaps,programming 232 cursors, programming 237 dialog boxes, programming 276 icons, programming 241 Windows applications creating 10-12 32-bit executables 159 IDE options 25-27 linking 199 Windows command (TFINST) 466 Windows messages, tracing 352 WinSight 343-353 Class List view 344-345 configuring 343 exiting 344 Message Trace view 347 messages, tracing 343-352 printing messages 347 saving messages 347 starting 343 views 343-344 Window Tree view 345 windows 343 locating 346 spying 347 windows hierarchy lists 345-347 WINSPCTRBIN 353, 360 WINSPCTR.INI, commands, editing 354 WINSPCTRLOG 353,355-359 DFA utility 359 Disassembly section 356 Message Queue section 357 Modules section 358 Register section 357 Stack Trace section 356 System Information section 358 Tasks section 357 USER and GDI heap section 358 WinSpector 353-361 adding source files to reports 359 appending new reports 354 BUILDSYM.EXE utility 361 exceptions, reports 355 EXEMAP.EXE ·360-361 functions, listing 356 heaps, listing information 358 including line numbers in reports 359 locating last message received 357 modules, listing running 358 overwriting previous reports 354 preferences, setting 354 processing data 360 programs, listing running 357 reading log files 355-359 stack pointers 356 starting 353 system information, listing 358 TMAPSYM.EXE utility 360-361 utilities 360-361 viewing reports 354 WINSPECTORLOG, configuring 354 Word alignment (2-byte) option, nl6-bit compilers 54 W ordStar-style cursor-movement commands 470 Wrap option 405 WREMOTE command-line options 484 configuring 482 error messages 488 hardware requirements 478 software requirements 482 writing resource scripts 310 Yes option 411 zoom icon 383-384 Zoom tool, Graphics editor 255 Borland Corporate Headquarters: 100 Borland Way, Scotts Valley, CA 95066-3249, (408) 431- 1000. Offices in: Australia, Belgium, Brazil, Canada, Chile, Denmark, France, Germany, Hong Kong, Italy, Japan, Korea, Latin America, Malaysia, Netherlands, Singapore, Spain, Sweden, Taiwan, and United Kingdom . Part # WBC1350WW21770 ISBN: 0-672-30922-X
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.3 Linearized : No XMP Toolkit : Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:56:37 Producer : Adobe Acrobat 9.12 Paper Capture Plug-in Modify Date : 2009:07:29 17:41:02-07:00 Create Date : 2009:07:29 17:41:02-07:00 Metadata Date : 2009:07:29 17:41:02-07:00 Format : application/pdf Document ID : uuid:ecda3bae-5e49-42c7-8ba3-c4f936590f76 Instance ID : uuid:eecac9ea-61b4-4d9d-a9c6-95b730e860a0 Page Layout : SinglePage Page Mode : UseNone Page Count : 651EXIF Metadata provided by EXIF.tools