Borland_C++_Version_4.0_Users_Guide_Oct93 Borland C Version 4.0 Users Guide Oct93

Borland_C++_Version_4.0_Users_Guide_Oct93 Borland_C++_Version_4.0_Users_Guide_Oct93

User Manual: Borland_C++_Version_4.0_Users_Guide_Oct93

Open the PDF directly: View PDF PDF.
Page Count: 462

DownloadBorland_C++_Version_4.0_Users_Guide_Oct93 Borland C  Version 4.0 Users Guide Oct93
Open PDF In BrowserView PDF
or an

++

User's Guide

Borland® C++
Version 4.0

Redistributable files
You can redistribute the following files in accordance with the No Nonsense License
Statement:
•
•
•
•
•
•
•

BC40RTL.DLL
BIDS40.DLL
BIDS40F.DLL
BIVBX1 O.DLL
BW320007.DLL
BW320009.DLL
BW32000C.DLL

•
•
•
•

BWCC.DLL
BWCCOO07.DLL
BWCCOO09.DLL
BWCCOOOC.DLL

• BWCC32.DLL

• COMPRESS.EXE .
• CTL3D.DLL
• CTL3D32.DLL
•
•
•
•

CW32.DLL
CW32MT.DLL
CX32.DLL
CX32MT.DLL

• DIB.DRV
.• GAUGEVBX
• LOCALEBLL
• MARS.DLL
• MARS.MOB

• MSMOUSEDRV
.OWL200.DLL
• OWL200F.DLL
• PICT.VBX
• REGLOAD.EXE
• STRESS.DLL
• SWITCH.VBX
• TOOLHELP.DLL
• VGAP.DRV
• YESMOUSE.DRV

Borland may have patents andbr pending patent applications covering subject matter in this
document. The furnishing of this document does not give you any license to these patents.
COPYRIGHT © 1987,1993 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.

Borland International, Inc.
100 Borland Way, Scotts Valley, CA 95067-3249 .
PRINTED IN THE UNITED STATES OF AMERICA
1EOR1093
9394959697-9876543

W1

Contents
Introduction
1
What's new in Borland c++ ................... 1
Manual conventions ......................... 2
Contacting Borland .......................... 2
Part I Using Borland C++ for Windows
Chapter 1 Getting started
7
Installing Borland C++ ....................... 7
Hardware and software requirements ........ 7
Installation steps .......................... 8
Starting Borland C++ ..................... 10
Getting Help ............................. 11
Configuring the IDE ........................ 11
Changing the SpeedBars ................... 12
Setting IDE preferences ................... 13
Saving your IDE settings ...... : ........... 13
Using the Editor ............................ 14
Configuring the IDE editor ................ 14
Syntax highlighting ....................... 14
Working with the Message window ........... 15
Browsing through your code ................. 16
Browsing through objects (class overview) ... 17
Filters ................................. 17
Viewing declarations of listed symbols .... 18
Browsing through global symbols .......... 18
Using regular expressions in the browser .. 19
Browsing symbols in your code ............ 20
Using command-line tools ................... 20
DPMI and the command-line tools .......... 20
Memory and MAKESWAP.EXE ............ 21
The run-time manager and tools ............ 21
Controlling the memory RTM uses ....... 21
Running other programs from the IDE ........ 22
Chapter 2 Using the project manager
25
What is project management? ................ 25
Creating a project ........................... 26
Creating a multiple-target project ........... 28
Converting old projects ................... 29
Converting projects to makefiles ......... " . 29
Changing the Project View .......... , ...... 29
Building a project ..................... : ..... 30
Building part of a project .................. 30
Editing the projecttree ...................... 31

Editing target attributes with TargetExpert " 32
Editing node attributes .................... 32
Adding and deleting a node ............... 33
Adding and deleting targets ............... 33
Moving nodes and targets ................. 34
Copying nodes ............................ 34
Using Source Pools ......................... 35
Setting project options ...................... 36
Local Override ........................... 36
Using Style Sheets ... , .................... 37
Attaching a Style Sheet to a node ......... 37
Creating a Style Sheet ................... 38
Editing Sty Ie Sheets . . . . . . . . . . . . . . . . . . . . . 38
Sharing Style Sheets .................... 39
Viewing options in a project ............... 40
Translators ................................ 40
Installing a translator ..................... 41
Using Special on the SpeedMenu ........... 42
Installing viewers and tools . . . . . . . . . . . . . . . . 42

Chapter 3 Compiling
43
Compiling in the IDE ....................... 43
Using IDE compiler options ............... 44
Using the command-line compilers ........... 44
Configuration files ........................ 45
Response files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Option precedence rules .................. 46
Compiler options reference " ................ 46
Directories ................................ 55
File-search algorithms .................... 56
Compiler I Defines .......................... 56
Compiler I Code-generation .................. 57
Compiler I Floating Point .................... 58
C~mpiler I Compiler Output ................. 59
Compiler I Source ........................... 59
Compiler I Debugging ....................... 60
Compiler I Precompiled headers ............ '.. 61
16-bit Compiler I Processor .................. 61
16-bit Compiler I Calling Convention .......... 62
16-bit Compiler I Memory Model ............. 62
16-bit Compiler I Segment Names Data ........ 65
16-bit Compiler I Segment Names Far Data .... 65
16-bit Compiler I Segment Names Code ....... 66
16-bit Compiler I Entry /Exit Code . ~ .......... 66

32-bit Compiler I Processor ................... 68
32-bit Compiler I Calling Convention .......... 68
C++ Options I Member Pointer ............. ;. 69
C++ Options I C++ Compatibility ............. 69
C++ Options I Virtual Tables ................. 70
C++ Options I Templates .................... 71
C++ Options I Exception handling/RTTI ....... 71
Optimizations ............. '................. 72
Optimizations I Specific ...................... 72
Optimizations I Size ......................... 73
Optimizations i Speed ....................... 74
Messages .................................. 76
Messages I Portability ....................... 77
Messages I ANSI Violations .................. 77
Messages I Obsolete C++ ..................... 78
Messages I Potential C++ Errors .............. 78
Messages I Inefficient C++ Coding ............ 78
Messages I Potential errors ....... '............ 78
Messages I Inefficient Coding ................. 79
Messages I General ........... ,............... 79
Make ..................................... 79
Command-line options ...................... 79

Chapter 4 Building applications with AppExpert 83
AppExpert basics ........................... 83
Creating an application with AppExpert ....... 84
Default AppExpert applications ............ 85
Application options ......................... 85
Application I Basic Options ................ 86
Application I Advanced Options ............ 86
Application I Code Gen Control ............ 87
Application I Admin Options ............... 87
Main Window options ...................... 88
Main Window I Basic Options .............. 88
Main Window I SDI Client ................. 89
Main Window I MDI Client ................ 90
MDI Child/View options .................... 90
MDI Child/View I Basic Options ...... ~ .... 90
Chapter 5 Using Class Expert
93
Starting ClassExpert ........................ 93
Class Expert basics ........................ 93
Classes pane ........................... 94
Events pane ............................ 94
Edit pane ................. ; ............ 94
Adding a class ........................... 94
Creating document types .................. 95
Adding and deleting event handlers ........ 96
Adding and deleting instance variables ...... 97

Jumping to class source code ............... 98
Using Resource Workshop with ClassExpert ... 98
Running Resource Workshop from the IDE .. 99
Using Rescan .............................. 99
Deleting a class ......................... 100
Moving a class .......................... 100
Renaming an AppExpert element ......... 100
Importing a class ........................ 101
Rebuilding the .APX database file ......... 101

Chapter 6 Using the integrated debugger
103
Types of bugs ............................. 103
Compile-time errors ..................... 103
Run-time errors ......................... 104
Logic errors ............................ 104
Generating debugging information .......... 105
Specifying program arguments ............. 105
Controlling program execution .............. 105
Watching program output ................ 106
Stepping through code ................... 106
Tracing into code ........................ 107.
Stepping and tracing class member
functions ............................. 107
Stepping and tracing external code ...... 108
Stepping over large sections of code ........ 108
Running to a specific location ........... 108
Locating a function .................... 108
Returning to the execution point ........ 108
Navigating backward .................. 108
Stopping the program ................... 109
Starting over . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Examining values ......................... 109
What's an expression? .................... 110
Watching expressions .................... 110
Adding a watch ....................... 110
Formatting watch expressions .......... 111
Disabling a watch ..................... 112
Deleting a watch ...................... 112
Editing a watch ....................... 112
Evaluating and modifying expressions ..... 112
Evaluating expressions ................. 112
Modifying variables ......... ; ......... 113
Inspecting data elements ................. 114
Examining register values ................ 115
Using breakpoints ......................... 116
Setting breakpoints .............. , ....... 116
Working with breakpoints ................ 116
Deleting breakpoints ................... 117
Disabling and enabling breakpoints ..... 117

TLINK.CFG ............................
Response files ...........................
Using TLINK with BCC.EXE ..............
Linking libraries ........................
TLINK options ............................
Module-definition file reference .............
CODE statement ........................
DATA statement ........................
DESCRIPTION statement ................
EXETYPE statement .....................
EXPORTS statement .....................
Chapter 7 WinSight
123
IMPORTS statement .....................
Getting started ............................ 123
LIBRARY statement .....................
Starting and stopping screen updates ...... 123
NAME statement ........................
Turning off message tracing ............. 124
SEGMENTS statement ...................
Choosing a view ........................... 124 . STACKSIZE statement ...................
Class List ................................. 124
STUB statement ................ ~ ........
Using the Class List view ................. 125
Module-definition file defaults .............
Spying on classes ........................ 125
Window Tree ............................. 125 Chapter 10 Using resource tools
Finding a window ....................... 126 BRCC.EXE: The resource compiler ...........
Leaving Find Window mode ............ 127 RLINK: the resource linker .................
Spying on windows ...................... 127 BRC.EXE: the resource shell ................
Choosing messages to trace ................. 127
Using the Message Trace view ............ 127 Chapter 11 Using libraries
Other tracing options .................. 128 Using IMPLIB: The import librarian .........
Using IMPDEF: The module-definition file
Chapter 8 WinSpector
133 manager .................................
Classes in a DLL ........................
Using WinSpector ......................... 133
Functions in a DLL ......................
Configuring WINSPCTR LOG: ............ 134
WINSPCTRLOG reference ............... 135 Using TLIB: the Turbo Librarian .............
Why use object module libraries? ..........
Disassembly section ................... 136
The TLIB command line ..................
Stack Trace section ..................... 136
Using response files ...................
Register section ....................... 137
Message Queue section ................. 137
Using case-sensitive symbols: The IC
option ...............................
Tasks section .......................... 138
Creating an extended dictionary: The IE
Modules section ....................... 138
option ...............................
USER and GDI heap section ............ 139
Setting the page size: The IP option .....
System Information section ............. 139
Processing WinSpector data ................. 139
Removing comment records: The 10
option ......, .............. : ..........
DFA output ............................. 140
The operation list ......................
Using DFA with WINSPCTRLOG ......... 140
Examples ...............................
Using DFA with WINSPCTRBIN .......... 140
Other WinSpector tools ..................... 141
Chapter 12 Using MAKE
Using EXEMAP.EXE ..................... 141
MAKE
basics .................. '...........
Using TMAPSYM.EXE ................... 142
BUILTINS.MAK
........................
Using BUILDSYM.EXE ................... 142
Using TOUCH.EXE ......................
Chapter 9 Using the linker: TUNK
143
MAKE options ..........................
Setting options on as defaults ...........
TLINK basid; ............................. 143
Viewing and editing code at a breakpoint. 117
Resetting invalid breakpoints ........... 118
Changing breakpoint properties ......... 118
Logging expressions ................... 119
Customizing breakpoints and the execution
point ............................' ....... 120
Catching general protection faults ........... 120
Using the Event Log window ............... 120
Debugging dynamic-link libraries ........... 121
Debugging in soft and hard mode ........... 122

iii

144
145
146
146
147
154
154
155
155
155
156
157
157
158
158
159
159
159
161
162
163
164
167
167
168
169
169
170
170
171
171
172
172
172
173
173
174
175
175
176
177
177
178

Compatibility with Microsoft's NMAKE .. 178
Show Identifiers ....................... 204
Using makefiles ........................... 179
Show Resources ....................... 204
Symbolic targets ......................... 179
Show Items . ; ......................... 204
Show Unused Types ................... 204
Rules for symbolic targets .............. 180
Explicit and implicit rules .................. 180 ,
Selecting a resource . . . . . . . . .. . . . . . . . . . . . . 204
Explicit rule syntax ...................... 180 Working with resources .................... 204
Single targets with multiple rules ........ 181
Loading a resource ...................... 204
Implicit rule syntax ...................... 182
Resource editors ...................... 205
Explicit rules with implicit commands ... 182
The internal text editor ...... , .......... 205
Commands syntax ..... " ................ 183
Adding a resource .. ~ .................... 205
Command prefixes .................... 183
Adding an embedded resource .......... 206
Using @ .' . . . • . . . . . . . . . . . . . . . . . • . . . . . . • 183
Adding a linked resource ............... 206
Using -num and - ............... ; ..... 183
Moving a resource ....................... 207
Using & .............................. 184 , Copying resources between projects ....... 207
Command operators ................... 184
Deleting a resource ...................... 208
Debugging with temporary files ......... 184
Renaming a resource .................... 208
Using MAKE macros ....................... 185
Specifying resource memory options ....... 209
Defining macros ......................... 185 Using identifiers .......................... 210
Using a macro ........................... 186
Components of resource identifiers ........ 210
String substitutions in macros ............. 186
Identifier files ........................... 211
"Creating identifier files ................. 211
Default MAKE macros ................... 186
Modifying default macros ................ 187
C header files ......................... 211
Using MAKE directives .................... 188
Automatic identifier management ......... 212
.autodepend ..... '....................... 189
Working without an identifier file ......... 213
!error .................................. 189
Adding identifiers ....................... 213
Summing up error-checking controls ..... 189
By renaming resources ................. 213
!if and other conditional directives ......... 190
By using the Identifiers dialog box ....... 214
!include ................................ 191
Editing identifiers ....................... 214
!message ................. : ............. 191
Deleting identifiers ...................... 214
.path.ext ................................ 192
Listing identifiers ....................... 215
.precious ....... ',' ............. '......... 192
Starting a resource editor ................. 215
.suffixes ................................ 192 Setting preferences ........................ 216
!undef .............................. '.... 193
Undo Levels ............................ 216
Using macros in directives .............. , . 193
Text Editor ............................. 216
Nun macros ............................ 193
'Multi-Save ............................. 216
Target Windows Version ................. 217
Part" Using Resource Workshop
Working with binary files .................... 217
Chapter 13 Resource Workshop basics
197 Creating 32-bit resources ................... 218
Understanding Windows resources ., ......... 197 Chapter 15 Creating dialog boxes
221
Types of resource files ...................... 199 Starting the Dialog editor ................ : . ; 221
Bitmapped resource files ................. 200
Creating a new dialog box ................ 221
I

Editing an existing dialog box ............. 222
Using the Dialog editor .................... 222
Selecting a dialog box . . . . . . . . . . . . . . . . . . . . 223
Setting dialog box attributes .............. 223
Adding a caption ...................... 223
Choosing a frame style ................. 224
Choosing a dialog style ................ 224

Chapter 14 Working with projects, resources, and
identifiers
201
Creating a new project ..................... 201
Opening an existing project ................. 202
Using the Project window .................. 202
, Embedded and linked resources ........... 203
Displaying the Project window ............ 203

iv

Changing fonts ........................ 225
Including a menu ...................... 225
Assigning a custom class to a dialog box .. 226
Setting dialog box position ................ 226
Working with controls ................... 226
Families of controls .................... 226
Tools palette .......................... 227
Selecting controls ...................... 229
Adding controls ....................... 231
Adding multiple copies of a control ...... 231
Control'properties (.VBX controls) ....... 232
Moving controls ....................... 232
Resizing controls ...................... 232
Locating and sizing controls at the
same time ............................ 232
Aligning controls with a grid ............ 233
Editing controls ......... ' .............. 233
Adding captions to controls ............. 235
Changing a control's class ............... 235
Specifying controls as tab stops .......... 235
Grouping related controls .............. 236
Reordering controls (tab order) .......... 236
Aligning, resizing, and arranging controls .. 237
Aligning multiple controls .............. 237
Placing controls in columns and rows .... 239
Resizing multiple controls .............. 240
Single-control sizing options ............ 241
Button controls .......................... 241
Push button Control ID values .......... 242
Scroll bar controls ....................... 243
List box controls ......................... 244
Edit text controls ........................ 246
Static controls ........................... 248
Iconic static controls ................... 249
Combo box controls ..................... 250
Custom controls ......................... 251
Creating your own custom controls ...... 252
Installing a control library (.DLL or .VBX) .252
, Displaying custom cont~ols ............. 252
Adding a custom control ............... 252
Testing a dialog box ....................... 253
Viewing two dialog boxes .................. 253
Customizing the Dialog editor' .............. 254

Chapter 16 Creating menus

257
Menu terminology ......................... 257
Starting the Menu editor ................... 258
Creating a new menu .................... 258
Editing an existing menu ................. 258

Menu editor screen ........................
Attribute pane ..........................
Test Menu pane ............ " ...........
Outline pane ............................
Editing menus ............................
Adding new statements ..................
Adding menu items and separators ........
Editing menu items ............. , ........
Using the Attribute pane ...............
Entering item text .....................
Entering item IDs .....................
Moving and copying statements ...........
Deleting menu statements ................
Creating floating menus ..................
Testing menus ....... : ....................
Editing menu resource scripts ...............
Sample menu .............................
Creating the sample menu ................
Adding commands to the menu .........
Adding commands to the Arrange
List menu ............................
Testing the menu ..... '" ..............

259
259
259
259
260
260
261
261
262
264
264
264
265
265
266
267
268
268
269

Chapter 17 Creating accelerators

271

Accelerator table key combinations ..........
ASCII keys .............................
Virtual keys .. ; .........................
Starting the Accelerator editor ..............
Creating a new accelerator table ...........
Editing an existing accelerator table ........
Running the Menu editor at the same time ..
Using the Accelerator editor ................
Outline pane ............................
Attribute pane ..........................
Editing an accelerator table .................
Adding an accelerator key ................
Selecting an accelerator key ...............
Using the Attribute pane .................
Setting the command value .............
Specifying the accelerator key ...........
Flash feature ..........................
Checking for duplicate key combinations .....
Creating a sample accelerator table ..........

271
272
272
272
272
273
273
273
273
274
275
275
275
275
276
276
277
277

Chapter 18 Creating a string table

281
281
281
282
282

Starting the String editor ...................
To create a new string table ...............
To edit an existing string table ............
Working with string tables ..................

v

270
270

277

Windows and strings .................... 283
Entering a new string .................... 283
Editing existing strings ........... _........ 284
Changing a string ..................... 284
Editing the resource script of a string table .. 285
Changing the string .................... 285
Creating a sample string table ............... 285

Save with default device colors ......... 308

Chapter 20 Creating icons
309
Creating a new icon ....................... 309
Adding an icon to a project file ............ 309
Creating a standalone icon file ............ 310
'Binary format option .................. 310
Icon project file ....................... 311
Editing icons .............................. 311
Viewing other resolutions ................ 311
Using transparent and inverted color areas . 311
Adding an image to an icon resource ........ 312
Changing an icon's attributes ............... 313
Displaying device information ............ 313
Creating a sample icon ..................... 314
Drawing the calculator ................... 314
Adding a three-dimensional effect ........ ; 315
Drawing the ledger page ................. 316

Chapter 19 Using the Bitmap editor
289
Starting the Bitmap editor .................. 289
Pixels, foreground and background colors .... 289
Using the Tools palette ..................... 290
Pick Rectangle tool ...................... 292
Scissors tool ............................ 292
Zoom tool ..................... ~ ........ 292
Eraser tool .............................. 293
Pen tool ................................ 293
Paintbrush tool .......................... 293
Airbrush tool ........................... 294
Paint Can tool ........................... 294
Line tool ................................ 295
Text tool ................................ 295
Painting empty frames ................... 296
Painting filled frames ............. , ...... 296
Hand tool .............................. 297
Style selections .......................... 297
Using the two window panes ............... 297
Reading the status line ..................... 298
Working with colors ....................... 298
Choosing the number of colors for a
resource ................ ,................ 299
Using foreground and background colors ... 299
Transparent and inverted color areas ....... 300
Setting transparent and inverted colors ... 300
Hiding and showing the Colors palette ..... 301
Customizing colors ........................ 301
Editing colors in the Colors palette ......... 302
Palette index ........ ,.................. 302
Editing a color ........................ 302
Adding text to a bitmap .................... 303
Aligning text ............................ 303
Choosing fonts, size, and text style ......... 304
Choosing brush shapes ..................... 304
Choosing paint patterns .................... 305
Choosing a line style ....................... 306
Aligning a selected area .................... 306
Resizing a selected area .................... 307
Setting global Bitmap editor options ......... 307
Draw on both images .................. 308

Chapter 21 Creating cursors
Creating a new cursor ......................
Adding a cursor to a project file ...........
Creating a standalone cursor file ..........
Binary format option ..................
Cursor project file .....................
Editing cursors ............................
Colors palette for cursors .................
Working with transparent and
inverted areas ...........................
Setting the cursor's hot spot ...............

Chapter 22 Creating fonts
Font types ................................
Why put bitmaps in a font? ...............
Creating a new font resource ...............
Adding a font to a project file .............
Creating a standalone font file ............
Binary format option ..................
Font project file .......................
Editing a font resource .....................
Defining and adding characters for a font ..
Defining the font size ..................
Setting the number of characters ........
Mapping the character set ..............
Creating variable-width fonts .............
, Setting the width of a character or image.
Defining a header for a font resource .......
Changing size and attributes ..............
Using your fonts in your applications ........

vi

319
319
319
320
320
321
321
321
321
321
323
323
324
324
324
325
325
325
326
326
326
327
327
328
328
329
330
330

Chapter 23 Creating user-defined resources
331
Creating a resource type .................... 332
Adding user-defined resources .............. 332
Editing user-defined resources .............. 333
Embedding resource data in the project file .334
Entering data in the resource script ........ 334
Handling data stored in a separate file ..... 335
Using the RCDATA resource type ............ 335
Appendix A Error messages
337
Message classes ........................... 337
Fatal errors ............................. 337
Errors .................................. 338
Warnings ............................. '.. 338
Help compiler messages .................... 338
Message listings ........................... 339
Message explanations ...................... 339

Borland Button Style dialog box .........
Borland Radio Button Style dialog box ...
Borland Check Box Style dialog box .....
Borland Shade Style dialog box .........
Borland Static Text Style dialog box ......
Modifying existing applications for BWCC ...
Loading BWCC .........................
Using BWCC in C and C++ programs ....
Tips on editing resources .. '. ~ .............

398
400
400
400
400
401
401
401
402

Appendix C Precompiled headers

403
403
404
404
4:04
405
405

How they work ...........................
Drawbacks .............................
Using precompiled headers .................
Setting file names .......................
Establishing identity .....................
Optimizing precompiled headers ..........

Appendix 0 Using EasyWin
407
ConsoleD OS to Windows made easy ......... 407
_InitEasyWin() ........................... 407
Added functions ........................ 408

Appendix B Borland Windows Custom Controls 395
Using the Borland custom dialog class ....... 395
Using Borland controls ..................... 396
Button and check box enchancements ...... 397
Using the BWCC style dialog boxes ........ 398

Index

vii

409

Tables
1.1 Letter symbols in the Browser ............. 19 11.3 TLIB action symbols ................... 174
1.2 Browser search expressions .............. 19 12.1 MAKE options ........................ 177
12.2 Command prefixes .................... 183
1.3 Environment variables for RTM's memory
allocation .............................. 22 12.3 Command operators .................. 184
3.1 Options summary ....................... 47 12.4 Command line vs. makefile macros ..... 186
4.1 Client/view class with Document/view ... 89 12.5 Default macros ......................., 187
12.6, Other default macros .................. 187
4.2 MDI client/view class with
Document/view ........................ 91 12.7 File-name macro modifiers ............. 187
6.1 Format specifiers for debugger expressions .113 12.8 MAKE directives ..................... 188
6.2 CPU flags in the Register window ........ 115 _ 12.9 Conditional operators ................. 191
6.3 Event Log window SpeedMenus ......... 121 14.1 Resource memory options .............. 209
7.1 Mouse messages ....................... 129 14.2 Identifier prefixes ..................... 212
7.2 Window messages ..................... 129 15.1 Common options in Style dialog boxes ... 234
7.3 Input messages ........................ 129 15.2 Control attributes ..................... 234
7.4 System messages ....................... 130 15.3 Alignment options .................... 237
7.5 Initialization messages .................. 130 15.4 Size options .......................... 240
7.6 Clipboard messages ................ ~ ... 130 15.5 Button types ......................... 242
7.7 DDE messages ......................... 130 15.6 Predefined Windows button controls .... 243
7.8 Nonclient messages ........... ,......... 130 15.7 Alignment options .................... 244
7.9 Print messages ............... ' .......... 130 15.8 Owner Drawing options ............... 244
7.10 Control messages ..................... 131 15.9 List Box options ...................... 245
7.11 Pen messages ......................... 132 15.10 Edit Text Style dialog box options ...... 246
7.12 Multimedia messages .................. 132 15.11 Windows 3.1 styles ................... 247
7.13 Other messages ....................... 132 15.12 Control Type options ................. 248
7.14 Messages not documented by Microsoft .. 132 15.13 Combo box Type options ............. 25U
8.1 Exception types ............ : ........... 135 15.14 Owner Drawing options .............. 250
8.2 DFA options ........................... 141 15.15 Combo box attributes ......... ~ ....... 251
9.1 Borland 16-bit libraries and startup files ... 146 16.1 View menu selections ................. 259
9.2 Borland 32-bit libraries and startup files, .. 147 16.2 Menu editor Attribute pane selections ... 262
9.3 TLINK options ........................ 147 17.1 Attribute pane selections ............... 274
9.4 TLlNK32 warnings ..................... 153 19.1 Zoom commands ..................... 292
10.1 BRCC (Borland resource compiler) ...... 162 22.1 Font size options ...................... 327
10.2 RLINK switches ...................... 163 22.2 Character options ..................... 328
10.3 BRC switches ......................... 164 22.3 Font header options ................... 329
11.1 IMPLIB options ....................... 168 B.1 Predefined BWCC button controls ....... 399
11.2 TLIB options ......................... 171 B.2 Bitmap offsets ......................... 399

viii

Figures
1.1 Elements ofthe IDE ..................... 10
1.2 Viewing classes in an application ......... 17
1.3 Symbol declaration window .............. 18
1.4 Viewing globals ......................... 18
2.1 The project tree ......................... 26
5.1 The ClassExpert window ................. 93
6.1 The Watch window ..................... 110
6.2 The Watch Properties dialog box ......... 111
6.3 The Breakpoint window ................ 116
6.4 The Breakpoint Properties dialog box ..... 117
14.1 Project window showing respurces by file .203
15.1 A typical dialog box ................... 221
15.2 Dialog editor with empty dialog box .... 222
15.3 Tools palette .......................... 228
15.4 Dialog box coordinates ................ 233
15.5 Control order options .................. 239

15.6 Size Controls dialog box ............... 240
15.7 Edit text control ...................... 246
15.8 Combo box from Open File dialog box ... 250
16.1 Sample menu ......................... 268
18.1 String editor with string table entries .... 282
18.2 String editor with four strings defined ... 287
19.1 Bitmap editor Tools palette ............. 291
19.2 16-color Colors palette ................. 299
19.3 16-color palette index .................. 302
19.4 Aligning text . . . . . . . . . . . . . . . . . . . . . . . . . 304
20.1 Icon window ......................... 312
20.2 Calculator before adding drop shading .. 315
20.3 Calculator with shading ............... 316
20.4 Finished Home Budget icon ............ 317
B.1 Dialog box with Borland controls ........ 396

ix

x

Introduction
See the Roadmap for
information on the
manuals and online
Help included with
Borland C++.

Borland C++ is a powerful professional tool for creating and maintaining
DOS, Windows, Win32s, and Windows NT applications using the C and
C++ languages. Part 1 of this manual introduces you to the Integrated
Development Environment (IDE) and the command-line tools needed to
create applications. Part 2 teaches you how to use Resource Workshop to
build Windows resources for your applications.

Whats new in Borland C++
Borland C++ 4.0 has many more features than previous releases. The
following is a brief list of major additions and changes:
• The 32-bit compiler and tools generate 32-bit targets for Win32s and
Windows NT .
• You can generate DOS programs from the Windows IDE.
• The IDE has a graphical integrated debugger for debugging 16-bit
Windows applications.
• The IDE has an enhanced editor that lets you record keystroke macros,
work in multiple panes in one editor window, and search for text using
regular expressions. You can configure the editor to use Brief or Epsilon
keystrokes or you can create your own keystrokes.
• The right mouse button brings up SpeedMenus that list commands
specific to the object you click. For example, some common editing
commands are on the SpeedMenu of all editor windows. (To access old
functions of the right mouse button, press Ctrl+click right mouse button.)
• The IDE has a new multiple-target project manager that visually shows
file dependencies and lets you manage more than one program.
• The IDE has a new multiple-window ObjectBrowser that displays class
relationships.
• Using AppExpert you can quickly generate ObjectWindows 2.0 Windows
programs. ClassExpert helps you modify and organize your AppExpert
application.

Introduction

Manual conventions
This manual uses special fonts and icons as follows:
Monospaced type

. This

font represents text that you type or onscreen text.

Italics

Italics are used to emphasize certain words and indicate variable names
(identifiers), C++ function names, class names, and structure names.

Bold

Reserved keywC?rds words, format specifiers, and command-line options
appear bold.

Keycap

ALL CAPS
Menu IChoice

This font represents a particular key you should press-for example, "Press
Del to erase the character."
All caps are used to represent disk directories, file names, and application
names.
Rather than use the phrase"choose the Save command from the File
menu," this manual uses the convention"choose File ISave".
16-bit Windows

32-bit Windows

Contacting Borland
Borland offers a variety of services to help you with your questions. Be sure
to send in the registration card: registered owners are entitled to receive
technical support and information on upgrades and supplementary
products. North American customers ca~ register by phone 24 hours a day
by calling 1-800-845-0147. Borland provides the following convenient
sources of technical information.
Service

How to contact

Available

Cost

Description

Tech Fax

1-800-822-4269
(voice)

24 hours daily

Free

Sends technical information to your fax
machine. You can request up to 3
documents per call. Requires a TouchTone phone.

Automated support

408-431-5250
(modem)

24 hours daily'

The cost of
the phone call

Requires a Touch-Tone phone or
modem.

2

Borland C++ Users Guide

Online Services
Borland Download
BBS

408-431-5096

24 hours daily

The cost of
the phone call

Sends sample files, applications, and
technical information via your modem.
Requires a modem (up to 9600 baud);
no special setup required.

CompuServe online
service

Type GO BORLAND.
Address messages to
Sysop or All.

24 hours daily;
1-working-day
response time.

Your online
charges

Sends answers to technical questions
via your modem. Messages are public
unless sent by CompuServe's private
,mail system.

BIX online
service

Type JOIN BORLAND.
Address messages to
Sysop or All.

24 hours daily;
1-working-day
response time.

Your online
charges

Sends answers to technical questions
via your modem. Messages are public
unless sent by BIX's private mail
system.

GEnie online
service

Type BORLAND.
Address messages to
Sysop or All.

24 hours daily;
1-working-day
response time.

Your online
charges

Sends answers to technical questions
via your modem. Messages are public
unless sent by GEnie's private mail
system.

For additional details on these and other Borland services, please refer to
the Borland Support and Services Guide that was included with your product.

Introduction

3

4

Borland C++ Users Guide

p

A

R

T

Using Borland C++ for Windows
This section of the User's Guide describes how to install and use Borland
C++. It teaches you how to use the components in the Integrated
Development Environment (IDE), including the integrated debugger, the
browser, AppExpert, ClassExpert, and the project manager. It also
documents the command-lines tools, including the compiler, linker,
librarian, and MAKE. Borland C++,
• Integrates development of DOS, Windows, Win32s, and Windows NT
applications. You can build more than one application type from a single
project file.
• Creates ObjectWindows applications quickly and easily using
AppExpert. After you create an application, ClassExpert helps you
maintain that application by tracking classes and events and works with
Resource Workshop to manage the resources you create and use in your
application.
• Helps you debug and browse your applications without having to use a
separa te debugger.
• Contains a customizable editor. You can use the keyboard shortcuts
provided with Borland C++, or you can customize your own.
This section also describes two Windows programs that help you debug
your applications: WinSight and WinSpector.
There are two online files for Borland C++ that contain additional material
not in the manuals or online Help:
• INSTALL.TXT
• UTILS.TXT

Contains complete installation information for both
floppy and CD ROM installations.
Describes command-line tools and utilitiesnotfoimd
in the manuals or online Help.

c

H

A

p

T

E

R

1

Getting started
Borland C++ is a development package containing Windows tools,
command-line tools, and libraries that help you develop applications for
DOS, Windows, Win32s, and Windows NT. This chapter gives you a .
working description of the Borland C++ product-the IDE, project
manager, AppExpert, tools, and utilities.
Read this chapter to learn how to
•
•
•
•

Install and configure Borland C++
Use the editor
Use syntax highlighting for code
Use the SpeedBar

• Use the Message window
• Browse your code
• Start and use other tools from the
IDE

Other utilities and command-line tools are described briefly in this chapter.
For information on other parts of the Borland C++ product, see the
Roadmap, which points you to topics in the documentation.

Installing Borland C++
Borland C++ contains both DOS and Windows applications. Before you can
install Borland C++, make sure your computer has the minimum hardware
and software requirements.
Hardware and
software
requirements

To use Borland C++, your computer must have:

Chapter 1, Getting started

• DOS version 4.01 or higher
• Windows 3.1 or higher running in 386-enhanced mode
• A hard disk with 40 MB of available disk space for a normal installation
(80MB for a full installation)
,
• A 1.44 floppy drive or CD ROM (for installation)
• At least 4MB of extended memory
• A Windows-compatible mouse

7

Although the following items aren't required, they can greatly increase
your computer's performance:
• 8MB RAM .
• An 80x87 math coprocessor (if you're writing programs that use
floating-point math). Borland C++ emulates a math chip if you don't
have one.
'
Installation steps

If you use a diskcompression utility,
you should read
INSTALL.TXT before
you install Borland
CH.

The Borland C++ install program installs the Borland C++ product (the
IDE, command-line tools, ObjectWindows, and Turbo Debuggers) and it
installs Win32s (Win32s lets you run 32-bit programs under 16-bit
Windows). The installation program works under Windows, Win32s, and
Windows NT; however, not all programs run under Windows NT.
Before you install, make sure your computer meets or exceeds the
hardware and software requirements. If you need more information about
installing Borland C++, read the online file INSTALL.TXT, located on Disk,
1 (this file isn't compressed, so you can view it using any text editor).
The installation instructions for floppy and CD are basically the same, but
you should read the INSTALL.TXT file or the CD liner notes if you're
installing from CD ROM.
To install Borland C++ from floppy disks,
1. Put Disk 1 in your floppy drive (usually A or B).
2. Start Windows and choose File I Run from the Program Manager.
3. Type a: \install (or b: \install if your floppy is in drive B), then press
Enter. The install dialog box appears. At the bottom of this dialog box
you'll see the amount of hard~disk space needed for'a complete install
(Target Requirements). You'll also see the amount of disk space
available on your machine. Make sure you have more than enough
room available for installation before continuing. If your computer uses
disk compression, read the INSTALL.TXT file; you might need more
room than what is listed as available.
4. Click the Customize BC4.0 Installation button if you want to select only
specific files for installation. Another dialog box appears with buttons
and descriptions for areas of the product. Click a button for an area you
want to customize. A dialog box for that area appears where you can
uncheck files you don't want installed (the default installation installs
all files to your machine). Click OK and repeat this process for any areas
you want to customize. Click OK to return to the first install dialog box.

8

Borland C++ User's Guide

5. The install program lists default directories where it will install files.
Type another path only if you want Borland C++ installed to a different
directory .
• Borland C++ destination directory is the main directory under which
all other files are installed (by default the directory is C: \BC4) .
• Borland C++ Configuration File directory is where the installation

program puts the Borland C++ configuration files (usually
C: \BC4 \BIN).

6. By default, the installation program creates a Windows group where it
places all the Borland C++ icons. If you don't want to create a group,
uncheck Create Borland C++ Group.
7., Win32s also installs by default. If you don't want Win32s, uncheck this
option. Win32s is required for running 32-bit applications.
8. Check LAN Windows Configuration only if you're inst~lling on a
machine with LAN Windows.
9. Click Install to begin copying files to your machine. When installation is
complete, you can read the README.TXT file. This file contains lastminute changes to the product, the documentation, and the online Help.
For a description of all the icons that install creates, read the file
INSTALL.TXT located on disk one and C:\BC4.
After you install, make sure your CONFIG.SYS file has FILES and BUFFERS
equal to 40 or more (see your DOS documentation for information on the
CONFIG.SYS file).
The install makes the follow~g changes to existing files on your machine:
• AUTOEXEC.BAT now includes the path to Borland C++ (c: \BC4 \BIN by
default).
• WIN.lNI includes a section [BCW4. 0 INSTALL] that is used by the TASM
install program to locate where Borland C++ is installed on your
machine. Also, inthe [EXTENSIONS] section, the extension IDE is associated
with the IDE (BCW.EXE).
• SYSTEM.lNI includes two device lines:
device: c:\bc4\bin\tddebug.386
device: c:\bc4\bin\windpmi.386
• If you run under Windows NT, NTCMDPROMPT is added to CONFIG.NT.
FILELIST.TXT lists every file that ships with Borland C++. If you need to
free disk space, read this file before. you delete any Borland C++ files.

Chapter 1, Getting started

9

Starting Borland
C++

Borland
c++

To start the IDE, double-click the Borland C++ icon in Windows (shown at
left). The IDE lets you write, edit, compile, link, debug, and manage your
programming projects. The IDE has
• An editor and browser described in this chapter
• A project manager, described in Chapter 2, "Using the project manager"
• A debugger, described in Chapter 6, "Using the integrated debugger"
Figure 1.1 shows some of the components of the IDE.

Figure 1.1
Elements of the IDE
SpeedS

Editor
window

Project
window

-r.f--l~IJeE~aMenu

[.epp) code size=594 lines=274 dala size=99
.. \ .. \ .. \inelude\windows.h [AuloDepend)
.. \ .. \ .. \inelude\sldlib.h [AuloDepend)
" \ .. \ .. \inelude\_dels.h [AuloDepend)
.. \ .. \ .. \inelude\slring.h [AuloDepend)
.. \ .. \ .. \inelude\loeale.h [AuloD epend)
~ whello [.Ie)
&) whello [.del)

Status' bar

The IDE has context-sensitive SpeedMenus that let you modify objects
quickly. To view a SpeedMenu, right-click in a window (the window must
be selected first with the left mouse button) or on an item in a window, or
press Alt+F10 (the SpeedMenu changes depending on what is selected). For
example, to jump to a line in an editor window, right-click in the editor
window, choose Go to line, then type the number for the line you want to
view. The menu item "Go to line" appears only when an editor window is
selected. If you open a SpeedMenu in a project window, you'll view a
completely different set of menu items.
The SpeedBar also changes depending on what window you select. There is
a configurable SpeedBar for the editor, browser, debugger, project manager,
message window, desktop, and ClassExpert (to configure a SpeedBar, see

.1
I

10

Bar/and C++ Users Guide

I

page 12). When you place the mouse pointer over a button on the SpeedBar,
a help line describing the button appears in the status line at the bottom of
the IDE.
Some of the buttons on the SpeedBar are dimmed at times. This means that
the command the button represents isn't available to you in the current
context. For example, if an edit window is open, the Paste Text from
Clipboard button is dimmed if there is no text in the Clipboard.
Getting Help

The Borland C++ Help system gives you online access to detailed
information about Borland C++. You can find most product information in
both the manuals and the online Help. The following topics, however, are
only in online Help:
• IDE menu commands
• Editor KEYMAPPER

• Run-time library example code
• Windows API

To get online Help:

I

~:'

• In the IDE, choose Help from the menu or press F1.
• In dialog boxes, click the Help button or press F1.
• For menu commands, select the menu command and then press F1.
I

Configuring the IDE
You can configure the IDE to do tasks automatically (such as saving a
backup of files in editor windows) or to handle events. This section
describes what you can configure.
The Options I Environment dialog box lets you configure the editor,
browser, debugger, project windows, and other elements of the IDE (these
options are saved in a file called BCCONFIG.BCW).

You can also press +
or - to expand and
collapse the list of
options.

To ope!\ the Environment Options dialog box, choose Options I Environment. The dialog box appears with a, list of topics on the left. Some topics
contain subtopics under them. For example, the Editor topic has subtopics
called Options, File, and Display. When a topic has subtopics that aren't
displayed, the topic contains a + next to the name. When you click a topic's
+ sign, its subtopics appear under it and the + turns to a - (you can then
click the - to collapse the list). Topics that don't contain subtopics appear
with a dot next to their name. When you click a topic, its characteristics
appear to the right in the dialog box.

Chapter 1, Getting started

. 11

Not all Options I Environment topics are discussed in this chapter. See the
online Help (click the Help button in the dialog box) for complete reference
material on all topics and options.
Some topics associated with tasks or parts of the IDE are discussed
elsewhere in this manual (for example, project options are discussed in
Chapter 2). Check the index of this manual for entries on specific topics.
Changing the
SpeedBars

The IDE has SpeedBars for Editor, Browser, Debugger, Project, Message,
Desktop, and ClassExpert windows. When you select one of these types of
windows, the corresponding SpeedBar appears. You can customize each of
the SpeedBars so that they include only the buttons you need.
To add or delete buttons from any of the SpeedBars,
1. Choose Options I Environment from the 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 choose how you want the -SpeedBar to appear
(top or bottom of the IDE), and how you want it to behave (check Use
flyby,help to view help hints on the status line when you pass the
mouse pointer over a button).
3. Choose Customize, the topic under SpeedBar. The options on the right
display information about the SpeedBars.
, 4. Choose the type of SpeedBar you want to modify (Editor, Browser,
Debugger, Project, Message, Desktop, or ClassExpert) from the Window
drop list.
'
The column on the left (Available Buttons) displays all the available
(unused) buttons with names next to them that describe the button's
function. The column on the right (Active Buttons) displays only the
buttons for the selected SpeedBar.
5. To add a'button, double-click the button icon in the Available Buttons
list, or select it and click the right-pointing arrow. The button moves to
the Active Buttons list.
6. 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, use the up and down
arrows. The selected button in the Active Buttons list moves up or down
the list (the top button appears on the far left of the SpeedBar; the last
button in the list appears on the far right).

12

Borland C++ Users Guide

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,
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.
Separators put space between two buttons. You can add separators to any
SpeedBar by selecting a button from the Active Buttons list then clicking
the Separator button. The separator is added before the selected button.
Setting IDE
preferences

Preferences let you customize what you want saved automatically and how
you want some windows to work.
To set preferences,
1. Choose Options I Environment I Preferences.
2. Check and uncheck the options you want. See the online Help (press the
Help button) for an explanation of each option.
3. Choose OK.

Saving your IDE
settings

The IDE automatically saves information when you exit the IDE, build or
make a project, use a transfer tool, run the integrated debugger, or close,
open, or save a project. You can control the automatic saving by choosing
Preferences from the Environment Options dialog box (choose Options I
Environment from the main menu) and setting options for automatic save.
To save your settings manually,
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 flbout 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.

Chapter 1, Getting started

13

Using the Editor
You can open up to
32 editor windows in
the IDE.

Editor windows are where you create and edit your program code. When
you're editing a file, the IDE status bar displays the line number and
character position of the cursor. For example, if the cursor is on the first line
and first character of an editor 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 IDE status bar
also indicates whether the cursor will overwrite or insert characters (press
Insert to toggle this option) and displays the word Modified if you've made
any changes to the file in the selected edit window.
The editor lets you undo multiple edits by choosing Edit I Undo or pressing
Alt+Backspace. For example, if you delete a line of text, then paste some text,
you can undo these edits: the pasting, which was the last edit, is undone
first, then the deletion. You can set the number of undo actions allowed by
choosing Options I Environment I Editor I Options and setting the Undo
Limit.

Configuring the
IDE editor

The .CKB files also
configure other
windows in the IDE.
See the online Help
for more information.

Syntax
highlighting

You can configure the editor so that it looks and behaves similar to other
editors (like Brief and Epsilon). The IDE editor uses keyboard mapping files
(.CKB) that set the keyboard shortcuts for the editor (these files also change
the keystrokes for other windows).
'
You can use one of the four default .CKE files by choosing Options I
Environment I Editor and clicking a SpeedSetting (Default keymapping,
IDE classic, BRIEF emulation, or Epsilon). To learn how to edit or create
your own .CKB file, see the online Help (search on "Keymapper").
Syntax Highlighting lets you define a color and font attribute (like bold) for
certain elements of code. For example, you could display comments in blue
and strings in red. Syntax Highlighting is on by default. To turn off
highlighting,
1. Choose Options I Environment I Syntax Highlighting.
2. Uncheck Use Syntax Highlighting.
Syntax Highlighting works on files whose extension is listed in the Syntax
Extensions list (.CPP, .C, .H, and .HPP by default). You can add or delete
any extension from this list, but you must separate extensions with
semicolons.
'
The Syntax Highlighting section displays the default color scheme and four
predefined color settings (buttons) you can use.

14

Borland C++ Users Guide

To use a predefined color scheme,
1. Choose Options I Environment ISyntax Highlighting.

2. Choose one of the four color schemes by clicking its button; the sample
code changes to use the color scheme you select. You can use a color
scheme as a starting point for customizing syntax highlighting.
To manually select syntax highlighting colors,
1. Choose Options IEnvironment ISyntax Highlighting ICustomize.

2.

3.

4.
5.
6.

Elements and sample code appear on the top right of the Environment
Options dialog box.
Select an element you want to modify from the list of elements (for
example, 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. The sample code uses the font selected in the
Editor IDisplay section of the Environment Options dialog box.
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.
Choose an Attribute such as bold, if you want.
You can check Default FG (foreground) or BG (background) to use the
Windows default colors for an element.
Repeat steps 2-4 for the elements you want to modify.

Working with the Message window
You can customize
some of the
functionality of
message windows by
using Preferences in
the Environment
Options dialog box.

The Message window displays errors and warnings when you compile
programs. When you select a message in the Message window, the editor
places the cursor at the spot in your code where the error or warning
occurred. If the file containing the error isn't loaded in an editor window,
press Spacebar to load it (you can also press AIt+F10 and choose View source
from the SpeedMenu). The message window remains selected so you can
move from message to message.
To view the code associated with an error or a warning, either select the
message in the message window and press Enter, double-click the message,
or press AIt+F10 and choose Edit source from the SpeedMenu. The cursor
appears on the line and column in your source code where the error is most

Chapter 1, Getting started

15

likely to have occurred (the message window moves to the background).
Use AIt+F7 to move to the next error message or Alt+FB to go to the previous
error message.
You can also cursor through messages in the message window. As you
select a message, the cursor in the editor window moves to the place where
the error occurred (this is called automatic error tracking). Automatic error
tracking works only if theiile containing the errors is displayed in an editor
window. If the next message you select references another source file (not
the one in the current editor window), you must select the editor window
that displays the source file associated with the message before you can
continue automatic error tracking.
You can clear the message window by choosing Remove all messages from
the message-window SpeedMenu (right-click or press Alt+F10 to view the
SpeedMenu).

Browsing through your code
The browser lets you view the object hierarchies, classes, functions,
variables, types, and constants 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 and
inherits.
• List the variables your program defines, then select one and view its
declaration, list all references to it in your program, or edit its declaration
in your source code.
Before you use the browser, be sure to set these options in the Project
Options dialog box (choose Options IProject) and compile your application:
• Choose Compiler IDebugging and check Debug information in OBJs
• Choose Compiler IDebugging and check Browser reference information
in OBJs
• Choose Linker IGeneral and check Include debug information.
The Browser has a
customizable
SpeedBar (see page
12 for more
information on
customizing
SpeedBars).

16

To start the browser, choose Search IBrowse Symbol, View IClasses, or
View IGlobals. You can also place your cursor on a symbol in your code
and choose Search IBrowse symbol to bring up the browser. If the program
in the current editor window hasn't been compiled yet, you must compile
and link your program with debugging information before you can use the
browser. If you try to browse a class definition (or any symbol that doesn't
have symbolic debug information), you'll get an error message.

Borland C++ Users Guide

You can set several browser options using the Environment Options dialog
box. Choose Options IEnviro.nment, click the Browser topic and select the
options you want to use. Single window means you can only have only one
browser window up at a time; Multiple windows opens a' new browser
window each time you perform a browsing action (such as choosing View I
Globals from the main menu). Visible symbols are described on page 18.
Browsing through
objects (class
overview)

Choose View IClasses to see the "big picture," the object hierarchies in your
application, as well as the small details. When you choose View IClasses,
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 ancestor-descendant relationships of the currently
selected object more clearly. Figure 1.2 shows the structure of the WHELLO
application.

Figure 1.2
Viewing classes in an
application

To see more information on a particular object, double-click it. If you aren't
using a mouse, select the object by using your arrow keys and press Enter.
Filters

You can also check
the Browser options
in the Environment
Options dialog box to
select the type of
symbols, but you
must set these
options before
opening browser
windows.

When you browse a particular symbol, the same letters that identify the
symbol appear in a Filters matrix at the bottom of the browser window.
You can use filters to select the type of symbols you want to see listed. (See
Table 1.1 for a list of letters and their meaning.)
The Filters matrix has a column for each letter. Click the top or bottom row
to move the letter (a letter in the top row means the browser shows
symbols with that identification; a letter on the bottom means the browser
excludes symbols with that identification).
To restrict views of a particular type of symbol, click the bottom cell of the
letter's column as shown at left. For example, to remove all the variables
displayed in the currently selected object, click the bottom cell in the vcolumn.
In some cases more than one letter appears next to a symbol. The second

letter appears just after the letter identifying the type of symbol and further
describes the symbol. See Table 1.1 for a list of filter identifiers.

Chapter 1, Getting started

17

Viewing
declarations of
listed symbols

Use one of these methods to see the declaration of a particular symbol
displayed in a list:
• Double-click the symbol.
• Select the symbol and press Enter.
• Select the symbol, press Alt+F10 to view the SpeedMenu, then choose
Browse Symbol.
The symbol declaration appears in a window, as shown in Figure 1.3.

Figure 1.3
Symbol declaration
window

Browsing through
global symbols

Choose View IGlobals to open a window that lists every global symbol in
your application in alphabetical order. The browser lists the symbols (the
functions, variables, and so on) used in the object. Figure 1.4 shows the
globals for the WHELLO program.

Figure 1.4
Viewing globals

One or more letters appear to the left of each symbol in the object. The
,letters describe what kind of symbol it is. You can filter out symbols using
the filter list at the bottom of the browser window. See the previous section
"Filters" for more information.

Borland C++ Users Guide '

Table 1.1
Letter symbols in the
Browser

Letter
F
T
V
C

Functions
Types
Variables
Integral constants
.Debuggable
Inherited from an ancestor
Virtual method

?
v
You can also type
regular expressions
for searching (for
example, you can use
?, * and t).

Symbol

To get more information on a particular symbol, either click the symbol or
use your cursor keys to select it. A 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's name. As you type, the highlight
bar in the list box moves to a symbol that matches the typed characters.
You can view the symbol declaration by selecting the symbol and pressing
Enter. See the previous section, "Viewing declarations of listed symbols," for
more information.

Using regular
expressions in the
browser
Table 1.2
Browser search
expressions

You can use expressions in the search box in some browser windows. See
Table 1.2 for a list of the symbols allowed.

Character

Function
Matches one of any character.
Matches zero or more of the previous character. For example,
* is an error because there is no previous character
fo* matches anything starting with an "f"
fo*x matches "fx", "fox","fooox"

Chapter 1, Getting started

t

Matches one or more of the previous character. For example,
t is an error
fot matches anything starting with "fo"
fotx matches "fox", '1000x"

?

Matches zero or one of the previous character. For example,
? is an error
f o? matches anything starting with "f"
fo?x matches only "fx" or "fox"

19

Browsing
symbols in your
code

You can also browse any symbol'in your code without viewing object
hierarchies or lists of symbols first. Choose from these methods:
• Highlight the symbol in your code and choose Search I Browse Symbol.
• Click the right mouse button or press Alt+F10when an editor window is
selected to display the SpeedMenu, then choose Browse Symbol.

Using command-line tools
Borland C++ contains several command-line tools that let you do the same
tasks you can do in the IDE. Borland C++ includes a command-line
compiler, a linker, a resource ~ompiler, a librarian, a project builder (called
MAKE), and other tools. Most of these tools are documented in this
manual. Some are documented in online files. All tools are documented in
the online Help.
You can use either the IDE or the command-line tools, because they
produce the same results, but you might choose to 'use the command-line
tools if you program using a DOS editor such as Brief. Here's a list of the
command-line tools, what they do, and where they are documented:
• BCC.EXE and BCC32.EXE are the 16-bit and 32-bit compilers. They are
documented in Chapter 3.
• TLINK.EXE and TLINK32.EXE link .OB] files and .LIB files to form .EXEs
and .DLLs. They are documented in Chapter 9.
• IMPLIB.EXE, and TLIB.EXE help you work with and create libraries.
They are described in Chapter 11.
• HC31.EXE compiles files for online Help and creates the .HLP file that
most Windows applications can use. It is documented in the online Help.
• BRCC.EXE, BRCC32.EXE, BRC.EXE, BRC32.EXE, and RLINK.EXE are
resource tools that compile resources for your applications. They are
described in Chapter 10.
• MAKE.EXE and MAKER.EXE help manage your projects by building
only the files that have changed since the last build. They are
documented in Chapter 12.
DPMI and the
command-line
tools

The command-line compiler uses DPMI (Dos Protected Mode Interface) to
run in protected mode on 286, 386, i486, or Pentium machines with at least
640K conventional RAM and at least 1MB extended memory.
Although Borland C++ runs in protected mode, it still generates
applications that run in real mode. The advantage to using Borland C++ in

20

Borland C++ Users Guide

protected mode is that the compiler has much more room to run than if you
were running it in real mode, so it can compile larger projects faster and
without extensive disk-swapping.
If you get "Out of Memory" errors from DOS (not running DOS from
Windows) when running the 32-bit command-line tools, create a swap file
with the MAKESWAP utility. MAKE SWAP takes the size of the file to
create in KBytes, for example:

Memory and
MAKESWAP,EXE

MAKESWAP 12000

creates a 12MB swap file called EDPMI.SWP in the current directory, which
the command-line tools use when they need additional memory. To ~et up
a swap file, use the DPMIMEM environment variable at the DOS prompt or
add this line to your AUTOEXEC.BAT file:

MAKESWAP applies
to DOS only, not to
DOS boxes opened
under Windows. See
the online file
INSTALL.TXT for
information on
running the tools from
DOS boxes.

set DPMIMEM=SWAPFILE \EDPMI.SWP

You must clear this environment variable before running Borland C++ 3.1
command-line tools or other 16-bit DPMI-hosted executables, suchas
Paradox. To clear the variable, type at the DOS prompt:
set DPMIMEM=

Borland C++ protected-mode applications (such as BCC and BCC32) use
the run-time managers RTM.EXE and 32RTM.EXE. The tools that use the
run-time manager first load the run-time manager, then do their work, and
then unload the run-time manager. If you're doing lots of calls to 32-bit
command-line tools that use the run-time manager (perhaps from a
makefile), you could speed up the process by loading the run-time manager
once, then calling the tools. To load the run-time manger, type 32RTM at the
command line. To unload the run-time manager, type 32RTM -u.

The run-time
manager and
tools

Controlling the
memory RTM uses

By default, the run-time manager consumes all available memory for itself
when it loads. It then allocates memory to its clients when they request it
through the memory manager API routines.
To control how much memory the run-time manager can use, at the DOS
command line add the RTM environment variable to your system's DOS
environment. Here is the syntax:
SET RTM=(option nnnnl

Chapter 1, Getting started

21

The following table lists the options you can use, where nnnn can be a
decimal number or a hex number in the form of xAB54 or xab54.
Table 1.3
Environment
variables for RTMs
memory allocation

Option

Description

EXTLEAVE nnnn

Always leave at least nnnn kilobytes of extended memory
available. The default value is 640K.

EXTMAX nnnn

Don't allocate more than nnnn kilobytes of extended memory. The
default value is 4 gigabytes. In Windows, the default value is onehalf the available memory.

EXTMIN nnnn

If fewer than nnnn kilobytes are. available after applying EXTMAX
and EXTLEAVE limits, terminate with an Out of Memory message.
The default value is zero.

REALLEAVE nnnn

Always leave at least nnnn paragraphs of real memory available.
The default value is 64K or 4096 paragraphs.

REALMAX nnnn

Don't allocate more than nnnn paragraphs of real memory. The
default value is 1 megabyte or 65,535 paragraphs.

REALMIN nnnn

If fewer than nnnn paragraphs are available after applying
REALMAX and REALLEAVE, terminate with an Out of Memory
message. The default value is zero.

Running other programs from the IDE
You can run other programs, tools, and utilities without leaving the IDE.
The IDE lets you run Turbo Debugger, Resource Workshop, GREP,
WinSight, WinSpector, and Keymapper. To run a program from the IDE,
choose Tools I ProgramName (for example, Tools I GREP).
To add programs to the Tools menu,
1. Choose Options I Tools. The Tools dialog box appears, listing Tools,
Viewers, and Translators.
2. Click New. If you want to add an existing tool (listed in the Tools dialog
box), click Edit.
3. Type the name of the program, its path, and any command-line options
you always want to pass to it. (You can use transfer macros on this
command line; see the online Help for more information.)
4. Type Menu text. This text can appear on SpeedMenus and on the Tools
main menu. If you want to assign a shortcut key to your menu text,
precede a letter with an ampersand-this letter will appear underlined
in the menu. For example, the shortcut key for File is F. In the menu

22

Borland C++ Users Guide

text, File would appear as &File. If you want an ampersand in your
menu text, use two ampersands (&&Test appears as &Test in the menu).
5. Type any help text you want. Help hint text appears in the status line
when you select the menu item.
6. Click Advanced. The Tool Advanced Options dialog box appears.
7. Check Translator if the program uses one file type to create another file
(like a compiler). Check Viewer if the program is used to view a file (like .
an editor).
8. Check Place on Tools menu. Check Place on SpeedMenu if you want the
program to appear on the SpeedMenu for the project window (see
Chapter 2 for more information on projects).
9. If your program is a Translator, type an extension for the files you want
to associate with the program. For example, BeC is a translator for.C
and .CPP files, so Translate From would show . c; . cpp:. Use a semicolon
to separate file extensions and a colon to designate the end of the list.
10. Type an extension for the resulting translated file. For example, Bee
converts .CPP files to .OBJ, so .obj appears in the Translate to box.
11. Choose OK with all the open dialog boxes,12. Choose Tool from the main menu to see that your program name was
added correctly to the Tool menu.

Chapter 1, Getting started

23

24

Borland C++ Users Guide

c

H

A

p

T

E

R

2

Using the project manager
Borland C++ 4.0 features a new project manager with expanded
functionality. This chapter describes how to use Borland C++ to build
applications and projects from your source code files and how to use .PRJ
files from previous versions of the project manager. If you have used earlier
versions of the project manager, read this chapter carefully.
The project manager handles applications that are built from many
components. Applications can have several source modules that must be
compiled with different options. For example, to create an .EXE, resource
scripts must be compiled with the resource compiler, import libraries must
be created, and .OBJs must be linked. ,

What is project management?
The project manager
reads .PRJ files from
previous releases.

The project manager organizes and updates complex applications by
keeping track of all the files and their interdependencies in a project file
with the extension .IDE.
Using the project manager is an efficient way to build projects because it
only translates the files that have changed since the last build of the project.
The term translate refers to using one file type to create another. For
example, the C++ compiler is a translator for .CPP files because it uses
them to generate .OBJ files (see page 40 for more information on
transla tors).
A project can be viewed as a list of files dependent on each other. Some files
are source code you create; others, like .OBJ files, .EXE files, and .DLL files
are produced by the compiler, linker, or other tools and are dependent on
your source code files.

Chapter 2, Using the project manager

25

In the project manager, dependencies are shown graphically (this is the
project tree). On each level, the files shown in a project are dependent on
the files indented beneath them, as shown in Figure 2.1.
Figure 2.1
The project tree
Project node
Target node----j--~B sample [.eKe) 
[j cOwl [.obi) 
Node ---t[f-.--- II sample [.epp) 
II sample [.re) 
II sample [.def) 
Run-time_fl-+-_ [j bidsi [.lib) 
node
[j owlwi [.lib) 
[j import [.lib] 
[j crUd" [.lib) <.Binlnclude>

In the project tree, different nodes have different icons.
• A project node represents the entire project. All the files used to build
that project appear under it (a project node is similar to a symbolic target
in a makefile). A project can contain many target nodes. For example,
you might have one project that you use to build two applications and a
DLL (three targets).
• A target node represents a file that is created when its dependent nodes
are built (a target is usually the .EXE or .DLL that you're creating from
source code). You can collapse a target node so that the dependent nodes
aren't displayed.
• A node generally refers to a file used to build a target. Files such as .C,
.CPP, .H, and .RC are source files associated with nodes.
• A run-time node refers to common files used at run time, such as startup
code (.LIB files). You can choose not to view these files (see page 29).

Creating a project
To create a project,
1. Choose Project I New project. Type a path and a name (eight characters
or less) for the project, then press Tab. You can also use the Browse

button to select a path to the project file.
2. Type a name for the first target in your project. This is usually the name
of the program you want to create (the .EXE or .DLL).

26

Borland C++ Users Guide

You can use
TargetExpert to
change these
attributes.

3. Choose a target type:
• Application is a normal.EXE file.
• Dynamic Library is a .DLL file.
• EasyWin is.a character-mode application that runs under Windows .
.• Static Library is a .LIB file.
• Import Library is a .LIB file.
• Windows Help is a help file (.HLP) that you usually access from a
Windows application (.EXE).
4. Choose a platform for your target:
•
•
•
•

Windows 3.x is a 16-bit Windows application.
Win32 is a 32-bit Windows NT application.
DOS Standard is a 16-bit DOS application.
DOS Overlay is a 16-bit DOS application that uses overlays.

5. If your application is for DOS, check
See the DOS
Reference for more
information on these
libraries.

•
•
•
•
•

•
•
•
•
•

Floating point to link in FP87.lib.
Emulation to link in EMU.LIB.
No Math to link in the DOS math libraries.
Alternate startup to link in COFx.OBJ, which makes SS==DS for all
memory models.
Check any standard libraries you want to use in your application.
Some libraries are checked by default when you choose a target type
(you can't uncheck some of these because they are required for the
type of target you're creating). If dynamic and static libraries exist,
you can choose which type you want to use (Dynamic is usually the
default).
OWL uses th~ ObjectWindows libraries. See the Object Windows
Programmer's Guide for more information.
Class Library uses the Borland container class libraries discussed in
the Programmer's Guide.
Runtime uses the run-time libraries listed in the Library Reference.
BWCC uses the Borland Windows Custom Control libraries. See
Appendix B..
BGI uses the Borland Graphics Interface (available for DOS
applications only). See the online file UTILS.TXT.

6. Check Diagnostic if you want to use a diagnostic version of the libraries
(this is available for Class Libraries and ObjectWindows; see the

Chapter 2, Using the project manager

27

ObjectWindows documentation for more information on diagnostic
versions of its libraries).
7. Check Multithread if you want to use the multithread version of the
run-time library. Multithread is available only if your platform is
Win32.
8. Choose a memory model for your target (Target Model). Models change
depending on the target type.
.
9. Click OK to create the project. A graphical representation of your
project appears in a project window. You can change the target
attributes you set in steps 2-8 by using the project manager's
SpeedMenu (right-click a node or press AIt+F10).
The project manager creates a target with one or more dependents-the
default dependents depend on the target type. To view which dependents
are added for a target type, click the Advanced button in the New Project
dialog box. You can select other dependent nodes, then click OK. For DOS
application, you can select how you want the stack and data segments to
work.
After you create the initial target for a project, you can add, delete; or
rearrange nodes and targets to your project. See page 31 for more
information on editing projects.
Creating a
multiple-target
project

To include a DLL for
an application in a
project, place the DLL
node under the .EXE
node.

Creating multiple-target projects is similar to creating projects with one
target:
1. Create a project using the steps described on page 26.
2. Choose Project I New target to add a second target to your application.
The New Target dialog box appears.
3. Type a name for the second target and choose a target type (Standard is
the default). Choose OK. The project manager adds a new target to your
project just as it does for the first target in a project.

To view a sample project with two targets, open the file MULTITRG.IDE in
the EXAMPLES\IDE\MULTITRG directory. This project file builds two
versions of the WHELLO program (one that is 16-bit and one that is 32-bit).
The project file contains a text file that describes how to use two or more
targets in one project file.
With more than one target in a project, you can choose to build a single
target, multiple targets, or the whole project. See page 30 for information on
building projects.

28

Borland C++ Users Guide

Converting old
projects

The project manager for this release can load and use projects from
previous versions of Borland C++ for Windows. Choose Project I Open
project, then type the name of the old project file. You can also change the
search attributes from * . IDE to * . PRJ to list the old 3.0 and 3.1 projects.'
The project manager converts the old project to a new one. Be sure to save
the new project if you want to keep using it with this version of Borland
C++. To save the project, choose Options I Save. Make sure Project is
checked, then click OK. The new project is saved with the old name and the
new .IDE extension.

Converting
projects to
makefiles

You can convert Borland C++ project files (.IDE) to makefiles (.MAK) from
the IDE. To convert a project file to a makefile,
1. Open the project file (.IDE) 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. The IDE
displays the new make file in an editor window.
Changing the'
Project View

The project window, by default, displays the project node, target, and
dependents. You can control the display by using the Options I
Environment dialog box.
1. Choose Options I Environment. The Environment Options dialog box

appears.
2. Choose Project View. A list of options appears.
3. 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 will appear in the project window. The following list describes
each option:
Build translator displays the translator used on the node.
Code size displays the total size in bytes of code segments. This
information appears only after the node has been compiled.
Data s~ze displays the size in bytes of the data segment. This
information appears only after the node has been compiled.
Description displays a description of the node. You type the description
using the Edit node attributes dialog box from the SpeedMenu.
Location lists the path to the source file associated with the node.
Name displays the name of the node.

Chapter 2, Using the project manager

29

Number of lines displays the number of lines of code in the file

associated with the node (note that this displays only after you compile
the code).
Node type describes the type of node (for exainple, . cpp or . c).
Style Sheet names the Style Sheet attached with the node.
Output names the file (and the path to that file) that the node creates
when it is translated. For example, a .CPP node creates an .OBJ file.
Show runtime nodes displays the nodes the project manager uses when
the project is built. For example, it lists startup code and libraries.
Show project node displays the node for the entire project. The project
node is built when you choose Project IBuild all. Note that all targets are
dependents of the project node.

Building a project
To build a project,
1. Open the project you want to build using Project IOpen project from the
main menu.
2. Choose Project IBuild all from the main menu to build all the nodes in
the project, even if they're up-to-date. Or, choose Project IMake all to
build only the nodes whose dependents have changed since the last
project build.
The project manager builds the project using the Default Project Options
Style Sheet unless you have attached a different Style Sheet to a node or
overridden the options locally. See the section "Using Style Sheets" on
page 37 for more information.
.
The project manager starts at the first target and works down the project
until it comes to a node with no dependents. The project manager builds
that node first (and other nodes on the same level), then works back up the
project tree.
For example, if you have a project with an .EXE target that is dependent on
a .CPP file, the project manager builds the .CPP file to an .OBJ, and then the
project uses the new .OBJ file to create the .EXE.
If you choose Make all, the project manager checks a file's date and time to
seeif the file has been updated. If so, the project manager rebuilds that file,
then moves up the project tree and checks the next node's file date and
time. The project manager' checks all the nodes in a pr9ject and builds all
the out-of-date nodes.

30

Borland C++ Users Guide

Building part of a
project

There are three ways you can build part of a project:
• 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 build a project using MAKE,
1. Select the node you want to build.
2. Right-click the node (or press AIt+F10) and choose Make node from the
SpeedMenu. MAKE builds only the nodes that aren't current. For more
information about MAKE and how it chooses which files to build, see
Chapter 12, "Using MAKE."

• To translate the individual node,
1. Select the node you want to translate.
2. Choose Project ICompile from the main menu or select the default
translation command from the SpeedMenu. For example, if you've
selected a .CPP file, the project SpeedMenu contains the command C++
Compile, which compiles only the selected node.
Project ICompile translates the current node if the project window is
selected. If an editor window is selected, Project ICompile translates the
text in the editor.

Editing the project tree
You can edit the project tree using keystrokes or menu commands. Some
menu commands appear only on the SpeedMenu. To display a SpeedMenu
in the Project window', right-click a node, or select a node and press AIt+F10.
The options available on the SpeedMenu reflect the type of selected node
and vary slightly among node types.
When editing projects, you can add, delete, and move targets and nodes,
and you can copy nodes. You can also change node and target attributes.

Chapter 2, Using the project manager

31

Editing target
attributes with
TargetExpert

Target attributes describe a target type. For example, a target can be a 16-bit
Windows DLL that you want to change to be 32 bits. You can change
attributes for Standard and AppExpert target types, but not for Source
Pools (see page 35 for information on Source Pools). Also, you can't change
a target type to be another target type (for example, you can't change a
Source Pool target to be an AppExpert target type).
To change a Standard or AppExpert target's attributes,
1. Select the target in the project window.

2. Press AIt+F10 or right-click the target node.
3. Choose TargetExpert from the SpeedMenu. The TargetExpert dialog
box appears.
4. Change the target attributes, then choose OK. Target attributes are
explained on page 27.
Editing node
attributes

Node attributes describe a node and define the options and translator used
when translating a node. To edit a node's attributes,
1. Select the node in the project window.
2. Press Alt+F10 or right-click the node.
3. Choose Edit node attributes from the SpeedMenu. The Node Attributes
dialog box appears.
4. Change the node attributes, then choose OK. Node attributes, which
usually display in the project window, are defined as follows:
Name is the name of the node.
Description is any text that describes 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 parent's Style Sheet.
Translator names the translator used on that node, which is usually the
default translator for the node type (CppCompile for a .CPP node). If
you change the translator, you'll override the default translator for this
node, affecting builds and makes for this node. See page 40 for more
information on translators.
Node type defines the node and the available translators tor that node.

32

Borland C++ Users Guide

Adding and
deleting a node
You can also use the
SpeedMenu to add
nodes. Press
AIt+F1O, then choose
Add node (you can
add one or more
nodes using this
command).

..

To add one node to the project,
1. Select the node you want the new node to appear under. If you want the
new node to appear under the target, select the target node.
2. Press Ins or right-click the selected node and choose Add node from the
SpeedMenu.
3. Choose the file or files you want associated with the new node, or type
the name of the node you want to add (if the file you type doesn't exist
in the current directory, the IDE creates the file).
4. Choose OK. The new node appears under the selected node.

If you want to add many nodes to a project,
1. Start the Windows File Manager and select the files you want to add as
nodes to your project. Make sure you can view the project window in
the IDE.
2. Drag the files from the File Manager. The project manager automatically
adds them under the selected node.
To delete a node in the project, select the node and press Del, or choose
Delete node on the SpeedMenu. You can delete many nodes by selecting
the ones you want to delete (use etrlor Shift with the left mouse button to
select multiple nodes), then pressing Del. The project manager asks if you
want to delete the nodes before it proceeds.

Adding and
deleting targets

To add a target to a project,
1. Choose Project I New target from the main menu.
2. Type the name for the new target and choose a target type:
Standard (default) can be an executable, DLL, or other file.
AppExpert is an ObjectWindows-based application. See Chapter 4 for
more information on this type of target.
Source Pool is a collection of files that can be referenced in other
targets. See page 35 for more information on using Source Pools.
3. Choose OK. If the target typeis Standard, the TargetExpert dialog box
appears so you can further define your target (see page 27 for more
information on these choices). If the target type is AppExpert, see
Chapter 4. If the target type is Source Pool, the target is added to the.
project and you can add nodes to it immediately.

Chapter 2, Using the project manager

33

..

To delete one or more targets,
1. Select the target and view the SpeedMenu (right-click the target or press

Alt+F10).
'
2. Choose Delete node.
3. The project manager asks if you're sure you want to delete the target.
Click OK. Note that you cannot undo this deletion.
Moving nodes and
targets

Copying nodes

You can move nodes and targets in several ways:
• Drag the node with the mouse. The node moves under the selected node
when you release the mouse button .
• Select 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 move a node through levels of dependencies.
For example, if you have a header file dependent on a .CPP file (so the .H
file appears under 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+left arrow.
Nodes can be copied completely or by reference. A complete copy lets you
take the node and its attributes and put an identical, but separate, copy
somewhere in the project. A complete copy inherits the attributes from its
parent node unless you override any options.
A reference copy lets you take a node and its dependents and reference
them in another place in the project; a reference copy isn't distinct-if you
add or delete dependents of the original, the reference copy is also
updated. A reference copy is a copy of a node and its dependents.
To make a complete copy of a node,
1. Select the node or nodes you want to copy (use Shift or GIrl and the
mouse to select multiple nodes). If a node has dependents, the
dependents are copied automatically-you don't need to select them.
2. Hold down the Girl key and drag the selected nodes to where you want
to place the complete copies.
3. When you release the mouse button, the copied nodes appear. If you
edit the original node, the complete copy is not changed.

34

Borland C++ User's Guide

To make a reference copy,
1. Select the node you want to reference copy. You don't need to select the
node's dependents because they are copied automatically.
2. Hold down the Aft key and drag the selected node to where you want to
place the reference copy.
3. When you release the mouse button, the copied node appears. The
reference-copied node appears in a lighter (unbold) font. This helps you
remember that the copy is referenced rather than complete. If you edit
the original (such as adding or deleting dependents), all reference copies
are updated.
Warning!

If you delete an original node, all references to that node are also deleted.
You cannot undo this deletion.
'

Using Source Pools
A Source Pool is a collection of nodes. The Source Pool target isn't built, but
can be referenced during a build. Source Pools let different targets use a
common setof source code. One use for a Source Pool might be to create
two target applications-one 16-bit and the other 32-bit. To see a working
example of Source Pools, open the sample project called SRCPOOL.IDE in
the EXAMPLES\IDE\SRCPOOL directory. This project file includes a text
file that describes how the Source Pool is used in that example.
Source Pools can contain several files that you want to copy by reference in
your project. For example, you might have several header files that you
want to place throughout your project. If you place these files in a Source
Pool, then reference copy the Source Pool throughout the project, you only
have to update the original Source Pool. If you need to add a new header
file to the collection, you can add it in the original Source Pool and all the
referenced copies are automatically updated.
Source Pools are useful when you want to assign a single Style Sheet to
multiple targets. For example, if you have three targets in a project and you
want all the targets to use the same Style Sheet, you can either attach the
Style Sheet to each target individually, or you can move the targets under a
Source Pool; then attach the single Style Sheet to the Source Pool node. If
you want to reassign a Style Sheet (for example, you want to compile
without debug information), you only have to reassign the Style Sheet to
the Source Pool-not to each target.

Chapter 2, Using the project manager

35

Setting project options
Once you create a project, you might want to change the default build
options. These options tell the project manager how to build your project
(for example, they specify whether you want to include debugging
information in your application).
To change project options,
1. Choose Options IProject. A dialog box appears.
2. Edit the options you want to change. See Chapters 1 and 3 for a
description of the options.
3. Choose OK when you're done changing options.
When you build your project, the options you set are used for your entire
project. If you create a new project, it receives the project options from the
last open project.
There are times when you want to select different options for a specific node
in the project (for example, you might have a specific file you don't want
compiled with debugging information, but you want the rest of your files
to include debugging information). To use different options for a node, you
can use Local Override or a Style Sheet.

Local Override

Project options can be overridden locally. Local Override is useful when
you use project options, but you want to override a particular option for a
single node. If you want to override many options, use a separate Style
Sheet instead (see the next section on Style Sheets).
To override an option,
1. Choose the node whose options you want to override.
2. Right-click the node (or press Alt+F10) and choose Edit local options
from the SpeedMenu. The Style Sheet dialog box appears with the
options used for that node.
3. Select the option you want to override. The Local Override box is
checked automatically.
4. Click OK.

Caution!

36

To undo an override, uncheck Local Override. The checkmark in Local
Override shows only when the cursor is in the override option, which
makes it difficult to know which options you oyerrode. The Local Override
box is dark gray if no options in that section of 'options is overridden. The

Borland C++ Users Guide

box turns light gray if any option in that section is overridden, but you still
must select the individual options to find which one is overridden.
If you find yourself overriding more than one or two options, you might
want to create and use a separate Style Sheet for that node instead of using
Local Override.
Using Style
Sheets

Style Sheets are a collection of build options for a project. Every project uses
a default set of options. These "defaults" are saved in a Style Sheet, and by
default the project uses a Style Sheet called "Default Project Options". The
settings in the Style Sheet determine how the project is built. If all the
components in your project can be built with the same options, you can set
the options using the Options I Project dialog box (this is a way of editing
the "Default Project Options" Style Sheet. If you want to change options for
a single node, use Local Override, but if you find you're using Local
Override a lot, you might want to use Style Sheets.
When a project is built, the project's Style Sheet is used unless the node
being built references a different Style Sheet or uses Local Override (see
page 36 for information on using Local Override). You can use Style Sheets
and Local Override. You might want to do this if you attach Style Sheets to
your targets but want to slightly modify (override) the Style Sheet for a
node under the target.
When the project manager builds a node, it uses the node's Style Sheet and
any Local Override options. If the node doesn't have its own Style Sheet,
the project manager uses the Style Sheet of the node's parent. If the parent
node doesn't use a Style Sheet, the project manager looks at the next parent,
continuing until it uses the project's Style Sheet.
Different nodes in a project usually need to be built with different options.
For example, you might want to compile .C files with one set of options but
.CPP files with another. Or, you might want to build one target with 16-bit
options and another with 32-bit options. To see how Style Sheets can be
used in a project, open the project file called STYLESHT.IDE in the
directory \EXAMPLES\IDE\STYLESHT. This file uses Style Sheets for
each of the targets (two versions of WHELLO). The project also contains a .
text file that explains the use of Style Sheets.

Attaching a Style
Sheet to a node

The project manager contains several Style Sheets that you can use, but you
can also create your own. To attach an existing Style Sheet to a node,
1. Select the node and right-click it.
2. Choose Edit node attributes.
3. Select a Style Sheet from the list box.

Chapter 2, Using the project manager

37

4. Click OK.
You can also click the Styles button to create a new Style Sheet. See the next
section for more information on creating Style Sheets.
Creating a Style
Sheet

Editing Style Sheets

To create a Style Sheet for a project,
1.
2.
3.
4.

Choose Options IStyle Sheets from the main menu.
Click Create. Type a name for the Style Sheet and press Enter.
Click Edit. The Style Sheet dialog box appears.
Edit the options for your Style Sheet. Most options are described in
Chapter 3.
5. Click OK when you've completed setting the options for your new Style
Sheet.
You can edit, rename, and copy existing Style Sheets. Choose Options I
Style Sheets to view the Style Sheets dialog box. You can do any of the
following tasks from that dialog box:
Compose lets you create a Style Sheet that contains the combined options
from one or more Style Sheets:
1. Create a new Style Sheet (click New and type a name), then click
Compose.
2. Select a Style Sheet you want included in your new Style Sheet, then
click Add.
3. Continue adding Style Sheets, then click OK when you're finished. You
can't edit a composed Style Sheet, but you can click Compose again to
add or delete Style Sheets from the Composed one.

..

To copy a Style Sheet,
1. Select the Style Sheet you want to copy and then click Copy.
2. Type a name for the copied Style Sheet, then click OK. You can now
click Edit to change any of the copied options. Copying is a fast way to
create a Style Sheet that closely resembles another-you only have to
change the options you want.

..

To edit any Style Sheet,
1. Select the Style Sheet and click Edit.
2. Change the options you want, then click OK.

38

Borland C++ Users Guide

_

To rename a Style Sheet,
1. Select the Style Sheet and click Rename.
2. Type the new Style Sheet name, then click OK.

To remove a Style Sheet, select it and click Remove.
Sharing Style
.Sheets

Caution!

If you create Style Sheets for a project, then choose Project I New project, the
new project inherits the Style Sheets (and tools and options) from the old
project. However, if you close a project or restart the IDE, you'll have to
reopen the project with Style Sheets, then create a new project to inherit the
Style Sheets.

You can also share Style Sheets between projects another way. Every time
you create a project file (.IDE), you also create a Project Description
Language file (.PDL), which contains information about the Style Sheets
and Tools used in the project. Be careful when editing the text in this file
because you run the risk of corrupting the file to the point where the project
manager can't read it.
When you open a project file, the project manager opens the .PDL file with
the same name as the .IDE file.
To share a Style Sheet between projects,
1. Open the .PDL file containing the Style Sheet you want to share. You
can open the .PDL file using any text editor.
2. Search for the Style Sheet's name. For example, if you created a Style
Sheet called MYSTYLE, you'll see a section in the .PDL file that starts
{ StyleSheet

= "MYSTYLE".

3. Copy all the text from the beginning brace to the ending brace. You can
copy more than one Style Sheet.
4. Open the .PDL file to receive the copied Style Sheet.
5. Find the section for Style Sheets, then paste the copied text to the end of
the existing Style Sheet list.
6. Save the .PDL file that received the copied Style Sheet. When you open
the project associated with the updated .PDL file, you'll see the pasted
Style Sheets when you choose Options I Style Sheets.

Chapter 2, Using the project manager

39

Viewing options
in a project

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 the1options for
each node.
To view the hierarchy of options,
1. Right-click any node in the project and choose View options hierarchy.
The Options Hierarchy dialog box appears, listing the nodes in the
project and the options each uses. Autodependency nodes don't appear.
You can expand and collapse the list of nodes just like you can in the
project window.
2. Click a node you want to view. Its options appear to the right.
3. If you want to edit an option, double-click the option or select it and
then click Edit. If the option belongs to a Style Sheet, you'll be editing
the entire Style Sheet. If the option is a Local Override option, you'll be
editing the Local Override options for the selected node.
4. When you finish viewing node options, click Close.

The Options list shows the name of the node in square brackets followed by
the name of the Style Sheet for that node. It also lists any options that are
overridden for that node. This hierarchy lets you see what options are sent
to dependent nodes.

Translators
A translator is any program that changes (translates) one file type to
another. For example, the compiler is a translator that uses .C and .CPP files
to create .OBJs, and the linker is a translator that uses .OBI, .LIB, .DEF, and
.RES files to produce an .EXE file.
The project manager lets you define your own translators. Translators you
add to a project remain with that project file-they aren't added as
permanent parts of the IDE. However, translators, viewers, other tools, and
Style Sheets can be passed to the next project: if you have a project file open
that contains added-on tools or Style Sheets, the next project you create
(choose Project I New project) inherits the translators, viewers, other tools,
and Style Sheets from the previous project. For more information on .
sharing information between projects, see page 39.
You can view default translators by choosing Options I Tools-this list also
shows tools and viewers.

40

Borland C++ User's Guide

Installing a
translator

To install a translator,
1. Choose Options I Tools. A dialog box appears that lists Tools, Viewers,
and Translators. You can also install translators by choosing Build
Attributes from the project manager SpeedMenu.
2. Click New.
3. Type the name of the translator, the path to the translator, and any
command-line options for the translator. You can use transfer macros on
this command line. For more information on transfer macros, see the
online Help.
4. Type Menu text. This text can appear on SpeedMenus and on the Tools
main menu. If you want to assign a shortcut key to your menu text,
precede a letter with an ampersand-this letter will appear underlined
in the menu. For example, the shortcut key for File is F. In the menu
text, File would appear as &File. If you want an ampersand in your
menu text, use two ampersands (&&Test appears as &Test in the menu).
5. Type any help text you want. Help hint text appears in the status line
when you select the menu item.
6. Click Advanced. The Tool Advanced Options dialog box appears.
7. Check Translator.
8. Check Place on Tools menu if you want this translator to appear on the
Tools main menu. Check Place on SpeedMenu if you want it to appear
when you right-click a node associated with your translator.
9. Check Target translator if you want the translator to work on targets.
When you use this translator, the node becomes a target and the
translated file is saved to the Final directory. If you don't check Target
translator, the translated file is saved in the Intermediate directory.
10. Type an extension for the files you want to associate with this translator.
For example, BCC is a translator for .C and .CPP files, so Translate From
would show .c; .cpp:. Use a semicolon to separate file extensions and a
colon to designate the end of the list.
11. Type an extension for the resulting translated file. For example, BCC
converts .CPP files to .OBJ, so .obj appears in the Translate to box.
12. If you want your new translator to be the default for a node type, type
the file extension and a colon in the Default for box.
13. Choose OK.

Chapter 2, Using the project manager

41

Using Special on
the SpeedMenu

Installing viewers
and tools

When you display the SpeedMenu, some node types have a Special
command that lists other translators for the type of node you've selected.
For example, you see the commands Assembler Output and Preprocess if a
.CPP node is selected, but you see the command Implib if you selected a
.DLL target node.
Viewers let you see the contents of the selected node. For example, an
editor is a viewer that lets you examine the code in a .CPP file. On the
SpeedMenu for a .CPP node, you'll see the Text Edit command. The default
editor for the Text Edit view is the IDE editor.
To view a node, either
• Double-click it in the project window, or
• Right-click it and choose View to display a list of the available viewers.
Other node types have other viewers available. For example, Resource
Workshop can view .RC files. You can't view an .EXE node in a text editor,
but you can choose to view it using the integrated debugger, Turbo
Debugger for Windows, the ObjectBrowser, or even as an executing
program.
Tools are applications you want to run from the IDE, such as Turbo
Debugger and GREP. You can install viewers and tools just like you can
transla.tors. For more information, see the steps for installing a translator on
page 41.

42

Borland C++ User's Guide

c

H

A

p

T

E

R

3

Compiling
You can compile applications using either the IDE or the command-line
programs BCC.EXE (for 16-bit applications) or BCC32.EXE (for 32-bit
applications). You can control how the compiler generates code by using
compiler options that specify the type of application you want to build (a
debugging version for example), where to find header files and link
libraries, how C++ code is handled, and much more.
This chapter is organized into three parts:
• How to compile in the IDE
• How to compile with BCC or BCC32
• Compiler options reference
Table 3.1 cross-references the command-line compiler options with the IDE
options. Compiler options are discussed in detail according to their topic
groups in the Project Options dialog box.

Compiling in the IDE
This section describes how to compile simple programs using compiler
options in the IDE. To learn how to build large projects, read Chapter 2.
The IDE SpeedBar has three compiling buttons that correspond to menu
commands:
. Project I Compile (AIt+F9) compiles the code in the selected editor window
using the compiler options set in the Project Options dialog box. If a project
window is selected, all the selected nodes in the project are translated; child
nodes aren't translated unless they're selected (see Chapter 2 for
information on translators).
Project I Make all (F9) translates all the out-of-date nodes in a project. If no
project is open, all the files in edit windows are built using the default
project translators.

Chapter 3, Compiling

43

Project I Build all translates all nodes in a project-even if they are up-todate. Project I Build all always starts at the first project node and builds
down the project. Click Cancel to stop a build.
Using IDE
compiler options

There are two ways to set compiler options in the IDE:
• Choose Options I Project and set the options in the dialog box. These
options are used when you compile with no project file loaded. If a
project is loaded, these options affect the entire project when it is built.
• Set project options locally for each file; you must use the project manager
to do this. See Chapter 2 for information on local options.
For example, to compile code in an editor window (you don't have a
project loaded) that generates a 32-bit application for a 80386,
1. Select the editor window displaying the code to compile.
2. Choose Options I Project from the menu.
3. In the Project Options dialog box, click the 32-bit Compiler topic to
display the subtopics, then click Processor.
4. The Processor options for 32-bit appear on the right. Check 80386. This
option stays on until you change it or exit the IDE. To save the option as
a default (so that every time you compile, you get a 32-bit application
for a 80386), choose Options I Save from the main menu.
5. Click the Compile button on the SpeedBar, or choose Project I Compile
(this command compiles the code in the current editor window if no
project is loaded).

Using the command-line compilers
This section explains how to use the command-line compilers (BCC.EXE
and BCC32.EXE). BCC.EXE is a 16-bit application that generates 16-bit
code. BCC32.EXE is a 32-bit application that generates 32-bit code. BCC and
BCC32 work the same, but have different defaults (specified in Table 3.1)
and generate different code. Unless specified, instructions and options for
BCC also apply to BCC32.
You can use BCC to send files to TLINK or TASM (.ASM files if you have
TASM installed on your machine). The general syntax for BCC.EXE is

Bee [option [option ... ]] filename [filename . .. ]
To see a list of common compiler options, type Bee (without any options or
file names), then press Enter. The BCC command and each option and file

44

Borland C++ Users Guide

name must be separated by at least one space. Precede each option by
either a hyphen (-) or a forward slash (I); for example, to specify an
include path type:
BCC -Ic:\code\hfiles

Options and file names entered on the command line override settings in
configuration files.
By default, BCC compiles files without extensions and files with the .CPP
extension as C++ files. Files with a.C extension or with extensions other
than .CPP, .OBJ, .LIB, or .ASM compile as C files.
BCC.EXE and BCC32.EXE have options that are on by default (these
options are marked with bullets in Table 3.1). To turn off a default option,
type BCC -option-.
By default, BCC tries to link with a module-definition file with the same
name as the executable. Use TLINK to link with a module-definition file
with a different name. You can't link with more than one module-definition
file.
Configuration
files

TURBOC.CFG
configures BCC.EXE,
and BCC32.CFG
configures
BCC32.EXE; project
files (.IDE) configure
the IDE.

If you repeatedly use a certain set of options at the command-line, you
might want to list them in a configuration file (a standard ASCII text file). _
You must separate options by spaces; options can appear on one or more
.
lines.

By default, BCC.EXE uses a configuration file called TURBOC.CFG, and
BCC32.EXE uses BCC32.CFG (these defaults are marked with bullets in
Table 3.1). The compilers look for the .CFG files first in the directory where
you typed BCC, then in the directory where BCC.EXE or BCC32.EXE is
stored.
You can create multiple configuration files or modify TURBOC.CFG. To use
a configuration file, type + [path] filename at the BCC command line. For
example, to use a configuration file called MYCONFIG.CFG, you could use
the following command line:
BCC +C:\MYCONFIG.CFG mycode.cpp

Options typed on the BCC command line override configuration files.

Response files

Chapter 3, Compiling

To specify multiple options or files on the command line, place them in a
response file (a standard ASCII text file). Response files let you have a longer
command line than most operating systems allow.

45

To use response files,
1. Type the command-line options you want to use in a file and save the
file. Options can appear on one or more lines in the file, separated by
spaces. Response files s~pped with Borland C++ have the .RSP
extension.
2. TypeBCC @[path]respfile.rsp.
You can specify more than one response file by typing BCC
@[path] respfile. rsp @[path] otheresp. rsp. Options typed at the command
line override any option or file name in a response file.
Option
precedence rules

BCC.EXE and BCC32.EXE evaluate options from left to right, and follow
these rules:
• If you duplicate any option except -lor -L, the last option typed
_overrides any earlier one.
• If you list multiple -L or -I options on the command line, the result is
cumulative: the compiler searches all the directories listed, in order from
left to right.

• Options typed at the command line override configuration and response
file options.

Compiler options reference
Table 3.1 lists c~mpiler options for the IDE and the command line. Most
IDE options appear in the Project Options dialog box; if an option doesn't
appear in the Project Options dialog box, the IDE equivalent option or
command appears in angle brackets <>. Some topic names are abbreviated
or repeated in this table. You can find a more detailed explanation for each
option on the pages referenced in the table.
Default options for both 16- and 32-bit command-line compilers are marked
by a bullet (.); otherWise, the bullet is marked for 16-bit only default (.16) or
32-bit only default(.32). Note that defaults in the IDE are different. The
main default difference is that the IDE compiles with debug and browser
information, making your compiled files larger than if you compiled with
the command-line compilers (the applications will be the same size if you
use the same set of options for both IDE and command-line).

46

Borland C++ Users Guide

Table 3.1: Options summary

Option

.16

.32

•

Page IDE setting

@fiIename

45



+fiIename

45



-1
-2

79
61


16-bit CompileriProcessorl80286

-3

61

16-bit CompileriProcessorl80386

-3

68

32-bit CompileriProcessorl80386

-4

61

16-bit CompileriProcessorli486

-4

68

32-bit CompileriProcessorli486

-5

68

32-bit CompilerlProcessorlPentium

-A
-A-, -AT

59
59

CompilerlSourcelANSI
CompilerlSourcelBorland extensions

-AK

60

CompilerlSourcelKernighan and Ritchie

-AU
-an'

60
68

CompilerlSourcelUNIX V
16- or 32-bit CompilerlProcessorlByte, Word, Double Word

-a-B

62
79

16-bit CompilerlProcessorlByte


Description

I

•

•

•

-b

57

CompilerlCode GenerationlAllocate enums and ints

-b-

57

CompilerlCode GenerationlAllocate enums and ints (uncheck)

59
59
79
57
57
57
57

CompilerlSourcelNested Comments
CompilerlSourcelNested Comments (uncheck)

CompilerlDefines
Compilerl Defines
CompilerlCode GenerationlDuplicate strings merged
CompilerlCode GenerationlDuplicate strings merged (uncheck)

-C
-C-c
-Dname
. -Dname=string
-d
-d-

Chapter 3, Compiling

Read compiler options from
the response file filename.
Use the alternate configuration
file filename.
Generate 80186 instructions.
Generate 80286
protected-mode compatible
instructions (16-bit only).
Generate 16-bit 80386 protected-mode compatible
instructions (BCC option).
Generate 32-bit 80386 protected-mode compatible
instructions (BCC32 option).
Generate 16-bit 80486 protected-mode compatible
instructions (BCC option).
Generate 32-bit 80486 protected-mode compatible
instructions (BCC32 option).
Generate 32-bit Pentium
protected-mode compatible
instructions.
ANSI language compliance.
Borland C++ language
compliance.
Kernighan and Ritchie
language compliance.
UNIX V language compliance.
Align to n: 1 = Byte, 2 =Word,
4 = Double Word (32-bit only).
Align to one byte.
Compile and call the
assembler to process
assembly code.
Make enums always
integer-sized.
Make enums byte-sized when
possible.
Turn nested comments on.
Turn nested comments off.
Compile to .OBJ but don't link.
Define name to the null string.
Define name to string.
Merge duplicate strings.
Don't merge duplicate strings.

47

Table 3.1: Options summary (continued)

Option

•
•

•
•

•

48

Page IDE setting

-dc

64

16-bit CompilerlMemory ModeliPut strings in code segments

-efilename
-Efilename

79
80




-Fc

59 -CompilerlCompiler OutputiGenerate COMDEFs

-Ff

64

16-bit Compil~rlMemory ModeliAutomatic far data

-Ff=size

64

16-bit CompilerlMemory ModeliFar Data Threshold

-Fm

80



-Fs

80



-f
-f-ft-f87

58
58
58
58
80

CompilerlFloating pointlNo floating point (uncheck)
CompilerlFloating pointlNo floating point
CompilerlFloating pointiFast floating point
CompilerlFloating pointlFast floating point (uncheck)


-f287

80



-G
-G-gn

72
72
77

OptimizationslSpecificlExecutable Speed
OptimizationslSpecificlExecutable Size
MessageslStop after n warnings

-H

61

CompilerlPrecompiled headerslGenerate and use

-H-

61

CompilerlPrecompiled headerslDo not generate or use

-Hc

80



-Hu

61

CompilerlPrecompiled headerslUse but don't generate

-H"xxx"

61

CompilerlPrecompiled headerslStop precompiling after header

-H=filename

61

CompilerlPrecompiled headerslPrecompiled header file name

off

Description

Move string literals from data
segment to code segment
(16-bit only).
Link to produce filename.
Use filename as the
assembler.
Generate COMDEFs (16-bit C
only).
Create far variables
automatically (16-bit only).
Create far variables
automatically; set the threshold
to size (16-bit only).
Enable the -Fe, -Ff, and -Fs
options (16-bit only).
Assume OS =SS in all
memory models (16-bit DOS
only).
Allow floating point.
Don't do floating point.
Fast floating point.
Strict ANSI floating point.
Use 8087 hardware
instructions.
Use 80287 hardware
instructions (for DOS
applications).
Select code for speed.
Select code for size.
Warnings: stop after n
messages (100 by default).
Generate and use precompiled
headers.
Do not generate or use
precompiled headers.
Cache precompiled headers.
Must be used with -H or
-Hxxx.
Use but don't generate
precompiled headers.
Stop compiling precompiled
headers at file "xxi' (32-bit
only). This must be used with
-H, -Hu, or -H=fiIename.
Set the name of the file for
precompiled headers.

Borland C++ Users Guide

Table 3.1: Options summary (continued)

Option

Page IDE setting

-h

64

16-bit CompilerlMemory ModeliFast huge pointers

-Ipath

55

Directoriesllnclude

•

-in

59

CompilerlSourcelldentifier length

•

-Jg

71

C++ OptionslTemplateslSmart

-Jgd

71

C++ OptionslTemplateslGlobal

-Jgx

71

C++ OptionslTemplateslExternal

-jn

77

MessageslStop after n errors

-K

57

CompilerlCode GenerationlUnsigned characters

•

-K-K2

57
69

CompilerlCode GenerationlUnsigned characters (uncheck)
C++ OptionslC++ CompatibilitylDon't treat char as distinct

•

-k
-Lpath
-Ix

60
55
80

CompilerlDebugginglStandard stack frame
DirectorieslLibrary


-I-x
-M

80
80




-mc

63

16-bit CompilerlMemory ModeliCompact

-mh

63

16-bit CompilerlMemory ModeliHuge

-ml

63

16-bit CompilerlMemory ModellLarge

-mm

63

16-bit CompilerlMemory ModeliMedium

-mm!

63

16-bit CompilerlMemory ModeliMedium and Never

oms

63

16-bit CompilerlMemory ModeliSmali

•

•

Chapter 3, Compiling

Description
Use fast huge pointer
arithmetic (16-bit only).
Set search path for directories
for include files.
Make significant identifier
length to be n (the default is
32).
Generate definitions for all
template instances and merge
duplicates.
Generate public definitions for
all template instances;
duplicate result in redefinition
errors.
Generate external references
for all template instances.
Errors: ,stop after n messages
(25 messages by default).
Default character type
unsigned.
Default character type ~igned.
Allow only two character types
(unsigned and signed); char
is treated as signed (16-bit
only). Compatibility with
Borland C++ 3.1 and earlier.
Turn on standard stack frame.
Set search path for library files.
Pass option xto the linker (can
use more than one x).
Disable option x for the linker.
Instruct the linker to create a
map file.
Compile using compact
memory model (16-bit only).
Compile using huge memory
model (16-bit only).
Compile using large memory
model (16-bit only).
Compile using medium
memory model (16-bit only).
Compile using medium
memory model; assume OS !=
SS (16-bit only).
Compile using small memory
model (16-bit only).

49

Table 3.1: Options summary (continued)

Option

50

Page IDE setting

oms!

63

16-bit CompilerlMemory ModeliSmall and Never

-mt

63

16-bit CompilerlMemory ModeliTiny

-mt!

63

16-bit CompilerlMemory ModellTiny and Never

-N
-npath
-0
-01

60
55
73
72

CompilerlDebugginglTest stack overflow
DirectorieslFinal
OptimizationslSizelJump optimizations
OptimizationslSpecificlExecutable size

-02

72

OptimizationslSpecifici Executable speed

-Oa

72

OptimizationslSpecificiAssume no pointer aliasing

-Ob
-Oc

74
72

OptimizationslSizelDead code elimination
OptimizationslSpecificlOptimize locally

-Od
-Oe

72
74

OptimizationslDisable all optimizations
OptimizationslSizelGlobal register allocation

-Og

72

OptimizationslSpecificiOptimize globally

-Oi

74

OptimizationslSpeedlinline intrinsic functions

-01
-Om

73
75

OptimizationslSizelLoop optimization
OptimizationslSpeedlinvariant code motion

-Op
-Os

76
72

OptimizationslSpeedlCopy propagation
OptimizationslSpecificlExecutable size

-Ot

72

OptimizationslSpecificlExecutable speed

-Ov

76

OptimizationslSpeedlinduction variables

-OW

74

OptimizationslSizelWindows prolog/epilog

-Ox

72

Optimizationsl Specificl Executable speed

Description
Compile using small memory
model; assume DS != SS
(16-bit only).
Compile using tiny memory
model (16-bit only).
Compile using tiny memory
model; assume DS.!= SS
(16-bit only).
Check for stack overflow.
Set the output directory.
Optimize jumps.
Generate smallest possible
code.
Generate fastest possible code
(same as -Ox).
Optimize assuming pointer
expressions aren't aliased on
common subexpression
evaluation.
Eliminate dead code.
Eliminate duplicate
expressions within basic
blocks.
Disable all optimizations.
Allocate global registers and
analyze variable live ranges.
Eliminate duplicate
expressions within functions.
Expand common intrinsic
functions inline.
Compact loops.
Move invariant code out of
loops.
Propagate copies.
Generate smallest possible
code.
Generate fastest possible code
(same as -Ox).
Enable loop induction variable
and strength reduction.
Suppress the inc bp/dec bp on
Windows far functions (16-bit
only).
Generate fastest code;
Microsoft compatible.

Borland C++ Users Guide

Table 3.1: Options summary (continued)

Option

Page ' IDE setting

-ofilename

81



-P

81



-Pext

81



-P-

81



-P-ext

81



-p

62

16-bit CompilerlCalling ConventionlPascal

-p

68

32-bit CompilerlCalling ConventionlPascal

.16

-p- -pc

62

16-bit CompilerlCalling ConventionlC

.32

-p- -pc

68

32-bit CompilerlCalling ConventionlC

-po

57

CompilerlCode GenerationlFastThis

-pr

62

16-bit CompilerlCalling ConventionlRegister

-pr

68

32-bit CompilerlCalling ConventionlRegister

-ps

69

32-bit CompilerlCalling ConventionlStandard call

-r
-r-

58
58

CompilerlCode GenerationlAutomatic
CompilerlCode GenerationlNone

-rd

58

CompilerlCode GenerationlRegister keyword

-R

61

CompilerlDebugginglBrowser reference information in OBJs

-RT

71

C++ optionslException handling/RTTllEnable r,un-time type info

•

•

•

Chapter 3, Compiling

Description
Compile source file to
filename.OBJ.
Perform a C++ compile
regardless of source file
extension.
Perform a C++ compile and
set the default extension to
ext.
Perform a C++ or C compile
depending on source file
extension.
Perform a C++ or C compile
depending on extension; set
default extension to ext.
Use Pascal calling convention
with 16-bit applications (BCC
option).
Use Pascal calling convention
with 32-bit applications
(BCC32 option).
Use C calling convention (BCC
option).
Use C calling convention
(BCC32 option).
Use fastthis calling
convention for passing this
parameter in registers (16-bit
only).
Use fastcall calling convention
for passing pa~ameters in
registers (BCC option).
Use fastcall calling convention
for passing parameters in
registers (BCC32 option).
Use stdcall calling convention
(32-bit only).
Use register variables.
Disable the use of register
variables.
Allow only declared register
variables to be kept in
registers.
Include browser information in
generated .OBJ files.
Enable run-time type
information.

51

Table 3.1: Options summary (continued)

Option

.16

•

-S
-Tstring

81
81




-T-

81



-tD
-tOc
-tOe
-tW

81
81
81
66




16-bit CompilerlEntry/ExitlWindows all functions exportable

-tWC

81



-tWCD

81



-tWCDE

81



-tWO

67

16-bit CompilerlEntry/ExitlWindows DLL, all functions exported

-tWDE

67

16-bit CompilerlEntry/ExitiWindows DLL, explicit funcs exported .

-tWE

67

16-bit CompilerlEntry/ExitlWindows explicit functions exported

-tWM

81



-tWS

67

16-bit CompilerlEntry/ExitlWindows smart callbacks, all funcs

-tWSE

67

16-bit CompilerlEntry/ExitlWindows smart callbacks, explicit

-Uname

81



-u
-v, -v-vi,-vi-

59 CompilerlCompiler OutputlGenerate underscores
60
60

CompilerlDebugginglDebug information in OBJs
CompilerIDebuggingIOut-of-line inline functions

-va

70
70

C++ OptionslVirtual TableslExternal
C++ OptionslVirtual TableslPublic

-V1

52

Page IDE setting

Description
Produce .ASM output file.
Pass string as an option to
TASM, TASM32, or assembler
specified with -E.
Remove all previous
assembler options.
Make a DOS .EXE file.
Make a DOS .COM file.
Make a DOS .EXE file.
Make the target a GUI.EXE
with all functions exportable.
Make the target a console
.EXE with all functions
exportable.
Make the target a console
.DLL with all functions
exportable.
Make the target a console
.DLL with explicit functions
exportable.
Make the target a GUI.DLL
with all functions exportable.
Make the target a GUI .DLL
with explicit functions
exportable.
Make the target a GUI .EXE
with explicit functions
exportable.
Make the target multithread
(32-bit only).
Make the tar.get a Windows
.EXE that uses smart callbacks
(16-bit only).
Make the target a Windows
.EXE that uses smart
callbacks, with explicit
functions exportable (16-bit
only).
Undefine any previous
definitions of name.
Generate underscores.
Turn on source debugging.
Control expansion of inline
functions.
External C++ virtual tables.
Public C++ virtual tables.

Borland C++ Users Guide

Table 3.1: Options summary (continued)

Option

•

.16

•

Page IDE setting

-V
-Va

70
69

-Vb

69

-Vb-

69

-Vc

69

-Vf

64

-Vmd

69

-Vmm

69

-Vmp

69

-Vms

69

-Vmv

69

-Vo

81

-Vp

70

-Vs
-Vt

70
70

-Vv

70

-W

66

-WD

67

Chapter 3, Compiling

Description

Use smart C++ virtual tables.
Pass class arguments by
reference to a temporary
variable.
Make virtual base class pointer
C++ OptionsIC++ CompatibilitylSame size as 'this' pointer
same size as 'this' pointer of
the class (16-bit only).
Make virtual base class pointer
C++ OptionsIC++ CompatibilitylAlways near
always near (16-bit only).
Don't change the layout of
C++ OptionsIC++ CompatibilitylDisable constructor displacement
classes to relax restrictions on
member pointers (16-bit only).
Far C++ virtual tables (16-bit
16-bit CompilerlMemory Modell Far virtual tables
only).
Use the smallest
C++ OptionslMember PointerlSmallest for class
representation for member
pointers.
Member pointers support
C++ OptionslMember PointerlSupport multiple inheritance
multiple inheritance.
C++ OptionslMember PointerlHonor precision of member pointers Honor the declared precision
for all member pointer types.
Member pointers support
C++ OptionslMember PointerlSupport single inheritance
single inheritance.
Member pointers have no
C++ OptionslMember POinterlSupport all cases
restrictions (most general
representation).
Enable all backward

compatibility options (-Va, -Vb,
-Vc, -Vp, -Vt, -Vv).
Pass the 'this' parameter to
C++ OptionsIC++ CompatibilitylPush "this" first for Pascal
'pascal' member functions as
the first parameter on the
stack.
Local C++ virtual tables.
C++ OptionslVirtual TableslLocal
C++ OptionsIC++ ComplVirtual table Pointer follows data members Place the virtual table pointer
after nonstatic data members.
Don't add the hidden members
C++ OptionsIC++ Compatibilityl'deep' virtual bases
and code to classes with
pointers to virtual base class
members.
Make the target a GUI .EXE
16-bit CompilerlEntry/ExitlWindows all functions exportable
with all functions exportable.
Make the target a Windows
16-bit CompilerlEntry/ExitlWindows DLL, all functions exportable
.DLL with all functions
exportable.
C++ OptionslVirtual TableslSmart
C++ OptionslC++ ComplPass class values via reference to temp

53

Table 3.1: Options summary (continued)

Option

•

-WDE

67

16~bit CompilerlEntry/ExitlWindows DLL, explicit funcs exported

-WE

67

16-bit CompilerlEntry/ExitlWindows explicit functions exported

-WM

81



-WS

67

16-bitlEntry/ExitlWindows smart callbacks, all functions exported

-WSE

67

16-bitlEntry/ExitlWin smart callbacks, explicit functions exported

Ow!

79

MakelBreak Make on warnings

-w
-w-

-X

77
77
77
77
59

MessageslAIl
MessageslNone
MessageslSelected (see specific warning)
MessageslSelected (see specific warning)
CompilerlCompiler OutputiAutodependency information (uncheck)

-X-

59

CompilerlCompiler OutputlAutodependency information (check)

-x
-xd
, -xp

71
71
71

C++ OptionslException handlinglEnable exceptions
C++ OptionslException handlinglEnable destructor cleanup
C++ OptionslException handlinglEnable exception location info

-V

81



-Vo
-y

-z

81
60
74


CompilerlDebugginglLine numbers
OptimizationslSizelSuppress redundant loads

-zAname
.-zBname
-zCname
-zDname
-zEname
-zFname

66
65
66
65
65
65

16-bit CompilerlSegment Names CodelCode Class
16-bit CompilerlSegment Names DatalUnlnitialized Data Class
16-bit CompilerlSegment Names CodelCode Segment
16-bit CompilerlSegment Names DatalUnlnitialized Data Segment
16-bit CompilerlSegment Names Far DatalFar Data Segment
16-bit CompilerlSegment Names Far DatalFar Data Class

-wxxx
ow-xxx

•
•
•

54

Page IDE setting

Description
Make the target a Windows
.DLL with explicit functions
exportable.
Make the target a Windows
.EXE with explicit functions
exportable.
Make the target multithread
(32-bit only).
Make the target a Windows
.EXE that uses smart callbacks
with all functions exportable
(16-bit only).
Make the target a Windows
.EXE that uses smart
callbacks, with explicit
functions exportable (16-bit
only).
Returns a non-zero return
code from the command-line
compiler when there are
warnings and doesn't compile
to .OBJ.
Display warnings on.
Don't display warnings.
Enable xxx warning message.
Disable xxx warning message.
Don't use compiler
autodependency output.
Use compiler autodependency
output.
Enable exception handling.
Enable destructor cleanup.
Enable exception location
information.
Enable overlay code
generation.
Overlay the compiled files.
Line numbers on.
Enable register load
suppression optimization.
Code class.
BSS class.
Code segment.
BSS segment.
Far segment (16-bit only).
Far class (16-bit only).

Borland C++ Users Guide

Table 3.1: Options summary (continued)

Option

•

Page IDE setting

Description

-zGname
-zHname
-zPname
-zRname
-zSname
-zTname
-zVname

65
65
66
65
65
65
65

16-bit CompilerlSegment Names DatalUnlnitialized Data Group
16-bit CompilerlSegment Names Far DatalFar Data Group
16-bit CompilerlSegment Names CodelCode Group
16-bit CompilerlSegment Names Datallnitialized Data Segment
16-bit CompilerlSegment Names Datallnitialized Data Group
16-bit CompilerlSegment Names Datallnitialized Data Class
16-bit CompilerlSegment Names Far DatalVirtual Table Segment

-zWname
-zX:

66

16-bit CompilerlSegment Names Far DatalVirtual Table Class

82 

• Default for both 16- and 32-bit

.1616-bit default

BSS group.
Far group (16-bit only).
Code group.
Data segment.
Data group.
Data class.
Far virtual segment (16-bit
only).
Far virtual class (16-bit only).
Use default name for X; X is
A-H, P, R, S, T, V, or W.

.32 32-bit default

Directories
-Ipath

Include searches path (the drive specifier or path name of a subdirectory)
for include files (in addition to searching the standard places). A drive
specifier is a single letter, either uppercase or lowercase, followed by a
colon (:). A directory is any valid directory or directory path. You can use
more than one -I (which is an uppercase I) directory option.

-Lpath

Library forces the linker to get the COx.OBJ start-up object file and the
Borland C++ library files from the named directory. By default, the linker
looks for them in the current directory.
Source is the directory where the compiler looks for source code.
Intermediate is where the compiler places any temporary files it creates.

-npath

Final places any final output files (.OBJ, .I, or .ASM) created by the compiler
in the directory or drive named by path.

You can enter multiple directories on the command line in the following
ways:
• You can stack multiple entries with a single -L or -I option by using a
semicolon:
BCC.EXE -Ldirnamel;dirname2;dirname3 -linel;ine2;ine3 myfile.e
• You can place more than one of each option on the command line, like
this:
BCC.EXE -Ldirnamel -Ldirname2 -Ldirname3 -linel -linc2 -line3 myfile.e

Chapter 3, Compiling

55

• You can mix listings:
BCC.EXE -Ldirnamel;dirname2 -Ldirname3 -linel;ine2 -line3 myfile.e
If you list multiple -L or -I options on the command line, the result is
cumulative: The compiler searches all the directories listed, in order from
left to right. The IDE also supports multiple library directories.
File-search
algorithms

The Borland C++ include-file search algorithms search for the header files
listed in your source code in the following way:
• If you put an #include  statement in your source code,
Borland C++ searches for somefile.h only in the specified include
directories,.
• If, on the other hand, you put an #include "somefile.h" statement in your
code, Borland C++ searches for somefile.h first in the current directory; if
it doesn't find the header file there, it then searches in the include
directories specified in the command line.

The library file search algorithms are similar to those for include files:
• 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.OB]).
• Explicit libraries: Where Borland C++ searches for explicit (userspecified) 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++ searches for that library in the current
directory first. Then (if the first search was unsuccessful), it looks in the
specified library directories. This is similar to the search algorithm for
#include somefile.h" .
• If you list a user-specified library with drive and/or directory
information (like this: c :mystuff\mylibl.lib), Borland C++ searches only
in the location you explicitly listed as part of the library path name and
not in the specified library directories.
1/

CompilerlDefines
Macro definitions let you define and undefine macros (also called manifest
or symbolic constants) on the command line or in the IDE. Macros defined

56

Borland C++ Users Guide

Options It-JroJectlljompllen UeTlneS

on the command line or in the Options Setting dialog box override those in
your source file. Type IDE macro definitions in the Defines box under the
Code Generation I Settings topic.
-Dname
-Dname=string

Defines the named identifier name to the null string. separate macros with a
semicolon.
Defines the named identifier name to the string string after the equal sign.
string can't contain any spaces or tabs. Separate macros with a semicolon.
Borland C++ lets you make multiple #define entries on the command line
in any of the following ways:
• You can include multiple entries after a single -0 option by separating
entries with a semicolon:
BCC.EXE -Dxxxiyyy=lizzz=NO MYFILE.C
• Multiple -0 options can be included if they are separated by spaces:
BCC.EXE -Dxxx -Dyyy=l -Dzzz=NO MYFILE.C
• You can mix multiple -0 listings with semicolon entries:
BCC.EXE -Dxxx -Dyyy=lizzz=NO MYFILE.C

CompilerlCode-generation
-b -b-

Allocate enums as ints allocates a two-byte int (16-bit) or four-byte int (32bit) for enumeration types. This option is on by default. Unchecked (-b-),
this option allocates the smallest variable size that can hold the
enumeration 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 range of 0 to 65,535 (minimum) or -32,768
to 32,767 (maximum). The compiler allocates 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.

-K -K-

Unsigned characters treats all char declarations as if they were unsigned
char, which provides compatibility with other compilers. BCC defaults
char declarations to signed (unchecked or -K-).

-d

-po

Chapter 3, Compiling

Duplicate strings merged merges literal strings when one string matches
another, producing smaller programs but slightly longer compilation times.
This option can cause errors if one string is modified. This option is
unchecked by default (-d-).
FastThis uses the _ _fastthis calling convention for passing this in a
register to member functions.

57

uptlonslt-'roJectl(.;ompilerICode-generation

With fastthis enabled (16-bit applications only because fastthis is always
used for 32-bit applications), the compiler compiles member functions to
expect their this pointer to be 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 t~is.
'
You can enable fastthis using the -po command-line option or with the
Compiler I Code Generation I FastThis calling option. You can also use the
language-specifier keyword __fastthis.
In small or flat data models, this is supplied in the SI register; 16-bit-Iarge
data models use DS:SI. 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's easiest to compile all classes with fastthis, but you can compile some
classes with fastthis and some without.
-r-

None doesn't use register variables.

-rd

Register keyword specifies that register variables are used only if you use
the register keyword and a register is available. You can use -rd in
#pragma options. Use this option or the -r option to optimize the use of
registers.

,-r

Automatic uses register variables. The compiler automatically assigns
variables to registers if possible, even when you don't specify a register
variable by using the register type specifier. The -r option is on by default.

CompilerlFloating Point

58

-f -f-

No floating point (-f-) specifies that the program contains no floating-point
calculations, so no floating-point libraries are linked. Unchecked (-f), this
option emulates 80x87 calls at run time.

-ff -ft-

Fast floating pOint (-ft) optimizes floating-point operations without regard
to explicit or implicit type conversions. This option can provide answers
faster than under ANSI operating mode. Unchecked (-ft-) this option turns
off the fast floating-point option. The compiler follows strict ANSI rules
regarding floating-point conversions.

Borland C++ Users Guide

uptlonSI t-'roJeClILiomp"en rloaung

t"Ollll

CompilerlCompiler Output

-x -x-u

-Fe

Autodependency information (-X-) generates auto dependency information.
Modules compiled with this option on can use MAKE's auto dependency
feature. By default, auto dependency is turned on (-X-).
Generate underscores automatically puts an underscore in front of
identifiers before saving them in the object module. Underscores for C and
C++ identifiers are optional, but are on by default. You can set them off
with -u-. But note that setting the underscores off causes link errors when
linking with the standard Borland C++ libraries. See Chapter 10 in the
Programmer's Guide for details about underscores.
Generate COMDEFs (16-bit only) generates communal variables

(COMDEFs) for global C variables that are not initialized and not declared
as static or extern. The advantage of this option is that header files that are
included in several source files can contain declarations of global variables.
As long as a given variable doesn't need to be initialized to a nonzero
value, you don't need to include a definition for it in any of the source files.
You can use this option when porting code that uses a similar feature with
another implementation.

CompilerlSource

-c

Nested comments lets you nest comments. Comments normally can't be

nested.
-in

Identifier length causes the compiler to recognize only the first n characters
of identifier names. All identifiers, whether variables, preprocessor macros,
or structure members, are treated as distinct only if their first n characters
are unique. Specifying n to be 0 or greater than 249, or not specifying the
-in option at all, allows identifiers of unlimited length.

By default, Borland C++ uses 32 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; this helps you locate
name conflicts in long identifiers that have been truncated.
-A- -AT

Borland extensions uses Borland C++ keywords. See Chapter 1 in the

Programmer's Guide for a complete list of the Borland C++ keywords.
-A

Chapter 3, Compiling

ANSI compiles ANSI-compatible code. Any Borland C++ keyword is
ignored and can be used as a normal identifier.

59

upllonSIt"'roJeCm.iOmpllerl~OUrce

-AU

-AK

UNIX V uses only UNIX language-extension compliance.
Kernighan and Ritchie uses only Kernighan and Ritchie language

compliance.

Compilerl Debugging
-k

Standard stack frame generates a standard stack frame, which is useful
when using a debugger to trace back through the stack of called
subroutines. This option is on by default. When it's off, any function that
doesn't use local variables and has no parameters is compiled with
abbreviated entry and return code, which makes your code smaller and
faster.

-N

Test stack overflow generates stack overflow logic at the entry of each
function. It causes a stack overflow message to appear when a stack
overflow is detected at run time. This is costly in terms of both program
size and speed but is provided as an option because stack overflows can be
very difficult to detect. If an overflow is detected, the message Stack
overflow! is'printed and the program exits with an exit code of 1.

-vi

Out-of-line inline functions expands C++ inline functions inline. To control
the expansion of inline functions, the -v option acts slightly different for
C++: when inline function expansion isn't enabled, the function is
generated and called like any other function. Debugging with inline
expansion can be difficult, so Borland C++ provides the following options:

• -v turns debugging on and inline expansion off. With this option off, you
can link larger .OB] files. This option doesn't affect execution speed, but
it does affect compile time.
• -v- turns debugging off and inline expansion on.
• -vi turns inline expansion on.
• -vi- turns inline expansion off.
For example, if you want to turn both debugging and inline expansion on,
you must use -v -vi.
-y

60

Line numbers includes line numbers in the .OB] for the IDE's integrated
debugger. This increases the size of the .OB] but doesn't affect size or speed
of the executable program. This option is useful with symbolic debuggers.
In general, -v is more useful than -y with the integrated debugger.

Borland C++ Users Guide

OptionslProjectiCompilerlDebegglng

The debugging options include debugging information in your generated
code. For information on debugging your applications, see Chapter 6; for
browsing information, see Chapter l.
-v

Debug information in OBJs includes debugging information in .OBI files so
that they can be debugged with either t~e integrated debugger or a standalone debugger. 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.

-R

Browser reference information in OBJs includes browser information
when the compiler generates .OBI files; this lets you inspect the appli~ation
using the IDE's integrated Browser. The Browser is described in Chapter l.
When this option is off, you can link larger .OBI files. This option doesn't
affect execution speed, but it does affect compile time.

CompilerlPrecompiled headers
-H

Generate and use generates and uses precompiled headers using the
default file name BCDEF.CSM (16-bit) or 13C32DEF.CSM (32-bit) for the
command-line compilers and .CSM for projects in the IDE.
Precompiled headers can dramatically increase compile speed, although
they require considerable disk space. See page 403 for more information on
precompiled headers.

-Hu

Use but do not generate uses but doesn't generate precompiled headers.

-H-

Do not generate or use doesn't generate or use precompiled headers.

-H=fiIename

Precompiled header name generates and uses precompiled headers and
sets the name of the file for precompiled headers (other than BCDEF.CSM
or BC32DEF.CSM).

-H"xxx"

Stop precompiling after header file stops compiling precompiled headers
when it compiles the file specified as xxx. '

16·bit CompilerlProcessor
-2

80286 generates 16-bit 80286 protected-mode compatible instructions.

-3

80386 generates 16-bit 80386 protected-mode compatible instructions.

-4

. i486

Chapter 3, Compiling

generates 16-bit 80486 protected-mode compatible instructions.

61

Optionsl Projectl16-bit Compilerl Processor

-an

Data alignment Byte/Word align to n: 1 = Byte, 2 = Word (2-bytes). See also

-an for 32-bit applications on page 68. Word (-a) forces integer-size and
larger items to be aligned on a machine-word boundary. Extra bytes are
inserted in a structure to ensure member alignment. 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. Byte (-a-) allows byte-wise alignment. Word alignment increases
the speed with which 80x86 processors fetch and store data.

16·bit CompilerlCaliing Convention
Calling conventions are discussed in more detail in Chapter 2 in the

Programmer's Guide.
-pc -p-

C generates all subroutine calls and all functions using the C calling
convention, which is equivalent to declaritlg all subroutine and functions
with the __cdecl keyword. The C convention permits a function call to
pass a variable number of arguments. You can use the __cdecl, __ pascal,
or __fastcall keyword to declare a specific function or subroutine using
another calling convention.

-p

Pascal generates all subroutine calls and functions using the Pascal calling
convention, which is equivalent to declaring all subroutine and functions
with the __ pascal keyword. The resulting function calls are usually
smaller and faster than they would be if compiled with the C calling
convention (-pc). Functions must pass the correct number and type of
arguments. You can use the __cdecl, __stdcall, or __fastcall keyword to
specifically declare a function or subroutine using another calling
convention.

-pr

Register generates all subroutine calls and all functions using the Register
calling convention, which is equivalent to declaring all subroutine and
functions with the __fastcall keyword. You can use the __stdcall,
__pascal, or __cdecl keyword to specifically declare a function or
subroutine using another calling convention.

16·bit CompilerlMemory Model
Memory model options let you tell the compiler what memory model to
use when compiling 16-bit applications (32-bit applications are always flat
model). The available memory models are small, medium, compact, and

62

Borland C++ Users Guide

OptionslProjectl16-blt (';ompllenMemory Moael

large. See Chapter 8 in the Programmer's Guide for in-depth information on
memory models.
-ms -ms!

-mm -mm!

Small compiles using small memory model (the default). The commandline option -ms! compiles using small model and assumes DS!= S5. To do
this in the IDE, you need to check two options (Small and Never).
Medium compiles using medium memory model. The command-line option
-mm! compiles using medium model and assumes DS!= SS. To do this in

the IDE, you need to check two options (Medium and Never).
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 (when
DS == S5) is to make the resulting pointer a near (DS relative) pointer. This
way, you can assign the address to a default sized pointer in those models
without problems. When DS != 5S, 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 a _ss pointer. But for
the memory models affected, assigning the address to a near or defaultsized pointer produces a "Suspicious pointer conversion" warning. Such
warnings are usually errors, and the warning defaults to on.
The net effect of the -mt!, -ms!, and -mm! options is actually very small. If
you take the address of a stack variable (auto or parameter), the default
(when DS == SS) is to make the resulting pointer a near (DS relative)
pointer. This way, you can simply assign the address to a default-sized
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 a _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,- and the warning
defaults to on.
-me

Compact compiles using compac~ memory model.

-ml

Large compiles using large memory model.

-mh

Huge compiles using huge memory model.

-mt -mt!

Tiny compiles using tiny memory model. The command-line option -mt!

compiles using small model and assumes DS!= SS. To do this in the IDE,
you need to check two options (Tiny and Never).
Default for model uses the model to determine if the stack segment is equal
to the data segment. -

-Fs-

Chapter 3, Compiling

Never assumes that the data segment is never equal to the stack segment,
regardless of the memory model.

63

uptlonswroJect'l6-bit CompilerlMemory Model

Always assumes that DS is equal to SS in all memory models; you can use it
when porting code originally written for an implementation that makes the
stack part of the data segment.

-de

Put strings in code segments moves all string literals from the data
segment to the code segment of the generated object file, making the data
type canst (16-bit only). Using this options 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

~Ft

Automatic far data changes global variables greater than or equal to the
threshold size to far. 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 exceeds (or is close to)
64K. For tiny, small, and medium models this option has no effect. If you
use this option in conjunction with -Fc, the generated COMDEFs become
far in the compact, large, and huge models.

-Vt

Far virtual tables causes virtual tables to be created in the code segment
instead of the data segment (unless changed using the -zV and -zW
options), and makes virtual table pointers into full 32-bit pointers (the latter
is done automatically if you are using the huge memory model).

There are two primary reasons for using this option: to remove the virtual
tables from the data segment, which might be getting full, and to be able to
share objects (of classes with virtual functions) between modules that use
different data segments (for example, a DLL and an executable using that
DLL). For all modules that can share objects, you must compile either
entirely with or entirely without this option. Youcan get the same effect by
using the huge or _export modifiers on a class-by-class basis.
-h

Fast huge pointers 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. This option is off by default.

Normally, Borland C++ normalizes a huge pointer whenever adding to or
subtracting from it. This ensures that, for example, if you have a huge 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,
so that the offset part 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. This option is automatically selected when compiling for Windows.

64

Borland C++ Users Guide

OptionslProjectl16-bit (;OmpllenMemory MOael

-Ff=size

Far Data Threshold changes the point where data is forced to be far (used

by the -Ff option).

16·bit CompilerlSegment Names Data
Use these options only if you have a good understanding of segmentation
on' the 80x86 processor. Under normal circumstances, you don't need to
specify segment names.
-zRname

Initialized Data Segment sets the name of the initialized data segment to

name. By default, the initialized data segment is named _DATA.
-zSname
-zTname

Initialized Data Group changes the name of the initialized data segment
group to name. By default, the data group is named DGROUP.
Initialized Data Class sets the name of the initialized data segment class to

name. By default, the initialized data segment class is named DATA.
-zDname

Uninitialized Data Segment changes the name of the uninitialized data
segment to name. By default, the uninitialized data segment is named _BSS.

-zGname

Uninitialized Data Group changes the name of the uninitialized data
segment group to name. By default, the data group is named DGROUP.

-zBname

Uninitialized Data Class changes the name of the uninitialized data
segment class to name. By default, the uninitialized data segments are
assigned to class BSS.

16·bit CompilerlSegment Names Far Data
-zEname

Far Data Segment changes the name of the segment where _ _ far objects
are put to name. By default, the segment name is the name of the source file
followed by _DATA. A name beginning with an asterisk (*) indicates that
the default string should be used (16-bit only).

-zHname

Far Data Group causes _ _ far objects to be put into group name. By default,
_ _ far objects aren't put into a group. A name beginning with an asterisk (*)

indicates that the default string should be used (16-bit only).
-zFname

Chapter 3, Compiling

Far Data Class changes the name of the class for _ _far objects to name. By
default, the name is FAR_DATA. A name beginning with an asterisk (*)
indicates that the default string should be used (16-bit only).

65

upIIons't'roJectll o-Olt (jompllerlsegment Names Far Data

-zVname

Far Virtual Tables Segment sets the name of the far virtual table segment to
name. By default, far virtual tables are generated in the code segment (16-bit
only).

-zWname

Far Virtual Tables Class sets the name of the far virtual table class segment
to name. By default, far virtual table classes are generated in the CODE
segment (16-bit only).

16-bitCompilerlSegment Names Code
-zCname

Code Segment changes the name of the code segment to name. By default,
the code segment is named _TEXT.

-zPname

Code Group causes any output files to be generated with a code group for
the code segment named name.

-zAname

Code Class changes the name of the code segment class to name. By

default, the code segment is assigned to class CODE.

16-bit CompilerlEntry/Exit Code
Entry /Exit code options specify what type of application the compiler
creates. Although these options are listed in the 16-bit compiler section,
they also work for 32-bit applications. Use TargetExpert to specify if your
application is 16-bit or 32-bit (see Chapter 2 for more information).
-tW -W -WC-

Windows all functions exportable creates a Windows object module with
all far functions exportable. This option creates the most general kind of
Windows executable, although not necessarily the most efficient. This is the
default option (-W- is the default). This option generates the necessary
overhead information for every far function, whether the function needs it
or not. It assumes that all functions are capable of being called by the
Windows kernel or by other modules.

This option, when used with a 16-bit application, creates a Windows .EXE
function prolog/ epilog for all far functions, then sets up those functions to
be called from another module. To actually export the function address
from the .EXE to a .OLL, the code includes a call to MakeProcInstanceO,
passing the resulting pointer to the .OLL requesting the address of the
function. To actually export the function address from the .OLL, function
names need to be included in the .OEF file of the executable.

66

Borland C++ User's Guide

OptionslProjectl16-bit Gompllenl:ntry/l:XIt lioae

-tWE -WE . Windows explicit functions exported creates a Windows object module in
which only those functions declared as _export functions are exportable.

Use this option if you have functions that aren't 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 siven the extra prolog/ epilog.
This option is far more efficient for 16-bit applications than Windows All
Functions Exportable, because only those functions called from outside the
module get the overhead of the prolog. This option does, however, require
determining in advance which functions/ classes need to be exported.
MakeProcInstanceO is still used, but no .DEF file manipulation is needed.
-tWS -WS

Windows smart callbacks, all functio!1s exportable (16-bit only) creates an

object module with functions using smart callbacks and all functions
exported. Use this option only if the compiler can assume that DS == SS for
all functions in the module (which is the vast majority of Windows
programs and the default for Borland tools).
This option creates a Windows EXE function prolog/ epilog for all/far'
functions, then sets up those functions to be called from another module.
MakeProcInstanceO need not be called and no .DEF file editing is needed.
-tWSE -WSE

-tWO -WO

Windows smart callbacks, explicit functions exportable creates a 16-bit
Windows application with smart callbacks and explicit exported functions.
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 far more
efficient because only those functions called from outside the module get
the overhead of the prolog. This option does, however, require determining
in advance which functions/ classes need to be exported.
Windows DLL, all functions exportable creates a DLL object module with

all functions exportable. This option creates a Windows DLL function
prolog/ epilog for all/far' functions, then sets up those functions to be
called from another module. To actually export the function address from
the .DLL, function names need to be included in the .DEF file of the
executable.
-tWOE -WOE

Chapter 3, Compiling

Windows DLL, explicit functions exported creates a DLL object module in
which only those functions marked as _export are exportable. The
Windows DLL, Explicit Functions Exported is the same as Windows DLL,
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 is far more efficient than Windows DLL, All

67

uplIonSI t"'roJeCtll 0-011 l,;Ompllerl Entry/Exit Code

Functions Exportable because only those functions called from outside the
module get the overhead of the prolog. This option does, however, require
determining in advance which functions/ classes need to be exported. No
.DEF file manipulation is needed.

32-bit Compilerl Processor
-3

80386 generates 32-bit 80386 protected-mode compatible instructions.

-4. i486 generates 32-blt 80486 protected-mode compatible instructions.

-5
-an

Pentium generates Pentium protected-mode compatible instructions.
Data alignment BytelWord/Double word aligns to n at the command-line
where n matches the IDE options as follows: 1 = Byte,2 = Word (2-bytes),
4 = Double word (4-bytes).Word alignment increases the speed with which
80x86 processors fetch and store data. See page 62 for information on using
this option with 16-bit applications.

32-bit CompilerlCaliing Convention
Calling conventions are discussed in more detail in Chapter 2 in the

Programmer's Guide.

68

-pc -p-

C generates all subroutine calls and all functions using the C calling
convention, which is equivalent to declaring all subroutine and functions
with the _ _ cdecl keyword. The C convention permits a function call to
pass a variable number of arguments. You can use the _ _ cdecl, __pascal,
or _ _fastcall keyword to declare a specific function or subroutine using
another calling convention.

-p

Pascal generates all subroutine calls and functions using the Pascal calling
convention, which is equivalent to declaring all subroutine and functions
with the _ _ pascal keyword. The resulting function calls are usually
smaller and faster than they would be if compiled with the C calling
convention (-pc). Functions must pass the correct number and type of
arguments. You can use the _ _cdecl, __stdcall, or _ _ fastcall keyword to
specifically declare a function or subroutine using another calling
convention.

-pr

Register generates all subroutine calls and all functions using the Register
calling convention, which is equivalent to declaring all subroutine and
functions with the _ _fastcall keyword. You can use the _ _stdcall,

Borland C++ Users Guide

up1l0nsu. . roJeCIIJi::::-0I1 vOrnfJlI~r IvalllllY vUIIVt:IIUUII

_ _ pascal, __fastcall, or _ _ cdecl keyword to specifically declare a function

or subroutine using another calling convention.
-ps

Standard call uses stdcall calling conventions. This option tells the compiler

to use Pascal ordering for pushing parameters. Parameters are pushed
starting from left to right.

c++ OptionslMember Pointer
-Vmp

Honor precision of member pOinters uses the declared precision for
meIl).ber 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).

-Vmv

Support all cases lets member pointers point to any members. Member
pointers use the most general (but not always the most efficient)
representa tion.

-Vmm

Support multiple inheritance lets member pointers point to members of
multiple inheritance classes except members of virtual base classes.

-Vms

Support single inheritance lets member pointers point to members of
single inheritance classes only.

-Vmd

Smallest for class uses the smallest representation that lets member
pointers point to all members of their class. If the class isn't fully defined at
the point where the member pointer type is declared, the most general
representation is chosen by the compiler (a warning is issued).

c++ OptionsIC++ Compatibility
-K2

Do not treat 'char' as distince type treats char as signed. Compatibility
with Borland C++ 3.1 and earlier (16-bit only).

-Vb-

Always near stores a hidden pointer as near. 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 generates smaller and
more efficient code.

-Vb

Same size as 'this' pOinter matches the hidden pointer to the size of the

'this' pointer used by the class itself.
-Va

Chapter 3, Compiling

Pass class values via reference to temporary. 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,

69

uplIOnSll"'roJeCllli++ UptiOnSIG++ GOmpatibility

initialize this temporary variable with the argument value, and pass a
reference to this temporary to the function.
-Vc

Disable constructor displacements. When the Disable Constructor
Displacements option is on, the compiler doesn't add hidden members and
code to a derived class (the default). This option ensures compatibility with
previous versions of the compiler.

-Vp

Push 'this' first for Pascal member functions directs the compiler to pass
the 'this' parameter 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.

-Vv

'deep' virtual bases. When a derived class overrides a virtual function that
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, and add more code to its constructors and destructors. This option
directs the compiler not to add the hidden members and code, so that class
instance layout is same as with previous versions of Borland C++.

-Vt

Virtual table pointer follows data members places the virtual table pointer

after any nonstatic data members of the particular class, ensuring
compatibility when class instances are.shared with non-C++ code and
when sharing classes with code compiled with previous versions of
Borland C++.

c++ OptionslVirtual Tables
The -Vn option controls the C++ virtual tables. It has five variations:

-v

70

Smart generates common C++ virtual tables and out-of-line inline functions
across modules within your application. Asa result, only one instance of a
given virtual table or out-of-line inline function is included in the program.
This produces the smallest and most efficient executables, but uses .OBJ
and .ASM extensions only available with TLINK or TASM.

-Vs

Local generates local virtual tables and out-of-line inline functions. As a
result, each module gets its own private copy of each virtual table or outof-line inline function it uses; this setting produces larger executables than
the Smart setting.

-va

External creates external references to virtual tables. If you don't want to
use the Smart or Local options, you can use External and Public to produce
and reference global virtual tables.

Borland C++ Users Guide

OptionsIProjectIC++ OptionslVirtual I abies

-V1

Public produces public definitions for virtual tables. When using External
or Public options, 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 -va option to refer
to that Public copy of the virtual tables.

c++ OptionslTemplates
For more information about templates, see Chapter 3 in the Programmer's
Guide.
-Jg

Smart generates public definitions of all template instances. If more than

one module generates the same template instance, the linker merges them
to produce a single copy of the instance. To generate the instances~
however, 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).
-Jgd

Global generates public definitions for all template instances encountered.
Duplicate instances are not merged, causing the linker to report public
symbol redefinition errors if more than one module defines the same
template instance.

-Jgx

External generates external references to template instances. Make sure
instances are publicly defined in some other module (using the -Jgd
option), so that external references are properly resolved.

c++ OptionslException handling/RTTI
-x

Enable exceptions enables C++ exception handling. If you use C++
exception handling constructs in your code and compile with this option
disabled (by unchecking the option in the IDE or using the -x- commandline option), you'll get an error.

-xp

Enable exception location information makes available run-time
identification of exceptions by providing the line numbers in the source
code where the exception occurred. This lets the program query the file and
line number from where a C++ exception occurred.

-xd

Enable destructor cleanup destructors are called for all automatically
declared objects between the scope of the catch and throw statements when
an exception is thrown. Note that destructors aren't automatically called for
dynamic objects and dynamic objects aren't automatically freed.

Chapter 3, Compiling

71

optionsIProjectlC++ OptionslException handling/Rnl

-RT

Enable runtime type information generates code that allows run-time type

identification.

Optimizations
The Borland compiler contains an optimizer for improving your
application's speed or reducing its size. Compiling takes only 50% longer
for full speed optimizations and 20% longer for size optimizations. You can
compile with optimizations any time during your project cycle. When
debugging, compiling with optimizations on can sometimes help reveal
bugs in your code (the integrated debugger works with optimized code).
-Od

Disable all optimizations turns off all optimizations. You can override this
using named options sets in the project manager.

OptimizationslSpecific
-02 -Ot -Ox -G

Executable speed creates the fastest code. The compiler determines
whether it can safely generate code to perform a rep movsw instruction
instead of calling a helper function to do the copy. This produces faster
structure copies for structures and unions over eight bytes long than does
the helper function call. The command-line option -Ox is provided for
•compatibility with the Microsoft compiler.

-01 -Os -G-

Executable size creates the smallest code by scanning 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.
No optimization doesn't optimize common subexpressions. This option is
on by default. The command-line compilers don't optimize common
sub expressions by default, so there is no command-line equivalent option
(you don't need to specify an option).
.

-Oc

Optimize locally eliminates common subexpressions within groups of
statements unbroken by jumps (basic blocks).

-09

Optimize globally eliminates duplicate expressions within the target scope

and stores the calculated value of those expressions once (instead of
recalculating the expression). Although in theory this optimization could
reduce code size, it optimizes for speed and rarely results in size
reductions. Use this option if you prefer to reuse expressions rather than
recalculate them for each instance.

72

Borland C++ Users Guide

OptionSll-'rOJeCIIUptlmlZa1l0nSIi:lpeCITIC

-Oa

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
maintain common subexpression 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
applied only when you use -Oa.

-Oa controls how the optimizer treats expressions with pointers in them.
When compiling with common sub expressions and -Oa enabled, the
optimizer recognizes *p * x as a common subexpression in function func1.
int g, y;

~

int funcl(int *p)
{

int x=5;
y
9

= *p * x;
= 3;

return (*p *

Xli

void func2(void)
{

g=2;
funcl(&g);

II This is incorrect--the assignment 9 = 3
II invalidates the expression *p * x

OptimizationslSize
-0

-01

Jump optimizations optimize jumps. When the 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 on, the
sequences of tracing and stepping in the debugger can be confusing,
because there might be multiple lines of source code associated with a
particular generated code sequence. When this option is off, you'll get the
best stepping results when debugging.
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.
int v[lOO];
void t(void)
{

Chapter 3, Compiling

73

upuonSIt'roJeCIIUptlmlZatlOnSltilze

int i;
for (i = 0; i < 100; itt)
v[iJ = 0;

Depending on the complexity of the operands, the compaCted loop code
~an also be smaller than the corresponding noncompacted loop.

-z

Suppress redundant loads, which you should always use when compiling
with optimizations, optimizes for both speed and size by keeping track of
the values loaded into registers. Values already in a register aren't loaded
again.

-Ob

Dead-code elimination reveals variables that might not be needed. Because
the optimizer must determine where variables are no longer used and
where their values are needed (live range analysis), you must use Global
Register Allocation (-Oe) when using -Ob.

-ow

Windows prolog/epilog suppresses the inc bp / dec bp of an exported
Windows far function Prolog and Epilog code. If the Debug information in
OBJs (-v) option is on, this option is disabled because some debugging tools
(such as WinSpector or Turbo Debugger for Windows) need the inc bp/dec
bp to display stack frame information.

-Oe

Global register allocation, which you should always use when optimizing
code, increases the speed and decreases the size of your application. When
the Global Register Allocation option is on, global register allocation and
variable live range analysis are enabled.

OptimizationslSpeed
-Oi

Inline intrinsic functions generates the code for memory functions (such as
strcpy or memcmp) within your function's scope, thus eliminating the need

for a function call. The resulting code executes faster, but it is larger. The
following functions are inlined with this option:
• alloca
.fabs
.memchr
.memcmp
.memcpy

.memset
.rotl
.rotr
.stpcpy
• strcat

• strchr
.strcmp
• strcpy
• strlen
• strncat

.strncmp
.strncpy
• strnset
• strrchr

You can control the inlining of these functions with the pragma intrinsic.
For example, #pragma intrinsic strcpy generates inline code for all
subsequent calls to strcpy in your function, and #pragma intrinsic -strcpy

74

Borland C++ Users Guide

OptionslProjectlOptimizationslSpeed

prevents the compiler from inlining strcpy. Using these pragmas in a file
overrides compiler options.
When inlining any intrinsic function, you must include a prototype for that
function before you use it, because 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 strcpy __ sticpy__.
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 supplied doesn't match the compiler's prototype,
the compiler rejects the attempt to inline that function and generates an
error.
-Om

Invariant code motion moves invariant code out of loops and optimizes for
speed. The optimizer uses information gathered about all the expressions in
the function during common subexpression elimination to find expressions
whose values don't change inside a loop. To prevent the calculation from
being 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 you have used global
common sub expressions, 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[lO];
void f (void)
{

int i,x,y,z;
for (i = 0; i < 10; itt)
v[i] = x * y * z;

The optimizer rewrites the code:
int v[10];
void f (void)
{

int i,x,y,z,tl;
* y * z;
for (i ~ OJ i < 10; itt)
v[i] = tlj

tl '= x

Chapter 3, Compiling

75

Optionsl ProjectiOptimizationsl Speed

-Op

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 sub expression
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. Copies of constants, expressions, and
variables can be propagated.

-Ov

Induction variables creates induction variables and performs strength
reduction, which optimizes loops for 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[il in the following code because
the v[il operation requires multiplication, which also eliminates the need
to preserve the value of i:
int v[10];
void f(void)
{

int i,x,y,z;
for (i = 0; i < 10i itt)
v[i] = x * y * Zi

With Induction variables enabled, the code changes:
int v[10] ;
void f (void)
{

int i,x,y,z, *p;
for (p = Vi P < &V[10]i ptt)
*p = x * y * z;

Messages
Messages on by default contain an asterisk next to the command-line
option; these options are checked in the IDE.

76

Borland C++ Users Guide

uplIomjl t"'fUJt:::l,;lIIVIt:::::i::iayt::\)

-w

-wxxx -w-xxx

-w-gn

All displays all warning messages.
Selected enables the specific warning message typed at the command line
or checked in the IDE. Using the pragma warn in your source code
overrides messages options set either at the command line or in the IDE.
See Chapter 5 in the Programmer's Guide for more information on pragmas.
None doesn't display warning messages. Errors are still displayed.
Stop after n warnings stops compiling after n warnings occur in your

project.
-jn

Stop after n errors stops compiling after n errors occur in your project.

Messagesl Portability
-wrpt*
-wept*
-wrng*
-weln
-wsig
-wuep

Nonportable pointer conversion.
Nonportable pointer comparison.
Constant out of range in comparison.
Constant is long. .
Conversion may lose significant digits.
Mixing pointers to different 'char' types.

MessageslANSI Violations
-wvoi* Void functions may not return a value.
-wret*
Both return and return with a value used.
-wsus* Suspicious pointer conversion.
-wstu* Undefined structure structure.
-wdup*
Redefinition of macro is not identical.
-wbig*
Hexadecimal value contains more than 3 digits.
-wbbf Bit fields must be signed or unsigned into
-wext*
Identifier is declared as both external and static.
-wdpu*
Declare type prior to use in prototype.
-wzdi*
Division by zero.
-wbei* Initializing identifier with identifier.
-wpin . Initialization is only partially bracketed.
-wnak Non-ANSI keyword used: word.

Chapter 3, Compiling

77

ul.JllunSI t'roJecIIIVlessagesluOSolete t;++

MessageslObsolete c++
-wbbi*
-wofp*
-wpre*

Base initialization without a class name is now obsolete.
Style of function definition is now obsolete.
Overloaded prefix operator used as a postfix operator.

MessageslPotential C++ Errors
-wnci*
-weast
~whid*

-wnef*
-wibe*
-wdsz*
-wnst*
-wheh*
-wmpe*
-wmpd*
-wntd*
-wncf*

Constant member identifier is not initialized.
Assigning type to enumeration.
Functionl hides virtual function function2.
Non-const function function called for const object.
Base class basel is also a base class of base2.
Array size for' delete' ignored.
Use qualified name to access nested type type.
Handler for xxx is hidden by previous handler for yyy.
Conversion to type will fail for members of virtual base base.
Maximum precision used for member pointer type type.
Use '> >' for nested templates instead of '»'.
Non-volatile function function called for volatile object.

Messagesllnefficient C++ Coding
-winl*
-wlin*
-wlve*

Functions containing identifier are not expanded inline.
Temporary used to initialize identifier.
Temporary used for parameter in call to identifier.

Messagesl Potential errors
-wpia*
-wdef
-wnod
-wpro*
-wrvl*
-wamb
-weee*

78

Possibly incorrect assignment.
Possible use of identifier before definition.
No declaration for function function.
Call to function with no prototype.
Function should return a value. .
Ambiguous operators need parentheses.
Condition is always true/ false.

Borland C++ Users Guide

OptionslProjectiMessagesllnetticient Goamg

Messagesllnefficient Coding
-waus*
-wpar*
-wuse
-wstv
':""wrch*
-weff*

Identifier is assigned a value that is never used.
Parameter identifier is never used.
Identifier is declared but never used.
Structure passed by value.
Unreachable code.
Code has no effect.

MessageslGeneral
-wasm
-will*
-wias*
-wamp
-wobs*
-wpch*

Unknown assembler instruction.
Ill-formed pragma.
Array variable variable is near.
Superfluous & with function.
Identifier is obsolete.
Cannot create precompiled header: header.

Make
-wI

Break Make on warnings returns a non-zero return code from the
command-line compiler when there are warnings and doesn't compile to
.OBJ.

Command-line options
The options listed here can be used only with the command-line compilers
(BCC.EXE and BCC32.EXE). There are no direct equivalent options in the
IDE; however, because you can do most of these tasks in the IDE, each
option contains directions for the IDE.
-1

Generates extended 80186 instructions. It also generates 80286 programs
running in real mode.

-8

Compiles towards assembly and calls TASM to assemble code. If you don't
have TASM, using this option generates an error. Also, old versions of
TASM might have problems with 32-bit code.

--c

Compiles and assembles the named .C, .CPP, and .ASM files, but does not
execute a link command. Choose Project I Compile in the IDE.

Chapter 3, Compiling

79

vommana-IJne options

-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

Uses name as the name of the assembler to use. By default, TASM is used. In
the IDE, you can add a tool for the assembler program you want to use. See
Chapter 2 for information on adding tools to the IDE.

-f87
-f287

Uses 80287 hardware instructions (16-bit DOS only). In the IDE, check Fast
floating point in TargetExpert when you create a DOS target.

-Fm

Enables all the other -F options (-Fc, -Ff and -Fs).You can use it as a
handy shortcut when porting code from other compilers. To do this in the
IDE, check the IDE options for -Fc, -Ff and -Fs.

-Fs

Assumes that OS is equal to SS in all memory models. You can use this
option when porting code originally written for an implementation that
makes the stack part of the data segment. When you specify this optin, the
compiler links in an alternate startup module (COFx.OBJ) that places the
stack in the data segment. In the IDE, check Alternate Startup in the
TargetExpert dialog box. This option works with DOS applications only.

-He

Cache precompiled headers. Must be ~sed with -H or -Hxxx. This option is
useful when compiling more than one precompiled header.

-Ix

Passes option x to the linker (TLINK for BCC and TLINK32 for BCC32).
More than one option can appear after the -I (a lowercase 1). You can select
linker options in the IDE by choosing Options I Project I Linker. See Chapter
9 for a list of linker options.

-I-x

Suppresses linker option x. More than one option can appear after the -1- (a
lowercase 1). You can check and uncheck linker options in the IDE by
choosing Options I Project I Linker.

-M

Forces the linker to produce a full link map. The default is to produce no
link map. In the IDE, check Segment, Public, or Detailed in the Linker I
Map File section of the Project Option~ dialog box.

-0 filename

-p-

80

Uses 8087 hardware instructions (16-bit DOS only).

Compiles the named file to the specified filename.obj.
Compiles files with the .CPP extension as C++ files; other files compile as C
files. In the IDE, use different tools for compiling a project node. See
Chapter 2 for more information.

Borland C++ Users Guide

vUIII"laIlU-IIII~

-P

UfJlIUII;:)

Compiles all files as C++, regardless of extension. In the IDE, use different
tools for compiling a project node. See Chapter 2 for more information.

-Pext

Compiles all files as C++; it changes the default extension to whatever you
specify with ext. This option is available because sqme programmers use .C
or another extension as their default extension for C++ code. In the IDE, use
different tools for compiling a project node. See Chapter 2 for more
informa tion.
.

-P-ext

Compiles based on the extension (.CPP for C++ code, all other file-name
extensions for C code) and defines the default extension (other than .CPP).
In the IDE, use different tools for compiling a project node. See Chapter 2
for more information.

-s

-Tstring
- T-

-to -tOe
-tOe
-tWC -WC

Generate assembler source compiles the named source files and produces
assembly language output flIes (.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. In the IDE, use different tools for
compiling a project node. Select Special I C++ to Assembler from the project
window SpeedMenu. See Chapter 2 for more information.
Passes string as an option to TASM (or as an option to the assembler
defined with -E).
Removes all previously defined assembler options.
Creates a 16-bit DOS .EXE file. In the IDE, choose this target type when you
create a target for your project.
Creates a 16-bit DOS .COM file. You can't create .COM files from the IDE.
Creates a 32-bit console mode application. In the IDE, choose this target
type when you create a target for your project.

-tWCD -WCD

Creates a 32-bit console mode OLL with all functions exported. In the IDE,
choose this target type when you create a target for your project.

, -tWCDE -WCDE

Creates a 32-bit console mode OLL with explicit functions exported. In the
IDE, choose this target type when you create a target for your project.

-tWM -WM

Creates a multithread application or OLL. Use this option with -Wm and

-weD. In the IDE, choose this target type when you create a target for your
project.
-Uname

-Vo

Chapter 3, Compiling

Undefines any previous definitions of the named identifier name.
This option is a "master switch" that sets on all of the backwardcompatibility options listed in this'section. It can be used as a handy

81

vUllllllcUlU-lIne opIIons

shortcut when linking with libraries built with older versions of Borland
C++.
-Y

82

Enable overlay code generation. In the IDE, choose DOS Overlay for the
target type when you create a target for your project.

-Yo

Overlay the compiled files. In the IDE, check Overlay this module in the
node attributes dialog box for any nodes under a DOS Overlay (-Y) target.

-zx*

Uses the default name for X. For example, -zA* assigns the default class
name CODE to the code segment class.

Borland C++ Users Guide

c

H

A

p

T

E

R

4

Building applications with
AppExpert
See Chapter 5 or the
online Help for
reference material on
AppExpert.

This chapter teaches you how to create ObjectWindows 2.0-based Windows
applications using AppExpert. AppExpert works with Resource Workshop,
ObjectWindows 2.0 classes, and the IDE's project manager to form a visual
approach to application generation. You should be familiar with these
components to effectively use AppExpert.
AppExpert lets you create a Windows executable with features such as a
SpeedBar, a status bar, a menu structure, online Help, and MDI windows.
You can also select options to support printing, print preview, and
document/view.

AppExpert basics
The process of creating applications with AppExpert consists of four steps:
1. 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, and to navigate to existing class source code. ClassExpert can
also associate Resource Workshop objects with classes or handlers. You
should always use ClassExpert to help you with event handling, virtual
function implementation, and instance variables.
3. Use Resource Workshop to edit or add resources.
4. Use the project manager to build the executable.
AppExpert always creates the following files for each application:
AppExpert creates an
.APX file that
contains important
information that
Class Expert uses.

• A project file (.IDE)
• A main source file (. CPP)
• A main header file (.H)

Chapter 4, Building applications with AppExpert

• A resource script file (.RC)
• A resource header file (.RH)
• A database file for the
AppExpert source (.APX)

83

Depending on what options you choose, AppExpert can create the
following files:
• Help source files (.RTF)
• A Help project file (.HPJ)
• Icon and bitmap files (.lCO and .BMP)

Creating an application with AppExpert
This section tells you how to create an AppExpert application.
1. Start the IDE and choose Project I AppExpert. A dialog box appears.
2. Type a name for your project file. By default, most generated files
(including the .EXE) are derived from the project name (for example,
.CPP).
3. Select a path where you want the AppExpert project file to be stored
(AppExpert creates the directory if it doesn't already exist). This
directory becomes the default location for all created source files (you
can change this directory in the Application Generation Options dialog
box before generating the application). (You might want to place each
AppExpert project in its own directory for ease of use when making
changes to files.) Click OK. The AppExpert Application Generation
Options dialog box appeflrs.
4. You can click the Generate button at the bottom of the Options dialog
box to generate the default Windows application, or you can change
options in the dialog box and then generate the application. 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 press
the Help button for information on the options in that topic). To change
application options,
=Application
o Basic Options
o Advanced Options
o Code Gen Control
o Admin Options

• View options by clicking any + to display a subtopic (the + means the
topic contains subtopics, a - means all subtopics are displayed) then
selecting a subtopic. For example, click the + next to the Application
topic (or double-click the word" Application"), then select the
subtopic Basic Options. The panel on the right displays the basic
options for an AppExpert application .
• Check the options you' want in your application. For example, you
can edit the Base directory where AppExpert files are saved (which
you specified in step 3).
5. Click the Generate button at the bottom of the Options dialog box.

84

Borland C++ Users Guide

6. A dialog box confirming code generation appears. Click Yes to generate
the code (click No to return to setting options). When AppExpert is
generating your application, a message box appears.
AppExpert creates all the files for your application and places them in
the Base directory (you can edit the directories before generating the
application; see the Base Directory option on page 86).
With AppExpert, you choose your application options once, then
generate the code. After you generate the code and resources, you can
edit them and add to them, but you can't go back to AppExpert and
change options. For example, if you generate an application that doesn't
contain a status line, you can't use AppExpert to add that
functionality-you need to add it manually.
7. The project window appears, listing some of the files required for your
application (files for bitmaps, icons, and help text don't display). You
can use ClassExpert to modify your application or you can build it first
(see Chapter 5 for information on ClassExpert). To build your
application, choose Project I Make all (you can choose Build all, but
Make all is faster). By default, the executable (.EXE) is saved in the Base
directory.
Default AppExpert
applications

If you don't change any AppExpert options when you generate your
application, you get a default application. You can browse through the
options to view what the default options are.
If you uncheck options you don't need, the application generates and
builds faster.

Application options
Application options control how your application looks.
Multiple Document Interface sets the style of y'our application to follow the
Multiple Document Interface (MOl) model. .
Single Document Interface sets the style of your application to follow the
Single Document Interface (SOl) model.
DocumentlView determines whether your application supports the
Document/View model for handling application objects. The "document"
is the data and the "view" is the user interface to the data. In a
Document/View model, these two are separate (see the Object Windows
Programmer's Guide for more information on Document/View). You can use
this option with either SOl or MOl applications.

Chapter 4, Building applications with AppExpert

85

SpeedBar places a SpeedBar at the top of the main window of your'
application.
Status Line places a status line at the bottom of the main window of your
application and generates code to display help hints in the status line when
menu items are highlighted.
Drag/Drop supports standard Windows drag-and-drop actions.
Printing supports printing-related activities and creates the menus File I
Print Setup, Print Preview, and Print.

ApplicationlBasic
Options

Basic Options define where generated code is stored and controls Help file
support.
Target Name defines the name of the project you want to create as a basis

for the default names of other elements in your project (for example, header
files,class database,application class, and source files).
Base Directory sets the base directory path from which all of the project
directories are located. All paths in the project are relative to this directory.
You can choose a directory by typing it yourself or by selecting it from the
Browse dialog box (click the Browse button). The name of this direcfory is
passed to the project manager for the new AppExpert target. The default
value for the base directory is the directory of the parent node of the project
defined in the project manager. If you specify a new directory, AppExpert
creates the directory.
Help File Support generates Help source files (.RTF) and a Help project file

(.HPJ). The Help project file is added to the Project Manager project and
automatically built with the target application. The Help source file
contains placeholder text for the menu items in the application.
Help File Name names the help files (.HLP and .HPJ) associated with your

application.
Applicationl
Advanced
Options

Advanced Options control the behavior of your application when it starts
running, and its appearance.
Start Up sets the initial state of the application's main window .

• Normal (default) starts in a default size (defined by WS_NORMAL).
• Minimized starts as an icon on the Windows desktop.
• Maximized fills the entire Windows desktop when it starts running.
Control Style determines which type of controls the application uses.

• Windows (default) uses standard Windows controls.

86

Borland C++ Users Guide

• BWCC uses the Borland custom control style .
• 3D uses the new three-dimensional Windows controls.
ApplicationlCode
Gen Control

Code Gen Control options name various aspects of the code-generation
process and determine where the generated code is stored.
Target Name displays the name of the project as defined in Basic Options I

Target.
Base Directory displays the base directory for the project as defined in
Basic Options IBase Directory.
\
Source Directory specifies the directof~ where the source files for the
application are stored. This path is relative to the directory specified as the
Base Directory. If an absolute path is specified, it is converted to a path
relative to the Base Directory (you can't specify another drive). You can
choose a directory by typing it yourself or by selecting one (click the
Browse button). The default value for the Source Path is //. \ //.
Header Directory specifies the directory where the header files for the
application are stored. This path is relative to the directory specified as the
Base Directory. If an absolute path is specified, it is converted to a path
relative to the Base Directory (you can't specify another drive). You can
choose a directory by typing it yourself or by selecting one (click the
Browse button). The default value for the Header Path is //.\//.
Main Source File names the main application source file.
Main Header File names the main application header file.
Application Class names the class that AppExpert derives from

TApplication. The default class name is based on the project name.
About Dialog Class names the class that AppExpert derives from TDialog.
The default class name is based·on the project name.
Comments documents the generated code partially (terse) or fully

(verbose).
Applicationl
Admin Options

Admin Options identify information placed in a comment block at the
beginning of all the files generated forJhe project. Some of the information
is displayed in the application's Help IAbout dialog box.
Version Number sets the project version number that displays in the Help I
About dialog box (the default version number is //1.0"). This information is
stored in the .RC file for your project.

Chapter 4, Building applications with AppExpert

87

Copyright defines the copyright information that displays in the Help I
About dialog box.
Description describes the application and displays the text in the
application's Help IAbout dialog box. The default value is the name of the
project.
Author names the programmers who generate the source code and is used
to comment the generated code.
Company names the programmers' company and is used to comment the
generated code.

Main Window options
Main Window options control the features of your application's main
window-its appearance and type.
Window title names the text for the title bar of the application's main

window.
Background color sets the background color of the application's main
window; click the Background color button to select a color.

Main Windowl
Basic Options

Basic Options control the general appearance of the application's main
window.
Window Styles controls the appearance of the application's main window,
specifying its non-client area styles.
• Caption creates a single, thin border and a title bar where a caption can
•
•
•
•

•

88

be displayed.
Border puts a single, thin border without a title bar around the main
window.
Max box adds a maximize button to the right side of the main window
title bar. This option is available only if the Caption option is on.
Min box adds a minimize button to the right side of the main window
title bar (available only if the Caption option is on).
Vertical scroll adds a vertical scroll bar to the right side of the main
window. This option is available only if you check either Caption or
Border.
Horizontal scroll adds a horizontal scroll bar to the bottom of the main
window. This option is available only if you check either Caption or
Border.

Borland C++ Users Guide

• System menu adds a control-menu button on the left side of the main
•
•
•
•

•

Main WindowlSDI
Client

window title bar (available only if the Caption option is on).
Visible makes the main window visible. When Visible is off, the
WS_VISIBLE style is changed to NOT WS_VISIBLE.
Disabled disables the main window by default (for example, if you want
to display a bitmap when the application is started).
Thick frame puts a double border on the main window and makes the
main window resizable.
Clip siblings protects the siblings of the child windows. Painting is
restricted to that window (see WS_CLIPSIBLINGS in the API online
Help).
Clip children protects child windows from being painted over by the
application's main window (see WS_CLIPCHILDREN in the API online
Help).

SDI Client defines the class that represents the client area of the Single
Document Interface main window.
Client/view class names the class of the SDI client area window or view.
The interpretation of this value depends on whether you selected the
Document/view option in the Application Model settings. If
Document/view is selected, Client/view class selects the class of the view
of the default document/view. If Document/view is not selected,
Client/view class selects the class of the client window.

Table 4.1
ClienVview class with
DocumenVview

Document/view on

Document/view off

TEditView (default)
TListView
TWin do wVie w

TEditFile (default)
TListBox
TWindow

This value is automatically mapped to the Document/view setting. For
example, if you turn off the Document/view option, TListView is switched
to TListBox. Conversely, if you turn on the Document/view option,
TListBox switches tp TListView.
Document class (TFileDocument by default) names the class of the default

document (available if Document/view is on). '
Description describes the class of files associated with the document/view.
The default value is "All Files (*.*)".
Filters (*.* by default) lists wildcard file specifications, separated by
semicolons or commas, that specify the file names you want the application

Chapter 4, Building applications with AppExpert

89

to recognize. This value is passed to Windows common-file dialog boxes to
filter files displayed in them.
Default extension specifies the default file-name extension. This value is
passed to Windows common-file dialog boxes to be added to file names
when no extension is given. The default extension is used in the File I Open
and File I New dialog boxes.

Main Window/MOl
Client

MDI Client describes the class that defines the client window of the
Multiple Document Interface main window (available if MDI is selected in
Application Model settings).
Client class specifies the name AppExpert uses for the class derived from
TMDIClient that represents the client area of the MDI frame window.
Source file names the source file that stores the implementation of the class
named in Client Class.
Header file names the header file that stores the definition of the class
named in Client Class.

MOl ChiidNiew options,
MDI Child/View options define the class for child window or
document/view (available if MDI and Document/view from Application
Model settings are selected).
, MOl child names the class derived from TMDIChild that represents the

frame of the default MDI child windows.
Source file names the source file that stores the implementation of the class
named in MDI child.
Header file names the header file that stores the definition of the class
named in MDI child.

MDI ChiidNiew/
Basic Options

90

Basic Options defines the default MDI child window.
MOl client/view class names the class of the default MDI view. The
interpretation of this value depends on whether you selected the
Document/View option in the Application settings:

Borland C++ Users Guide

Table 4.2
MDI clienVview class
with DocumenVview

Document/view on

Document/view off
-TEditFile (default)
TListBox
TWindow

TEditView (default)
TListView
TWindowView

This value is automatically mapped to the Document/view settings. For
example, if you turn off the Document/view option,' TListView is switched
to TListBox. Conversely, if you turn on the Document/view option,
TListBox switches to TListView. Document class names the class of the document in the default
document/view (TFileDocument by default).
Description describes the class of files associated with the document/view.
The default value is All Files (*.*)".
II

Filters (*.* by default) lists wildcard file specifications, separated by
semicolons or commas, that specify the file names you want the application
to recognize. This value is passed to Windows common file dialog boxes to
filter files displayed in them.
Default extension specifies the default file-name extension passed to
Windows common file dialog boxes to be added to file names when no
extension is given.

Chapter 4, Building applications with AppExpert

91

92

Borland C++ Users Guide

c

p

A

H

E

T

R

5

Using ClassExpert
Class Expert displays
virtual functions and
events for existing
classes and checks
the ones
implemented in your
application.

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 can use ClassExpert with Resource Workshop
to associate classes to resources (for example, associating a TDialog class to
a dialog resource).

Starting Class Expert
To start ClassExpert,
1. Open an AppExpert project file by choosing Project IOpen project.
2. Double-click the AppExpert target node (ClassExpert is the default
viewer for AppExpert targets), or choose View IClassExpert or click the
SpeedBar button shown at left. ClassExpert appears, listing the classes
and their implementation for your application.

ClassExpert
basics

This section describes the three ClassExpert panes and their functionality .
You can size the panes by dragging their borders. If you resize ClassExpert,
the panes keep their relative proportions.

Figure 5.1
The ClassExpert
window

+1 Command Notifications
V + Virtual Functions
V + Windows Messages

PreviewWindow
sampleAboutDlg
sampleApp
sampleMDlChiid
sampleMDIClient

_ _ _-tl--Events
pane

Classes
pane - - t t - - - - -

=11=======_=_=_=:_=_=lij-----'IEdit

IF/="=jI'J=a=in=s=am=p=l=e

Copyxight ~ 1993.
SUBSYSTEjI'J:

FILE:

pane
All Rights Resexved

sample. exe Application
APXPxev.CPP

AUTHOR:

Chapter 5, Using ClassExpert

93

Classes pane

Events pane

The Classes pane lists the classes ClassExpert manages for the current
target. The information in the Events and Edit panes depends on which
class is selected here. You can double-click a class to jump to the class
constructor source code, which displays in the Edit pane. Using the Class
SpeedMenu (right-click in the Classes pane), you can add classes, associate
document classes with view classes, get information about a class, jump to
the class source code or header file, edit the class, and start Resource
Workshop (by choosing Edit dialog or Edit menu).
The Events pane lists events and virtual functions from the base class of the
class selected in the Classes pane. The information in the Events pane
depends on the base class type.
Using the Event SpeedMenu (right-click in the Event pane), you can add or
delete ~essage handlers and instance variables.

Edit pane

The Edit pane is an editor that displays the source code for the items
selected in the Classes pane and the Events pane. The Edit pane has the
same functionality as an IDE editor window; if you make changes or
update the IDE editor options, those options are immediately available in
the ClassExpert Edit pane.
The Edit pane uses the IDE main menu, and it has a SpeedMenu that you
access by right-clicking in the Edit pane. The Edit pane works exactly like
an editor window in the IDE except you can't split panes or open other files
into the Edit pane.

Adding a class

ClassExpert lets you add ObjectWindows-based classes and supports one
level of inheritance (you can manually add more derivations).
To add a class,
1. Right-click in the Classes pane. The SpeedMenu appears.

2. Choose Create new class or click the SpeedBar button shown at left. The
Add New Class dialog box appears.
3. Select the ObjectWindows base class you want your class derived from.
Press Tab.
4. Type the name you want to give to the new class. Press Tab.
5. Type the name of the source file you want the source code to appear in.
The file is saved in the project's Source path. Press Tab.

94

Borland C++ Users Guide

6. Type the name of the header file that defines the class. This file defaults
to the source file name but uses the extension .H. Press Tab.
7. Your next selections depend on the base class:
• If the base class is TDiaiog, you must specify or select a dialog
template ID. The Dialog ID list box contains IDs for all dialog
resources in your AppExpert application. If you specify an ID that
doesn't already exist, AppExpert creates an empty dialog box with
your specified ID (for consistency, you might want to use the prefix
IDD_), then Resource Workshop loads so you can define the dialog
box.
• If the base class is TFrame Window or a TFrame Window-derived class,
you can choose an existing class in the Client class list box to
represent the client area of the new frame window.
• If the base class is TWindow or a TWindow-derived class, you can click
the Set Window Properties button. A dialog box appears where you
set properties for the window such as color, border, and caption. See
the online Help (click the Help button) for information on each
property.

8. Click OK to add the new class.
Creating
document types

When you create an AppExpert application that supports document/view,
you can use ClassExpert to create view classes and document types.
To create a document type,
1. Create a class for the view unless you want to use one of the three
predefined view classes (TEditView, TListView, or TWindowView).
2. St~rt ClassExpert from your project. Right-click in the Classes pane,
then choose Create doc types from the SpeedMenu.
,/ 3. Select a View class (if you created your own class, it appears in this list).
The default view classes are:

See the
ObjectWindows
documentation for
more information on
these classes.

• TEditView provides a view wrapper for ObjectWindows text edit
class.
'
• TListView provides views for list boxes.
• TWindowView provides window-based views.
4. Type a description for the types of files your document type will
support. This text appears in the File I Open dialog box.
5. Type any Filters you want and separate them with commas; these filters
appear in the File I Open dialog box and are used to filter for any files a

Chapter 5, Using ClassExpert

95

user can open and use in your application. For example, if you're
creating a document type for bitmaps, you might have a filter * .EMP.
6. Type a Default extension for your application to use when saving files.
7. Click the Style's button to set styles for the document/view. The styles
you can choose are as follows (see the ObjectWindows documentation
for more information):
.

•
•
•
•
•
•
•
•

dtAutoDelete deletes the document object when the last view is closed.
dtNoAutoView doesn't automatically create a default view type.
dtSingleView provides only a single view for ~ach document.
dtAutoOpen opens a document when it's created.
dtUpdateDir updates the directory with the dialog directory.
dtHidden hides the template from the list of user selections.
dtSelected indicates the last selected template.
dtReadOnly checks the read-only check box when the dialog box is
created.

• dtOver WritePrompt asks users if it's OK to overwrite an existing file
when they use the Save As dialog box.

•
•
•
•
•

dtHideReadOnly hides the read-only checkbox.
dtPathMustExist lets the user type only existing paths.
dtFileMustExist lets the user type only existing file names.
dtCreatePrompt prompts the user before creating a new document. .
dtNoReadOnly returns the specified file as writeable.

8. Click Add to add the document type to your application (this updates a
data structure in the main source file that describes all available
document types). The document/view appears in the list of existing
types.
9. Repeat steps 1-8 for any document types you want to add. When you're
finished, click Close to return to ClassExpert.

Adding and
deleting event
handlers

96

To add a handler for an event,
1. Select the class for the message handler. The events appear in the Events
pane.
2. Select the event to handle (you might have to expand the list of events),
then right-click the event to view the SpeedMenu.
3. Choose Add handler from the SpeedMenu. If you choose to add a
handler for a Windows message, ClassExpert adds an entry to the
response table whose name is defined by default, then the function

Borland C++ Users Guide

associated with the handler appears in the edit window. Other handlers,
such as commands, prompt you for the name of the function before
adding the entry to the response table.
4. ClassExpert places a check mark next to the event in the Events pane to
show you that the event is handled. A lighter gray checkmark means
some events under the event category are handled (expand the list to
view the events).
To delete a handler for an event,
1. Select the class for the message handler. The events appear in the Events
pane.
2. Select the checkmarked event with the handle you want to remove (you
might have to expand the list of events), then right-click the event to
view the SpeedMenu.
3. Choose Delete handler. ClassExpert deletes only the entry in the
response table, not the code in the source file. The code for the handler
appears in the Edit pane, so you can delete it. If you delete the function,
remove the function definition from the header file (you can choose Edit
header from the Classes pane SpeedMenu to view the file).
Adding and
deleting instance
variables

Instance variables let you handle lots of controls easily. When you create
instance variables, ClassExpert adds a transfer buffer in your code. This
transfer buffer collects information at run time, so you can use the
information in the transfer buffer instead of creating code that checks
whether each check box is checked. For example, if you have a dialog box
that has six check-box controls and you want your application to do
something based on which boxes are checked, you can use instance
variables for each of the controls and then use the transfer buffer data in
your code. Consult the Object Windows Programmer's Guide for more
information on transfer buffers.
To add (associate) an instance variable to a control,
1. Select the control in the Events pan~ (you might need to expand the list
of events to view the controls).
2. Right-click the control and choose Add Instance variable.
3. In the Add Instance variable dialog box, type a name for the variable.
Click OK. ClassExpert adds the following to your application code:
• In the header file, it adds a structure declaration with an entry for the

instance variable.

Chapter 5, Using ClassExpert

97

• In the class constructor in the .CPP source file, the instance variable is
allocated (this associates the ObjectWindows class with the resource
object).
• In the .CPP file, a static instance of the transfer structure is declared.

4. The control label in the Events pane shows the class and name of the
instance variable you just created.
To delete an instance variable,
1. Select the control with the instance variable you want to delete.
I~~I

2. Right-click the control and choose Delete Instance variable.
3. 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'll be left with an
empty structure and the set transfer buffer call. This information doesn't
affectthe rest of your code, so you don't need to delete it manually.

Jumping to class
source code

To view the source code for a class, select the class in the Classes pane (click
the class name once). The code appears in the Edit pane. If you move the
cursor in the Edit pane, ClassExpert remembers the position the next time
you select the class.
To jump the cursor to the class constructor code, double-click the class
name in the Classes pane. To jump to a handled event, double-click the
event in the Events pane. You can also view the source file or its header file
in an IDE editor:
1. Select the class in the Classes pane.
2. Right-click the class. A SpeedMenu appears.
3. Choose Edit source to view the source file for the class constructor (the
.CPP file), or choose Edit header to view the header file where the class
is defined. .

Using Resource Workshop with ClassExpert
Resource Workshop is the default viewer for ClassExpert resource scripts
(.RC files). When you start Resource Workshop from ClassExpert (by right-

98

Borland C++ User's Guide

clicking a class and choosing Edit dialog or Edit menu), Resource
Workshop automatically loads the RC script for that application.
When using Resource Workshop with AppExpert-generated code, you
should always run it from ClassExpert because Resource Workshop and
ClassExpert update each other as you make changes to the project. When
you start Resource Workshop, it checks the resource code for changes and
sends any updates immediately to ClassExpert. For example, if you add a
button to a dialog box, Resource Workshop tells ClassExpert, which then
adds the control to the Events pane. To view the control in ClassExpert,
select the control in Resource Workshop, right-click it, then choose
ClassExpert from the SpeedMenu. Resource Workshop returns you to
ClassExpert with the control highlighted in the Events pane.
Running
Resource
Workshop from
the IDE

When you start Resource Workshop as a viewer for an AppExpert
application (either through the project manager in the IDE or through
ClassExpert), its behavior differs from running Resource Workshop
separately:
• When you make changes in Resource Workshop that affect the class
structure or functionality (such as editing menus or dialog boxes), those
changes are updated instantly in the ClassExpert window.
• You can't open another script (no File I Open or File I New).
• If you close the IDE, Resource Workshop is also closed and any changes
you made are automatically saved.
• If you close the AppExpert project file that started Resource Workshop,
Resource Workshop is also closed.
• If you build a project while Resource Workshop is open, it creates a .RES
file based on the resources loaded. For example, if you edit a dialog box,
but haven't saved it, the .RES file will reflect the unsaved edits.
• You can access the IDE from Resource Workshop using the SpeedMenu
(right-click) and choosing ClassExpert.

Using Rescan
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. If the rescan is successful, the original

Chapter 5, Using ClassExpert

99

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:
•
•
•
•
•
Deleting a class

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

To delete a class,
1. Remove the class source file from the IDE project by selecting the source
node, right-clicking 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.
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. Resource Workshop scans and updates the
resource files. When Rescan is complete, you'll return to the updated
project file where you can either build your application or use
ClassExpert. You can add the deleted class to the project by adding the
class source file as a dependent of the AppExpert target, then
rescanning.

Moving a class

To move a class from one source file to ,another,
1. Move (cut and paste) the source code of the class to the new file. If the
new file isn't in the project as a node under the AppExpert target, add it
(see Chapter 2). If the moved class was its own source file, you might
want to delete that empty source file from the project.
2. Select the AppExpert target in the project, right-click it to view the
SpeedMenu, then select Special I Rescan. When complete, Rescan
returns you to the project window in the IDR

Renaming an
AppExpert
element

100

To rename a class, event handler function, instance variable, or dialog ID,
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 .RB files).

Borland C++ Users Guide

2. In the project window, select the AppExpert target, right-click it, then
choose Special I Rescan. When complete, Rescan returns you to the
project window in the IDE.
Importing a class

To import a class from one AppExpert project to another,
1. 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 project's source directory (.CPP files) or header
directory (.H files). These directories were created when you first
generated the AppExpert project.
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. 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 file that contains the AppExpert target and dependent
nodes (this is the .IDE file).
2. Select the AppExpert target, right-click it, then choose Special I Rescan
from the SpeedMenu. Rescan automatically creates a new da,tabase file
using markers from the source code for the AppExpert application.

Chapter 5, Using Class Expert

101

102

Borland C++ Users Guide

c

H

A

p

T

E

R

6

Using the integrated debugger
No matter how careful you are when you code, your program is likely to
have bugs, or errors, that prevent it from running the way you want it to.
Debugging is the process of locating and fixing program errors that prevent
your programs from operating correctly. This chapter explains how to
locate errors in your Windows programs and how to correct them using the
IDE.

Types of bugs
There are three bas~c types of program bugs: compile-time errors, run-time
errors, and logic errors.
Compile-time
errors

Compile-time errors, or syntax errors, occur when your code violates a rule
of C or C++ syntax. The IDE can't compile your program unless the
program contains valid C or C++ statements.
If your code has syntax errors, the compiler opens the Message window

and displays all the errors and warnings. Errors must be fixed one at a time.
To correct an error, double-click it and the IDE positions your cursor on the
source code line that caused the problem so you can make your correction.
If your code had more than one syntax error, you can repeat this process
with each error until all the errors are corrected.
Warnings that appear in the Message window don't stop your code from
compiling, but they do indicate areas in your code you mightwant to
examine for problems. For example, warnings can alert you to code that
isn't portable, code that violates the ANSI standard, or inefficient code. You
can choose which type of warnings you want to see:
1. Choose Options I Project and double-click Messages.
The IDE displays the various message categories and (on the right) the
settings that affect those messages.

Chapter 6, Using the integrated debugger

103

2. Select the option you want. These options determine which warnings
the IDE displays.
• Select All and the IDE displays all warning messages.
• Select Selected and the IDE displays only the selected warning
messages. (You'll be selecting the messages in Step 4.)
• Select None and the IDE displays no warnings.
3. Limit the number of error and warning messages displayed in the

Message window. In the Stop After boxes, indicate the maximum
number of error messages and warning messages you want displayed
each time you compile. The number can be any whole number from
oto 255.
If you enter 0 in either box, the IDE won't limit the number of messages
it displays in the Message window.
4. Under Topics, choose the category of warning messages you want.
5. On the right, select the specific messages you want the IDE to display.
For example, if you want the compiler to warn you about suspicious
pointer conversions that might violate the ANSI standard, choose ANSI
Violations and check the Suspicious Pointer Conversion option.
Common causes of compile-time errors are typographical errors, omitted
semicolons, references to variables that haven't been declared, passing the
wrong number (or type) of arguments to a function, and assigning values
of the wrong type to a variable.
After you correct all the errors,' you can restart the compilation. Once
you've eliminated all the syntax errors and your program compiles
successfully, you're ready to run the program and look for run-time errors
and logic errors.
Run-time errors

Logic errors

104

If your program compiles but it fails when you try to run it, you've

encountered a run-time error. Your program contains legal statements, but
the statements can't be executed properly. For example, your program
might be trying to open a nonexistent file for input or to divide by zero.
The operating system detects this situation and stops your program from
'
executing.
Logic errors are errors in design and implementation. Your statements are·
valid and they do something, but what they do is not what you intended.
These errors are often hard to track down, because the IDE can't find them
automaticq.lly~ Fortunately, the IDE includes debugging features that can
help you locate logic errors.
.

Borland C++ User's Guide

Logic errors occur when variables have incorrect or unexpected values,
when graphic images don't look right, or when code isn't executed when
you expect it. The rest of this chapter d~scusses techniques for tracking
down these logic errors.

Generating debugging information
You must compile and link your program so that debugging information is
generated in your program's .OBJ and .EXE files .
• To add debugging information to your .OBJ files, choose Options I Project
to open the Option Settings dialog box, and select Compiler I Debugging I
Debug Information in OBJs. This is the default setting .
• To include debugging information in your .EXE files, in the Options
Settings dialog box, select Linker I General I Include Debug Information.
This is the default setting.
Now when you compile the program, the compiler generates a special table
of all the identifiers used, and stores it in the executable file. This list, called
the symbol table, is used by the debugger to track all variables, constants,
types, function names, and statements used in your program.

Specifying program arguments
If the program you want to debug requires that arguments be passed to it,
you must specify those arguments:

1. Choose Options I Environment and select the Debugger topic.
2. In the Run Arguments box, type in the arguments you want passed to
the program.

Controlling program execution
The most important element of debugging is controlling the execution of
your program. Because you can control when each statement is executed,
it's easier to determine which part of your program is causing a problem.

Stepping and tracing let you run your program one statement at a time; the
next statement won't execute until you tell the debugger to continue. You
can step or trace until you reach the spot in your code where things go
awry. You can then examine the state of the program and its data, view the

Chapter 6, Using the integrated debugger

105

program's 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.
Watching
program output

Stepping through
code

As you step or trace through your program, you can watch your
application's output in its window. Set up your windows so you can see
both your source code and your application's window as you step and
trace. If the IDE desktop window and your application window overlap as
you debug, you'll see some flickering in your application window. If you
arrange these windows so they don't overlap, your program's execution
will be quicker and smoother.
All execution in the debugger, including stepping, tracing, and halting at
breakpoints, is based on lines of source code. If a statement is more than·
one line on the screen, the statement is still considered to be one line.
You can control the rate of debugging to the level of a single line of source
code. If you string several statements together on one line, you can't debug
those statements individually. On the other hand, you can spread a single
statement out over multiple lines for debugging purposes, and the
statement still executes as a single step.
Each time you tell the debugger to step or trace, the execution point (the
highlighted line that marks your place in the program you're debugging)
moves to the next line. The execution point always shows you the next line
to be executed.
Stepping is the simplest way to move through your code a little bit at a
time. To step through your code, choose Debug I Step Over (or FB or the
Step Over button on the SpeedBar) to execute the code indicated by the
execution point, including any functions it might call before returning
control to you. The execution point then indicates the next complete line.
The following example helps explain how stepping works. Let's say that
these are the first lines of a program loaded into an edit window:

BOOL InitApplication ( HINSTANCE hlnstance )
{

WNDCLASS WCi
wc.style
wc.lpfnWndProc
wc.cbClsExtra
wc.cbWndExtra

106

= CS_HREDRAW I CS_VREDRAWi
= (long (FAR PASCAL*) ())MainWndProcj
= OJ
= OJ

Borland C++ tJ~er's Guide

return ( RegisterClass ( &wc )

)i

int PASCAL WinMain ( HINSTANCE hlnstance, HINSTANCE hPrevlnstance,
LPSTR lpCmdLine, int nCmdShow )
{

MSG msgi
if ( !hPrevlnstance )
if ( !InitApplication ( hlnstance ) )
return ( FALSE )i
if ( !Initlnstance (,hlnstance, nCmdShow )
return ( FALSE ) i

In this example, InitApplication is a function you defined in a module that
has been compiled with debugging information. If you were actually
debugging this program, each time you chose Debug I Step Over (or
pressed FB), the debugger would execute the line highlighted by the
execution point, and then the execution point would advance to the next
line. If you chose Step Over when the execution point got to the statement
if ( !InitApplication ( hlnstance ) )

the debugger would execute the InitApplication function and return a
Boolean value, but you W_Quldn't see the execution point move through the
actuallnitApplication function. Instead, the debugger would step over the
function. Stepping returns control to you after the function finishes.
Tracing into code

Stepping and
tracing class
member functions

Tracing into code is very much like stepping through code, except that
when you come to a line that calls a function, tracing into the code moves
the execution point into the code in the function. In Listing 6.0, if you chose
Debug I Trace In~o (F7 or the Trace Into SpeedBar button) to execute each
statement, you'd see the execution point jump to the code that implements
the InitApplication function when the debugger reached the statement that
evaluates the return value of InitApplication. As you debug, you can choose
to trace into some functions and step over others, depending upon your
needs.
If you use classes in your programs, you can still use the integrated
debugger to step and trace. The debugger handles member functions the
same way it would step over or trace through functions in a program that is
not object-oriented.

Chapter 6, Using the integrated debugger

107

Stepping and
tracing external
code

If you link external code into your program, you can step over or trace into
that code if the .OBJ file you link in contains debugging information.
You can debug external code written in any language, including C, C++,
Pascal, and assembly language. As long as the code meets all the
requirements for external linking and contains full Borl~nd symbolic
debugging information, the IDE's debugger can step or trace through it.

Stepping over
large sections of
code

Sometimes you don't want to step through each line of your code just to get
to the part that is causing problems. With the integrated debugger, you can
step over large amounts of code and regain control at the point where you
want to begin executing line-by-line again.

Running to a
specific location

You can tell the debugger you want to execute your program normally (not
step-by-step) until a certain location in your code is reached:
1. Position the cursor at the line where you want to resume debugging
control.
2. Choose Run to Cursor on the SpeedMenu (or press F4).
You can use Run to Cursor as a way to start your debugging session or
after you've already been stepping and tracing.

Locating a function

Returning to the
execution point

You can locate a particular function quickly with the Locate Function
command on the Search menu. Locate Function asks you for the name of a
function, then positions the cursor on the proper line in the file where that
function is defined. You must be debugging (stepping or tracing through
code) before you can use Locate Function.
While you are debugging, you are free to browse through any file in any
edit window, go to any place in your file, and even open and close files.
You can then return to the execution-point location very quickly.
To go to the execution-point location, choose Debug I Find Execution Point.
The debugger positions the cursor at the execution point. If you closed the
edit window containing the execution point, Find Execution Point opens an
edit window and displays the source code containing the execution point.

Navigating
backward

108

While you're debugging, it can be useful to know how you got to where
you are. The Call Stack window shows you the sequence of fUhction calls

Borland C++ Users Guide

that brought you to your current state. Use View I Call Stack to display the
Call Stack window.
The Call Stack window is particularly useful if you accidentally trace into
code you want to step over. You can step back, and then resume stepping
and tracing where you originally intended:
1. In the Call Stack window, double-click the call that calls the function
you traced into by mistake. (It will be the second call from the top of the
Call Stack window.)
The edit window becomes the active window with your cursor
positioned at the place the call was made.
2. In the edit window, move the cursor completely past the call.
3. Choose Run to Cursor on the edit window SpeedMenu.
The Call Stack window is also useful when you want to view the
arguments passed to each function.
You can view or edit the source code that contains a particular call. Select
the call in the Call Stack window and right-click to display the SpeedMenu
to display view and edit commands.
Stopping the
program

Instead of stepping over or tracing through code, you can use a simpler
technique to pause your program. Choose Debug I Pause Program, and
your program will stop executing. Then you can examine the value of
variables and inspect data at this state of the program. When you're done,
choose Debug I Run to continue the execution of your program.
If for some reason your program assumes control and won't allow you to
return to the debugger (for example, it might be in an infinite loop), you
can press Ctrl+AIt+Sys Req to stop your program.

Starting over

While debugging, you might occasionally want to start over from the
beginning. Choose the Debug I Terminate Program command or press
Ctrl+F2. This ends your program so that all subsequent running, stepping, or
tracing begins at the start of the main program.

Examining values
Stepping and tracing through your code can help you find problems in
program flow, but you'll usually want to watch what happens to the values
of variables while you step. For example, when you step through a for loop,

Chapter 6, Using the integrated debugger

109

it's helpful to know the value of the index variable. The IDE has several
tools to help you examine the contents of your program's variables:
• The Watch window lets you track the value of a variable or expression.
• The Evaluate Expression dialog box lets you evaluate any expression
· meaningful to the program you're debugging, and it lets you change the
value of a variable while you're debugging your program.
• The Data Inspector window lets you examine and modify the value in a
data element.
Whats an
expression?

Watching
expressions

Watching, evaluating, and inspecting operate at the level of expressions. An
expression consists of constants, variables, and data structures combined
with operators. Almost anything you can use as the right side of an
assignment statement can be used as a debugging expression.
If you want to keep track of the value of a variable or expression while you
step through your code, use a watch. A watch is an expression you enter in
the Watch window, which then displays the current value of the
expression. As you step through your program, the value of the watch
expression changes when the program does something to change it.
If the execution point steps out of the scope of a watch expression, the
'watch expression is undefined. Once the execution point enters the scope of
the expression once again, the Watch displays the current value of the
expression once more.

To open the Watch window, choose View I Watch. If you haven't added any
watches yet, the window is empty.
Figure 6.1
The Watch window

Adding a watch

To add a variable to the Watch window, choose Debug I Add Watch. The
IDE opens a Watch Properties dialog box, prompting you to type in a watch
expression.
Just like other IDE windows, you can move, resize, and close the Watch
window. If the Watch window is closed, you can display it again with
View I Watch. If the Watch window is the active window, you can add a
watch by choosing Add Watch from the SpeedMenu.

110

Borland C++ User's Guide

If the edit window is the active window, you can quickly add the
expression at your cursor into the Watch window. To do so, choose Set
Watch on the SpeedMenu.
'
Formatting watch
expressions

Figure 6.2
The Watch Properties
dialog box

If you double-click a watch in the Watch window, a Watch Properties
dialog box appears. You can also display a Watch Properties dialog box by
selecting a watch in the Watch window and then choosing Set Properties on
th~ Watch window SpeedMenu.
Watch Properties
EHPression:

Display as...

r;:-~D~fau,-t--~- ,,),ftT:r;cter' -'--ID;ing --~:

I,. ,'.•· ·.>.Slruc.tUte

... '.

~j Memory dump

,> f..ointe.r . .
,

L-_-.i

floating pOint. '.',.

\' •"

·l.~~~e~al,:~~~~.;~T~--~. t,.~~~i!i~~~t.'d!~i!~:J7, .,.,.,.•. '.•.,[ii

The default expression in a Watch Properties dialog box is the word at the
cursor in the current edit window. A history list keeps track of expressions
you've entered as watches previously.
You can format watch expression results by selecting options in the Watch
Properties dialog box. For example, although integer values normally
display in decimal form, you can specify that an expression be displayed as
hexadecimal by selecting the Hexadecimal button ..After selecting either
Decimal or Hexadecimal, you can modify the format of the expression
further with the Display As options.

If you're watching a data element such as an array, you can display the
values of the consecutive data elements. For example, for an array of five
integers named xarray, you would type the number 5 in the Repeat Count
box of a Watch Properties dialog box to see all five values of the array. An
expression used with a repeat count must represent a single data element.
The debugger views the data element as the first element of an array if the
element isn't a pointer, or as a pointer to an array if it is.
If you select the Floating Point display option, you can also indicate the
number of significant digits you want displayed in the watch expression
result. Specify the number of digits in the Significant box.

Chapter 6, Using the integrated debugger

111

Disabling a watch

If you prefer not to watch an expression you've entered in the Watch
window, but you don't want to delete it because you might want to use it
later, you can disable the watch.
If the IDE must evaluate many watch expressions in the Watch window~
stepping might slow down. You can choose to disable a watch, and then
enable it later when you need it. To disable a watch, click the check box
next to the watch. To enable it again, click the check box again.

You can also disable and enable watches with SpeedMenu commands. To
disable or enable multiple watches at a time, click and drag over a block of
watches to select them in the Watch window, or press etr/while you click
all the watches you want to disable or enable. Then choose the appropriate
command on the SpeedMenu.
Deleting a watch

To delete a watch expression, select the expression in the Watch window
and choose Delete Watch on the SpeedMenu. To delete all watch
expressions, choose Delete All Watches on the SpeedMenu.

Editing a watch

To change the properties of a watch, display the Watch Properties dialog
box for that watch and edit the properties you want changed.

Evaluating and
modifying
expressions

In addition to watching variables as your program executes, you can
evaluate expressions at any time and you can change the values of
variables at run time.

Evaluating
expressions

To evaluate an expression, choose Debug I Evaluate/Modify. The debugger
displays an Expression Evaluator dialog box. By default, the word at the
cursor position in the current edit window is highlighted in the Expressions
box. You can edit the expression, type in another, or choose one from the
history list of expressions you evaluated previously.
The current value of the expression in the Expression box shows in·the
Result box when you choose Evaluate. You can evaluate any valid C or
c++ expressions except those that contain these things:
• Symbols or macros defined with #define
• Local or static variables not in the scope of the function being executed
• Function calls

112

Borland C++ Users Guide

You can format expressions by adding a comma and one or more format
specifiers. For example, to display the result in hexadecimal, type ,H after
the expression. Table 6.1 shows all the legal format specifiers and their
effects.
Table 6.1: Format specifiers for debugger expressions

Character

Types affected

Function

H orX

Integers

Hexadecimal. Shows integer values in hexadecimal with the Ox prefix, including those in
data structures.

C

Characters,
strings

Character. Shows special display characters for ASCII 0.. 31. By default, such
characters are shown using the appropriate C escape sequences ~n, \t, and so on).

D

Integers

Decimal. Shows integer values in decimal form, including those in data structures.

Fn

Floating point

Floating point. Shows n significant digits (where n is in the range 2..18, and 7 is the
default).

nM

All

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, and S specifiers can be
used with M to change the byte formatting.

P

Pointers

Pointer. Shows pointers as seg:ofs with additional information about the address
pointed to. 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.

R

Structures,
unions

Structure/Union. Shows both field names and values such as (X:1; Y:1 0;Z:5).

S

Char, strings

String. Shows ASCII 0.. 31 as C escape sequences. Use only to modify memory dumps
(see nM above).

Modifying variables

While debugging, you can change the value of a variable by using the
Expression Evaluator dialog box. Enter the variable in the Expression box,
then type the new value in the New Value box. If you want the modified
value to take effect in your program, choose Modify. Otherwise, when you
close the dialog box, the debugger ignores the modified value.
Keep these points in mind when you change the values of variables:
• You can change individual variables or elements of arrays or structures,
but not arrays or structures themselves .
• The expression in the New Value box must evaluate to a result that is
assignment-compatible with the variable you want to assign it to. A good
rule of thumb is that if the assignment would cause a compile-time or
run-time error, it's not a legal modification value.

Chapter 6, Using the integrated debugger

113

Warning!

Inspecting data
elements

• You can't directly modify untyped arguments passed into a function, but
you can typecast them and then assign new values.
• You can use the Expression Evaluator dialog box to examine and modify
values in registers, including the flags register. For example, you can
enter expressions such as these: _CS,_BX,_FLAGS. These values are
bitmasks.
• Modifying values, and especially pointer values and array indexes, can
have undesirable effects because you might overwrite other variables
and data structures. Be careful.
You can examine and modify values in a data element in an Inspector
window. To inspect a data element,
1. Choose Debug I Inspect to display the Data Inspector window.
2. Type in the expression you want to inspect.
3. Choose Inspect to display an Inspector window.

If the execution point is in the scope of the expression you are inspecting,
the value appears in the Data Inspector window. If the execution point is
outside the scope of the expression, the value is undefined.

You can also display an Inspector directly from the edit window:
1. Po~ition your cursor on the data element you want to inspect.
2. Choose Inspect on the SpeedMenu or press Enter.
~f you choose this method, the data element is always evaluated within the
scope of the line on which the data element appears.

With either method, the appearance of the data in an Inspector window
depends on the type of data being inspected. For example, if you inspect an
array, you'll see a line for each member of the array with the array index of
the member. The value of the member follows in its display format,
followed by the value in hexadecimal.
Once you're in an Inspector window, you can inspect certain elements to
isolate the view. To inspect an item,
, 1. Select the item you want to inspect further.
2. Choose Inspect on the SpeedMenu or press Enter.

114

Borland C++ Users Guide

You can change the value of inspector items. To change the value of a
single inspector item:
1. Select the item.
2. Choose Change on the SpeedMenu.
3. Type.in a new value and choose 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 you're interested in. For easier viewing, you can
narrow the display to a range of data items.

To display a range of items,
1. Click in the Inspector window.
2. Choose Range on the SpeedMenu.
3. In the Start Index box, enter the index of the item you want to see first in
the window.
4. In the Count box, enter the number of items you want to see in the
Inspector window.
Examining
register values

While debugging, you can display the values in the data, pointer, index,
segment, and instruction pointer registers, as well as the settings of the
status word or flags. Choose View I Register to display the Registers
window.
You can also view register values with the Expression Evaluator dialog box.
See page 114.

Table 6.2
CPU flags in the
Register window

Letter in pane
c

z
s
0

p
a
i
d

Flag name
Carry
Zero
Sign
Overflow
Parity
Auxiliary carry
Interrupt enable
Direction

The Registers SpeedMenu lets you select the format to display the values in
the registers; choose from Hexadecimal or Decimal. You can also choose to
view the 16-bit (word) or 32-bit (double word) registers.

Chapter 6, Using the integrat~d debugger

115

Using breakpoints
A breakpoint is a designated position in the code where you want the
program to stop executing and return control to the debugger. A
breakpoint is similar to the Run to Cursor command, because the program
runs at full speed until it reaches a certain point But unlike Run to Cursor,
you can have multiple breakpoints and you can choose to stop at a
. breakpoint only under certain conditions.
Setting
breakpoints

To set a breakpoint in your code, move the cursor to the line where you
want to break. The line needs to contain executable code-if it's a comment,
a blank line, or a declaration, the debugger will declare it invalid. To select
the line as a breakpoint, choose Toggle Breakpoint (F5) on the Debug menu
or the edit window SpeedMenu; the line becomes highlighted.
Now when you run your program from the IDE it will stop whenever it
reaches that line, but before it executes the line. The line containing the
breakpoint shows in the edit window with the execution point on it. At that
point, you can do any other debugging actions such as stepping, tracing,
watching, inspecting, and evaluating.
To delete a breakpoint, move the cursor to the line containing the
breakpoint and choose Toggle Breakpoint(F5) from the Debug menu or the
edit window SpeedMeny.

Working with
breakpoints

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 window, so you don't have to search through
your source code files looking for them. Choose View I Breakpoint to
display the Breakpoint window.

Figure 6.3
The Breakpoint
window

From the Breakpoint window, you can set and view breakpoint properties.
, Double-click a breakpoint in the Breakpoint window, or select it and select
Set Properties from the SpeedMenu. A Breakpoint Properties dialog box
appears.

116

Borland C++ Users Guide

Figure 6.4
The Breakpoint
Properties dialog box

Breakpoint Properties

~
~WiMfl!f
~
Stale: Verified,
~-=;....,
1 '" hin,eNUmber:
168, ",,',

L,,'-

!~~~t~:;t;;;i:~:~Cr-_ak_po_in_t_---__------,
[~-f~;~~~:-Il

,I[!L

rActlonS:'---:-'~-----:-:::--'-;--~--------·---------0

.' E~renjon to log: ", ", "
" " , ,::1
lhJ~o~i~~r~$~~~,n. J. . ".,' ",.' "'.q,."""", .",.",.".",I~n
t~

Deleting
breakpoints

.Ilreak

To delete a breakpoint, select it in the Breakpoint window and choose
Delete Breakpoint on the SpeedMenu. To delete all breakpoints, choose
Delete All on the SpeedMenu.
You can also delete breakpoints with the Delete Breakpoint and Delete All
Breakpoints commands on the Breakpoint Properties SpeedMenu.

Disabling and
enabling
breakpoints

You can disable breakpoints temporarily. The simplest way is to uncheck
the check box for the breakpoint you want to disable in the Breakpoint.
When you want to enable the breakpoint again, check the breakpoint's
check box again.
You can also disable and enable breakpoints with SpeedMenu commands.
To disable or enable multiple breakpoints at a time, click and drag over a
block of breakpoints to select them in the Breakpoint window, or press etrl
while you click all breakpoints you want to disable or enable. Then choose
the appropriate command on the SpeedMenu.

Viewing and editing
code at a breakpoint

Even if a breakpoint isn't in your current edit window, you can quickly find
a breakpoint in your source code. To do so, select the breakpoint in the
Breakpoint window, then choose View Source on the SpeedMenu. The
breakpoint appears in the current edit window with your cursor positioned
on the breakpoint. The Breakpoint window remains open and is the active
window.
If you prefer to edit the source code marked as a breakpoint rather than just

view it, choose Edit Source on either the Breakpoint window SpeedMenu.
The breakpoint appears in the current edit window with your cursor
positioned on the breakpoint, ready for you to edit.

Chapter 6, Using the integrated debugger

117

Resetting invalid
breakpoints

Breakpoints must be set on executable code, or they are invalid. For
example, a breakpoint set on a comment, a blank line, or declaration is an
invalid breakpoint. If you unintentionally set an invalid breakpoint and run
your application, the debugger checks all breakpoints and reports an
invalid breakpoint by displaying an Invalid Breakpoint dialog box. Close
the dialog box and open the Breakpoints window. Find the invalid
breakpoint and delete it; if you want to set the breakpoint in a proper
location, do so now. Then continue to run your application.
You can choose to ignore the Invalid Breakpoint dialog box by putting the
dialog box away and choosing Run to continue to execute your program.
Your application will resume and the IDE will disable the invalid
breakpoint.

Changing
breakpoint
properties

To see and change the properties of a breakpoint, double-click it, or select it
in the Breakpoint window and choose Edit Breakpoint on the SpeedMenu.
A Breakpoint Properties dialog box appears.
Besides examining a breakpoint's properties, you can use a Breakpoint
Properties dialog box to do such things as set a new breakpoint, modify an
existing breakpoint, and make a breakpoint conditional.
The next sections explain how to do these things.
Setting a breakpoint
Although using Toggle Breakpoint on the edit window SpeedMenu is the
simplest way to set a breakpoint, there are times you might want to set a
breakpoint using the Breakpoint Properties dialog box, especially if you
want to create a conditional breakpoint:
1. Position the cursor where you want the breakpoint to occur.
2. Choose Add Breakpoint on either the Debug menu or the Breakpoints
SpeedMenu.
.
A Breakpoint Properties dialog box appears.

You can also set a breakpoint in a file that is not open in an edit window:
1. In the Breakpoint Properties dialog box, type the name of the file you
want the breakpoint set in.
'
2. In the Line Number box, ent.er the line number of your code where you
want the breakpoint to appear.

118

Borland C++ Users Guide

Modifying an existing breakpoint
You can modify an existing breakpoint by changing its properties in the
Breakpoint Properties dialog box. Enter new information for the properties
you want to alter.
Setting breakpoints after starting a program
While your program is running, you can switch to the debugger (just like
you would switch to any Windows application) and set a breakpoint. When
you return to your application, the new breakpoint will be set, and your
application will halt when it reaches the breakpoint.
Creating conditional breakpoints
The breakpoints added by the Toggle Breakpoint command on the edit
window SpeedMenu are unconditional: any time you get to that line, the
debugger stops. When you're editing a new or existing breakpoint,
however, you have extra options in the Breakpoint Properties dialog box
that let you create conditional breakpoints. You can put two kinds of
conditions on breakpoints: Boolean conditions and number of passes.

You can enter a Boolean expression as a condition for a breakpoint. For
example, you might test if a variable falls in a certain range, or if a
particular flag has been set. When the specified condition is met, the
debugger breaks, turning control over to you.
Specifying a number of passes on a breakpoint tells the debugger not to
break every time it reaches the-specified condition, but instead to break
only the nth time the specified condition is met. That is, if the pass count is
3, the debugger breaks only the third time the specified condition is met. If
you don't specify a condition, the debugger breaks every time the line of
code executes.
Logging
expressions

You can choose to have the value of a specified expression written in the
Event Log window each time a breakpoint is reached:
1. Select Log Expression in the Breakpoint Properties dialog box.
2. In the Expression to Log box, type the expression you want evaluated.

For example, if you type the name of a variable in the Expression to Log
box in the Breakpoint Properties dialog box, the debugger writes the value
of that expression in the Event Log window when it reaches your set
breakpoint.
For more information about the Event Log window, see the "Using the
Event Log window" section.

Chapter 6, Using the integrated debugger

119

Customizing
breakpoints and
the execution
point

You can use color to indicate enabled, disabled, and invalid breakpoint
lines:
1. Choose Options I Environment and choose Syntax Highlighting I
Customize Syntax Highlighting.
2. From the Element list, select the Break element you want to change and
then change the background and foreground to the colors you want.
To read more about using syntax highlighting, see page 14.
You can also change the color of the execution point. To do so, select the
Execution Point element and then select your desired colors.

Catching general protection faults
If a general protection exception (GP exception) occurs while running your
program in the IDE, your program halts and a General Protection
Exception dialog box appears. If you choose OK to close the dialog box, the
debugger displays the code that is responsible for the GP exception in the
edit window. The execution point marks the offending code.

At this point, you must choose Debug I Terminate Program to prevent your
program from crashing. Then you can correct the error that caused the
problem before you run your program again.
Although the debugger can catch most GP exceptions, it might fail to catch
all of them, depending on the cause of the exception.

Using the Event Log window
To display the Event Log window, choose View I Event Log.
In the previous section, you saw how to log expressions you've specified
when the debugger reaches a breakpoint to the Event Log window.
You can also log window messages and output messages to the Event Log
window. To select the events you want to log, choose Set Options on the
Event Log window SpeedMenu. Select the Debugger topic and then select
the Event Capture options you want.

120

Borland C++ Users Guide

The following table describes all the commands on the Event Log window
SpeedMenu:
Table 6.3
Event Log window
Speed Menus

Command

Description

Save Events to File

Displays a dialog box so you can specify a file name. All events that
are currently in the Event Log window are saved in that file, so you
can examine the events later.

Add Comment

Prompts you for a line of text that is inserted in the Log window as a
comment.

Clear Events

Clears the Event Log window.

Set Options

Displays Environment Options dialog box, so you can select
Debugger options and set the Event Capture options you want.

Debugging dynamic-link libraries
When you step or trace into a DLL your application uses, the debugger
automatically loads the DLL's symbol table, which is the list used to track
all the variables, constants, types, and function names used in the DLL.
Because only one symbol table can be loaded into memory at a time, your
.EXE's symbol table is unloaded when a DLL's symbol table is loaded.
Therefore, you won't be able to watch variables, inspect data, and so on in
the source code of the .EXE. You will, of course, be able to perform these
operations on the DLL code.
To see which symbol table the debugger is using, choose Debug ILoad
Symbol Table. You'll see a listing of the current symbol table and any
others that are available. For example, if your .EXE is named MYAPP .EXE
and it uses a MYDLL.DLL, then when you are stepping in the DLL,
MYDLL.DLL is the current symbol table and the MYAPP.EXE symbol table
is listed as available.
You can switch between symbol tables. For example, if you're stepping in
MYDLL.DLL and want to examine the value of a variable that's in
MYAPP.EXE, you can do so by loading the MYAPP.EXE symbol table:
1. Choose Debug ILoad Symbol Table.
2. Choose the symbol table you want to load from the Available list of
symbol tables.

Once you've examined the variable and want to resume stepping, you must
switch back to the original symbol table.

Chapter 6, Using the integrated debugger

121

Debugging in soft and hard mode
Windows is continually processing and generating messages. Any
executing Windows program, such as Borland C++ for Windows, must do
the same. When you run your own Windows programs, they too send
messages and process messages they receive.
When you set a breakpoint in your code, however, you want your program
to stop executing when it reaches the breakpoint. But in the Windows
environment, just doing such things as resizing a window, opening a dialog
box, moving the mouse cursor, or opening a menu generates Windows
messages that are sent to your executing program. Unless the debugger
handles these messages for you, the messages could force your program to
execute or possibly to lock up your system.
Fortunately, the integrated debugger handles the majority of these
situations for you, thus freeing you to debug your program while using the
full functionality of the Windows environment. When the debugger works
simultaneously with other Windows programs, it is said to be in soft mode.
Because of limitations in Windows, you might occasionally need to stop all
other Windows programs except the debugger from executing. This state is
called hard mode. When the debugger is in hard mode, you won't be able to
use the functionality of the Windows environment. For example, you won't
be able to switch to another task. The debugger behaves as if it's the only
program in memory.
You'll want to debug your programs in hard mode if they send inter task
messages such as DOE messages and for other very low-level debugging.
To change to hard mode,
1. Choose Options IEnvironment to open the Environment Options dialog
box.
2. Choose Debugger.
3. Select the Hard Mode on All Stops option.
When the Smart option is selected, the debugger chooses hard or soft
mode, depending on what is happening in the Windows environment. This
is the option you'll want tq use most frequently. To use the Smart option,
1. Choose Options I Environment.
2. Choose Debugger.
3. Select the Smart option.

122

Borland C++ Users Guide

c

H

A

p

T

E

R

7

WinSight
WinSight is a debugging tool that gives you information about windows,
window classes, and 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.

Getting started

~

r~

WinSight

To start WinSight, double-click the WinSight icon. 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 127) and you
can control when messages start and stop tracing as described in the
following sections.

Starting and
stopping screen
updates

Chapter 7, WinSight

To tum 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 to suspend tracing of messages
only (Class List and Window Tree will continue to update).

123

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 application. Choose Spy IExit to leave
WinSight.
.

ChQosing 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
A class is the name
with which the
window class was
registered with
Windows.

124

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.

Borland C++ Users 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 turn 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.

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
mixed 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 turn off all message tracing to the Message
view.

Window Tree
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.

Chapter 7, WinSight

125

• 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.
The diamond next to each window shows whether the window has any
children. When a window receives a message, the diamond next to it (or its
parent window if the tree is collapsed) turns black.
The window has no children.
The window has children but they aren't 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.
The window has children displayed (at least one level of child windows is
visible; further levels might be collapsed). To hide all of a window's child
windows, click (or double-click) the diamond next to the window.
Format

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 .OLL) 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 theparent'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

126

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.

Borland C++ User's Guide

Important! All other
applications are
suspended while
you're in Find
Window mode.

Enter Find Window mode by choosing Spy I Find 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

Spying on
windows

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.
To spy on one or more windows, select the windows (using the mouse and
the Shift or etr/key), then choose Messages I Selected 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 I All Windows.
Message Trace becomes visible when you choose Messages I Selected
Windows or Windows I All Windows.
Choose Messages I Trace 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

Chapter 7, Win Sight

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:

127

• Choose Messages I Selected Classes or Messages I Selected Windows, then
select the classes (in the Class List view) or windows (in the Window
Tree view) by using the mouse and Shift or Gtr!.
• Choose Message I All Windows.
• Choose Message I Options, then select any or all of fourteen groups of
messages (the groups are described in Tables 7.1 through 7.14). Check All
Messages in the Options dialog box to return to tracing all messages.
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.

Other tracing
options

• 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 IParam.
• 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.
• Type the name of the device (for example, type PRN) for the log file to
send output to the printer port.
• Type AUX to output trace messages to an auxiliary monitor or
window. To do this, you must have WINOX.SYS or OX.SYS installed
as a device in your CONFIG.SYS file.
To stop logging message traces to a file, printer, or auxiliary monitor,
uncheck Log File.
u

Format

Handle ["Title" or {Class} 1 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 (userdefined) 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.

128

Borland C++ Users Guide

Status is one or more of the following:
• Dispatched indicates the message was received via DispatchMessage.
• Sent [from XXXXl 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 7.1: Mouse messages
WM_HSCROLL
WM_LBUTTONDBLCLK
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MBUTTONDBLCLK
. WM_MBUTTONDOWN

WM_MBUTTONUP
WM_MOUSEACTIVATE
WM_MOUSEFIRST
WM_MOUSELAST
WM_MOUSEMOVE
WM_RBUTTONDBLCLK

WM_RBUTTONDOWN
WM_RBUTTONUP
WM_SETCURSOR
WM_VSCROLL

WM_GETDLGCODE
WM_GETFONT
WM_GETMINMAXINFO
WM_GETTEXT
WM_GETTEXTLENGTH
WMJCONERASEBKGND
WM_KILLFOCUS
WM_MOVE
WM_PAINT
WM_PAINTICON
WM_QUERYDRAGICON
WM_QUERYENDSESSION

WM_QUERYNEWPALETTE
WM_QUERYOPEN
WM_QUIT
WM_SETFOCUS
WM_SETFONT
WM_SETREDRAW
WM_SETTEXT
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

Table 7.2: Window messages
WM_ACTIVATE
WM_ACTIVATEAPP
WM_CANCELMODE
WM_CHILDACTIVATE
WM_CLOSE
WM_CREATE
WM_CTLCOLOR
WM_DDE_FIRST
WM_DESTROY
WM_ENABLE
WM_ENDSESSION
WM_ERASEBKGND
Table 7.3: Input messages
WM_CHAR
WM_CHARTOITEM
WM_COMMAND
WM_DEADCHAR
WM_KEYDOWN
WM_KEYLAST

Chapter 7, WinSight

129

Table 7.4: System messages
WM_COMPACTING
WM_DEVMODECHANGE
WM_ENTERIDLE
WM_FONTCHANGE
WM_NULL

WM_PALETTECHANGED
WM_PALETTEISCHANGING
WM_POWER
WM_QUEUESYNCH
WM_SPOOLERSTATUS

WM_SYSCOLORCHANGE
WM_SYSCOMMAND
WM_TIMECHANGE
WM_WININICHANGE

WMJNITMENU

WMJNITMENUPOPUP

WM_DESTROYCLIPBOARD
WM_DRAWCLIPBOARD
WM_HSCROLLCLIPBOARD
WM_PAINTCLIPBOARD
WM_PASTE

WM_RENDERALLFORMATS
WM_RENDERFORMAT
WM_SIZECLIPBOARD
WM_UNDO
WM_VSCROLLCLIPBOARD

WM_DDE_EXECUTE
WM_DDEJNITIATE
WM_DDE_POKE

WM_DDE_REQUEST
WM_DDE_TERMINATE

WM_NCLBUTTONDOWN
WM_NCLBUTTONUP
WM_NCMBUTTONDBLCLK
WM_NCMBUTTONDOWN
WM_NCMBUTTONUP
WM...NCMOUSEMOVE

WM_NCPAINT
WM_NCRBUTTONDBLCLK
WM_NCRBUTTONDOWN
WM_NCRBUTTONUP

DM_MODIFY
DM_ORIENTATION
DM_OUT_BUFFER
DM_OUT_DEFAULT
DM_PAPERLENGTH
DM_PAPERSIZE
DM_PAPERWIDTH

DM_PRINTQUALITY
DM_PROMPT
DM_SCALE
DM_SPECVERSION
DM_TTOPTION
DM_UPDATE
DM_YRESOLUTION

Table 7.5: Initialization messages
WMJNITDIALOG
Table 7.6: Clipboard messages·
WM_ASKCBFORMATNAME
WM_CHANGECBCHAIN
WM_CLEAR
WM_COPY
WM_CUT
Table 7.7: DDE messages
WM_DDE_ACK
WM_DDE_ADVISE
WM_DDE_DATA

WM_DDE~UNADVISE

Table 7.8: Nonclient messages
WM_NCACTIVATE
WM_NCCALCSIZE
WM_NCCREATE
WM_NCDESTROY
WM_NCHITTEST
WM_NCLBUTTONDBLCLK
Table 7.9: Print messages
DM_COLOR
DM_COPIES
DM_COPY
DM_DEFAULTSOURCE
DM_DUPLEX
DMJN_BUFFER
DMJN_PROMPT

130

Borland C++ Users Guide

Table 7.10: Control messages
BM_GETCHECK
BM_GETSTATE
BM_SETCHECK
BM_SETSTATE
BM_SETSTYLE
BN_CLlCKED
BN_DISABLE
BN_DOUBLECLICKED
BN_HILITE
BN_PAINT
BN_UNHILITE

CBN_SELCHANGE
CBN_SELENDCANCEL
CBN_SETFOCUS
DM_GETDEFID
DM_SETDEFID

CB_ADDSTRING
CB_DELETESTRING
CB_DIR
CB_FINDSTRING
CB_FINDSTRINGEXACT
CB_GETCOUNT
CB_GETCURSEL
CB_GETDROPPEDCONTROLRECT
CB_GETDROPPEDSTATE
CB_GETEDITSEL
CB_GETEXTENDEDUI
CB_GETITEMDATA
CB_GETITEMHEIGHT
CB_GETLBTEXT
CB_GETLBTEXTLEN
CBJNSERTSTRING
CB_LlMITIEXT
CB_MSGMAX
CB_RESETCONTENT
CB_SELECTSTRING
CB_SETCURSEL
CB_SETEDITSEL
CB_SETITEMDATA
CB_SETITEMHEIGHT
CB_SHOWDROPDOWN

EM_CAN UNDO
EM_EMPTYUNDOBUFFER
EM_FMTLlNES
EM_GETFIRSTVISIBLELINE
EM_GETHANDLE
EM_GETLINE
EM_GETLINECOUNT
EM_GETMODIFY
EM_GETPASSWORDCHAR
EM_GETRECT
EM_GETSEL
EM_GETIHUMB
EM_GETWORDBREAKPROC
EM_LlMITIEXT
EM_LlNEFROMCHAR
EM_LlNEINDEX
EM_LlNELENGTH
EM_LlNESCROLL
EM_MSGMAX'
EM_REPLACESEL
EM_SCROLL
EM_SETFONT
EM_SETHANDLE
EM_SETMODIFY
EM_SETPASSWORDCHAR
EM_SETRECT
EM_SETRECTNP
EM_SETSEL
EM_SETIABSTOPS
EM_SETWORDBREAK
EM_UNDO

CBN_CLOSEUP
CBN_DBLCLK
CBN_DROPDOWN
CBN_EDITCHANGE
CBN_EDITUPDATE
CBN_ERRSPACE
CBN_KILLFOCUS

EN_CHANGE
EN_ERRSPACE
EN_HSCROLL
EN_KILLFOCUS
EN_MAXTEXT
EN_SETFOCUS
EN_UPDATE

Chapter 7, WinSight

EN_VSCROLL
LB_ADDSTRING
LB_DELETESTRING
LB_DIR
LB_FINDSTRING
LB_FINDSTRINGEXACT
LB_GETCARETINDEX
LB_GETCOUNT
LB_GETCURSEL
LB_GETHORIZONTALEXTENT
LB_GETITEMDATA
LB_GETITEMHEIGHT
LB_GETITEMRECT
LB_GETSEL
LB_GETSELCOUNT
LB_GETSELITEMS
LB_GETTEXT
LB_GETTEXTLEN
LB_GETTOPINDEX
LBJNSERTSTRING
LB_MSGMAX
LB_RESETCONTENT
LB_SELECTSTRING
LB_SELlTEMRANGE
LB_SETCARETINDEX
. LB_SETCOLUMNWIDTH
LB_SETCURSEL
LB_SETHORIZONTALEXTENT
LB_SETITEMDATA
LB_SETITEMHEIGHT
LB_SETSEL
LB_SETTABSTOPS
LB_SETTOPINDEX
LBN_DBLCLK
LBN_ERRSPACE
LBN_KILLFOCUS
LBN_SELCANCEL
LBN_SELCHANGE
LBN_SETFOCUS
STM_GETICON
STM_SETICON

131

Table 7.11: Pen messages
WIN_USER
WM_GLOBALRCCHANGE
WM_HEDITCTL

WM_HOOKRCRESULT
WM_PENWINFIRST
WM_PENWINLAST

WM_RCRESULT
WM_SKB

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_MPU40CMIDIIN
MM_MPU40CMIDIOUT
MM_PC_JOYSTICK

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

Table 7.12: Multimedia messages
MM_ADLIB
MM_JOY1 BUTTON DOWN
MM_JOY1 BUTTONUP
MM_JOY1 MOVE
MM_JOY1 ZMOVE
MM_JOY2BUTTONDOWN
MM_JOY2BUTTONUP
MM_JOY2MOVE
MM_JOY2ZMOVE
MM_MCINOTIFY
MM_MICROSOFT
MM_MIDI_MAPPER
Table 7.13: Other messages
WM_COALESCE_FIRST
WM_COALESCE_LAST
WM_COMMNOTIFY
WM_COMPAREITEM
WM_DELETEITEM
WM_DRAWITEM
WM_DROPFILES
WM_KEYFIRST

WM_MDIACTIVATE
WM_MDICASCADE
WM_MDICREATE
WM_MDIDESTROY
WM_MDIGETACTIVE
WM_MDIICONARRANGE
WM_MDIMAXIMIZE
WM_MDINEXT

WM_MDIRESTORE
WM_MDISETMENU
. WM_MDITILE
WM_MEASUREITEM
WM_NEXTDLGCTL
WM_SYSTEMERROR

Table 7.14: Messages not documented by Microsoft
WM_ALTTABACTIVE
WM_BEGINDRAG
WM_CONVERTREQUEST
WM_CONVERTRESULT
WM_DRAGLOOP
WM_DRAGMOVE
WM_DRAGSELECT
WM_DROPOBJECT
WM_ENTERMENULOOP

132

WM_ENTERSIZEMOVE
WM_EXITMENULOOP
WM_EXITSIZEMOVE
WM_FILESYSCHANGE
WM_GETHOTKEY
WM-,SACTIVEICON
WM_LBTRACKPOINT
WM_NEXTMENU
WM_QUERYDROPOBJECT

WM_QUERYPARKICON
WM_SETHOTKEY
WM_SETVISIBLE
WM_SIZEWAIT
WM_SYNCPAINT
WM_SYNCTASK
WM_SYSTIMER
WM_TESTING
WM_YOMICHAR

Borland C++ Users Guide

c

H

A

p

T

E

R

8

WinSpector
WinSpector and its utilities help you perform a postmortem examination 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 ill the call stack
CPU registers
A disassembly of the machine instructions where the exception occurred
Windows information about the program environment

Using WinSpector
Before using WinSpector, be sure that TOOLHELP.DLL (from Windows 3.1
or later) is in your search path (TOOLHELP.DLL ships with Borland C++).
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.

,.
[I
"".;~~ .

.

::'+; ,;,\

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 139 for more information on DFA.EXE).

Chapter 8, WinSpector

133

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.
Configuring
WINSPCTR.LOG

There are two ways you can set the WinSpector options that control the
output to WINSPCTR.LOG:
_ To use the WinSpector Preferences dialog box, start WinSpector, click the
WinSpector icon and choose Preferences from the popup menu.
_ To edit commands in WINSPCTR.lNI,load the file into any text editor,
edit or add commands, then save the file and restart WinSpector.
The following sections describe each option in the Preferences dialog box.
WINSPCTR.INI options are listed to the left.

LogDir=[directory]

_ Directory is the location of WINSPCTR.LOG. Type the path where you

want the file (C: \ WINDOWS is the default).
LogViewer=[viewername] '_ 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, C: \ WIN31 \ WRITE.EXE. If WinSpector can't find
the editor, it displays the message
Error: Unable to execute: [option]

CreateNewLog=
o(append) or
1 (overwrite)
ShowSystemlnfo=

o(omit) or 1 (show)

LogToStdAux=O (on)
or 1 (off)

PostMortemDump=
1 (show) or 0 (omit)
, ShowStacklnfo=
1 (show) or 0 (omit)

134

where option is the editor file name. Check to make sure the editor you
indicated exists in the specified directory.
_ 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.
_ Check System Information to add the Task List, the Module List, and
information about the USER and GDI heaps to the log file.
_ 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.
_ Check PostMortem Dump to generate a WINSPCTR.BIN file. Use
DFA.EXE to translate the BIN file into a text file you can read.
_ 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.

Borland C++ Users Guide

It is 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.
• 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.

ShowUserlnfo=
1 (show) or 0 (omit)

WINSPCTR.LOG
reference

Each report in WINSPCTR.LOG 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 (Table 8.1 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)

(TASK=BAD)

Table 8.1: Exception types

Number

Name

Description

o

Division by zero

Occurs during a DIV or an IDIV interaction if the divisor is O.

12

Stack' fault

Usually occurs when there is ~ot enough room on the stack to proceed.

13

General protection fault (GPF)

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.

Chapter 8, WinSpector

135

• Accessing DS, ES, FS, or GS registers containing a null selector. (This
error can cause a 0 to 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 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

Stack Trace section

CMP
JNE
CMP
MOV

BYTE PTR ES: [BX1,FF
043A
WORD PTR [BP+061,03
DI, 0001

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

136

Borland C++ Users Guide

• 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 .sYM 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 .SYM 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 ~ample task, caused an exception:
Stack Trace:
o User 
CS:IP 002A:0429 (079F:0429)
C:\W1N31\SYSTEM\USER.EXE

SS:BP 10FF:18CA

BAD function5(unsigned long, unsigned long, unsigned long) + 0014
CS:IP 0001:0184 (1107:0184)
SS:BP 10FF:1952
C:\BIN\BAD.EXE

Register section

The Register section in WINSPCTRLOG lists the values stored in the
standard registers when the exception occurred, as the following example
shows:
Registers:
AX
0037
BX
0000
cx
0008
DX
10EE
SI
0037
D1
0028

Limits and access rights are given for the CS, DS, ES, and SS registers.
Message Queue
section

Chapter 8, WinSpector

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 information:

137

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.

Tasks section

• The Window handle that identifies the destination window
• The Message ID number that identifies the message
• Two parameters that contain additional message information
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

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:\WIN31\SYSTEM\NWPOPUP.EXE
Module: NWPOPUP
hModule: 142F

hTask: 141F

hlnstance: 13F6

C:\BIN\WINSPCTR.EXE
Module: WINSPCTR

hTask: 1387

hlnstance: 13SE

C:\BIN\BAD.EXE
Module: BAD

Modules section

hModule: 1397

hModule: 1467

hTask: 1127

hlnstance: 10FE

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

138

Borland C++ User's Guide

C:\WIN31\SYSTEM\KRNL386.EXE
Date: 03/02/1992 Size: 116132
Module: KERNEL hModule: 010F reference count: 21
C:\WIN31\SYSTEM\SYSTEM.DRV
Date: 03/01/1992 Size: 2304
Module: SYSTEM hModule: 013F reference count: 13
C:\C\BIN\WINSPCTR.EXE
Date: 06/02/1992 Size: 46256
Module: WINSPCTR 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
,
•
•
•
•
•

CPU type
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

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 WINSPCTR.BIN file and Turbo Debugger
information (either in the .EXE, .DLL or .TDS files) and translates the binary

Chapter 8, WinSpector

139

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 lo~al 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 134), WinSpector creates a WINSPCTR.BIN 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 WINSPCTR.BIN 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 WINSPCTR.BIN and WINSPCTR.LOG files before
continuing.
DFA output

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
•
•
•
•

Using DFA with
WINSPCTR.LOG

Using DFA with
WINSPCTR.BIN

Function names
Line numbers
Local and global variables
Data segments and their values (including the stack segment)

When DFA is used with the WINSPCTR.LOG file alone, it gives minimal
stack trace information, such as addresses. If Turbo Debugger information
(contained in a .EXE, .DLL, or .TDS file) is present, source file names and
line numbers are added to the report.
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

140

• Local variables
• Parameters

Bor/and c++ Users Guide

• In section two, the

•
•
..
•
•

Module name for the task with the fault
File names
Logical segments
The segments' selectors
Whether the segments are data or code segments

• In section three, the

• Global variables
.' Static variables
• The variables' values at the time of the exception
Format

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 8.2
DFA options

Option

What it does

IO[outputfile]
10

Renames the output file from the DFA.OUT default
Forces DFA to write a hex dump of the saved data segments

Other WinSpector t0915
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 .sYM
file from a .MAP file.
• BUILDSYM.EXE uses EXEMAP .EXE and TMAPSYM.EXE to create a
.SYM file from a Windows .EXE file.
Using
EXEMAP.EXE

Chapter 8, WinSpector

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.

141

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 .SYM files from existing .MAP files (created either by
the compiler or by the EXEMAP utility). The resulting .SYM 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 TMAPSYM-generated .SYM file.
To create a .SYM file from a .MAP file, type
type the .MAP extension).

Using
BUILDSYM.EXE

TMAPSYM filename . MAP

(you must

BUILDSYM creates .SYM 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
.SYM 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 .SYM files.
• Deletes the .MAP files because they are no longer needed.

To create a .SYM file from an .EXE, type

BUILDSYM filename.EXE.

Conveniently, you can use DOS wildcards in the filename portion of the
syntax. For example, type BUILDSYM *. EXE to create .SYM files for all the .EXE
files in the current directory.

142

Borland C++ Users Guide

c

H

A

p

T

E

R

9

Using the linker: TLINK
Appendix A, "Error
messages," lists
linker messages
generated by TLiNK
and by the built-in
IDE linker.

TLINK and TLINK32 are command-line tools that combine object modules
(.OBJ files) and library modules (.LIB files) to produce executable files. The
IDE uses built-in versions of the linkers. Because the compiler
automatically calls the linker, you don't need to use TLINK unless you
suppress the linking stage of compiling (see the -c compiler option). Unless
otherwise specified, instructions and options for TLINK also apply to
TLINK32.

TLINK basics
TLiNK and TLlNK32
options are casesensitive.

TLINK uses a configuration file called TLINK.CFG, a response file
(optional), and command-line options to link object modules, libraries, and
resources into an executable file (.EXE or .DLL). The IDE linker uses the
options specified in the Project Options dialog box in the Linker section.
The syntax for TLINK is
TLINK [@respfile] [options] startupfile myobjs, exename, [mapfile],
[mylibs] runtimelib [import], [deffile], [resfiles]

where
• options are TLINK options that control how TLINK works. For example,

See Tables 9.1 and
9.2 to determine
which module to use.

options specify whether to produce an .EXE or a DLL file. TLINK options
must be preceded by either a slash (/) or a hyphen (-). To turn off a
default option,-place a hyphen after the option (for example, -P-).
Table 9.3 lists the TLINK options .
• startupfile is a Borland initialization module for executables or DLLs
that arranges the order of the various segments of the program. The
initialization module must appear first in the object file list. If it isn't first,
the program segments might not be placed in memory properly, which
could cause some frustrating program bugs. Failure to link the correct
initialization module usually results in a long list of error messages
telling you that certain identifiers are unresolved, or that no stack has
been created.

Chapter 9, Using the linker: TUNK

143

_ myobj s are the .OB] files you want linked. Specify the path if the files

aren't in the current directory.
_ exename is the name you want given to the executable file (.EXE or .DLL).
If you don't specify an executable file name, TLINK derives the name of
the executable by appending .EXE or .DLL to the first object file name
listed. Be sure you give an explicit name for the executable file name on
the TLINK command line. Otherwise, your program name will be
something like .C02.EXE-which probably isn't what you wanted.
_ mapfile (optional) is the name you want given to the map file. If you
don't specify a name, the map file name is given the same asexefile (but
with the .MAP extension).
_ mylibs (optional) are the library files you want included at link time. If
these files aren't in the current directory or the search path (see the IL
option) then you must include their paths.
_ runtimelib is the Borland run-time library. If no libraries are included,
none are linked.
_ importlib is the Windows import library, which provides access to the
Microsoft Windows API functions.
_ deffile is the module-definition file (.DEF) for a Windows executable. If
you don't specify a .DEF file, TLINK creates an application based on
default settings.
_ resfiles are a list of .RES files to bind to the executable.
TLINK assumes or appends these extensions to file names that have none:
_ .OB] for object files
_ .LIB for library files
_ .EXE for executable files
_ .DEF for module-definition
files
_ .DLL for dynamic-link libraries
_
.RES for resource files
_ .MAP for map files
TLlNK.CFG
The IDE uses linker
options specified in
project options and
style sheets. See
Chapter 2 for more
information on setting
options for project.

144

TLINK uses a configuration file called TLINK.CFG (or TLINK32.CFG) for
options that you'd normally type at the command-line (note that
TLINK.CFG can only be options, not file names). Configuration files let you
save options you use frequently, so that you don't have to continually
retype them.
TLINK looks for TLINK.CFG in the current directory, then in the directory
from which TLINK was loaded.
The following TLINK.CFG file tells TLINK to look for libraries first in the
directory C: \ BC4 \ LIB and then in C: \ WINAPPS \ LIB, to include debug

Borland C++ Users Guide

information in the executables it creates, to create a detailed segment map,
and to produce a Windows executable (.EXE not .DLL).
TLINK

TLINK32

ILC:\bc4\libic:\winapps\lib

ILc:\bc4\libi c:\winapps\lib

Iv Is

Iv Is
ITpe

ITwe

Response files
The command-line
compilers also use
response files. See
page 45 for more
information.

Response files are ASCII files of options and file names for TLINK.EXE
(and TLINK32.EXE) that you would normally type at the command line.
Response files let you have a longer command line than most operating
systems allow. Response files can include the same information as
configuration files (command-line options), but they can also contain file
names.
Unlike the command line, a response file can be several lines long. To use
more than one line in your response file, end each line with a plus character
(+). Note that if a line ends with an option that uses the plus to turn it on
(such as /v+), the + isn't treated as a line continuation character (to continue
the line, use Iv++).
If you separate command-line components (such as .OBJ files from .LIB
files) by lines in a response file, you must leave out the comma used to
separate them on the command line. For example,
Ic

cOWSt

rnyprog,rnyexe
rnyrnap
rnylib cws

leaves out the commas you'd have to type if you put the information on the
command line:
TLINK Ic cOws rnyprog,rnyexe,rnyrnap,rnylib cws

To use response files,
1. Type the command-line options and file names into an ASCII text file
and save the file.
2. Type TLINK @[path]RESFILE.RSP, where RESFILE.RSP is the name of your
response file.
You can specify more than one response file as follows:
tlink Ic @listobjs,rnyexe,rnyrnap,@listlibs

If you use a response file in addition to command-line options, the
command-line options will override any options in the response file. For

Chapter 9, Using the linker: TLINK

145

example, if you include -v in a response file, but you use -v- at the
command-line, TLINK uses the command-line option -v-.
Using TLiNK with
BCC.EXE
BCC always starts
TLiNK with the Ic
(case-sensitive link)
option.

You can pass options and files to TLINK through the command-line
compilers (BCC.EXE and BCC32.EXE) by typing file names on the command line with explicit .OBJ and .LIB extensions. For example,
BCC mainfile.obj subl.obj mylib.lib

links MAINFILE.OBJ, SUBl.OBJ, and MYLIB.LIB and produces the
executable MAINFILE.EXE.
BCC starts TLINK with the files COWS.OBJ, CWS.LIB, and IMPORT. LIB
(initialization module, run-time library, and Windows import library).
BCC32 starts TLINK32 with the files COW32.0BJ, CW32.LIB, and
IMPORT32.LIB by default.

Linking libraries

You must always link the Borland C++ run-time library that contains the
standard C/C++ library functions for the type of application you are
linking. You must also include the appropriate import library (IMPORT. LIB
for 16-bit Windows applications,IMPORT32.LIB for console applications, '
or IMPRTW32.LIB for 32-bit Windows applications).
Table 9.1 describes the 16-bit Windows 3.~ libraries and .OBJ files provided
by Borland. See the Library Reference for a complete list of Windows
libraries and the DOS Reference for a complete list of DOS libraries and
startup files.

Table 9.1
Borland 16-bit
libraries and startup
files

Libraries and .OBJs

Description

Cn.LlB

Run-time library for DOS applications, where n is S, C, M, L or H to
indicate Small, Compact, Medium, Large or Huge memory model.

CWn.LlB

Run-time library for Windows 3.x applications, where n is S, C, M, or L
to indicate Small, Compact, Medium, or Large memory model.
Run-time library for Windows 3.x applications to link in as a .DLL.
Import library for Windows 3.x API functions.
Startup code for DOS .EXE applications, where n is T, S, C, M, L, or H
to indicate Tiny, Small, Compact, Medium, Large or Huge memory
model.
Startup code for Windows 3.x applications, where nis S, M, C, or L to
indicate Small, Medium, Compact, or Large memory model.
Startup code for Windows 3.x .DLL modules, where n is S, M, or L to
indicate Small, Medium, or Large memory model.
If your program uses floating-paints, you must include a math library.
MATHWS.LlB is for small and tiny models.
Math library for compact models.

CRTLDLL.LlB
IMPORT.LlB
COn.OBJ

COWn.OBJ
CODn.OBJ
MATHWS.LlB
MATHWC.LlB

146

Borland C++ Users Guide

Table 9.1: Borland 16-bit libraries and startup files (continued)

MATHWM.LlB
MATHWL.LlB

Math library for medium models.
Math library for large models.

Table 9_2 describes the 32-bit libraries and .OBJ files provided by Borland;
these are used by TLINK32. See the Library Reference for a complete list of
libraries.
Libraries and .OBJs

Table 9.2
Borland 32-bit
libraries and startup
files

CW32.LlB
. IMPORT32.LlB
COX32.0BJ
COW32.0BJ
COD32.0BJ

Description
Run-time library for Win32 applications. .
Import library for console applications and 32-bit Windows
applications.
Startup code for console applications.
Startup code for Win32 applications.
Startup code for 32-bit DLL modules.

TLINK options
Unless otherwise specified, options work with both TLINK and TLINK32.
Options are case-sensitive and must be preceded by either a slash (I) or a
hyphen (-). To turn off a default option, place a hyphen after the option at
the command-line (for example, -P- or IP-). You can place options
anywhere in the command line. You don't need spaces after options (lmlflc
is the same as 1m If Ic), but you must separate options and files with a
space.
Table 9.3 lists the TLINK command-line options and the IDE equivalent
options (note that not all command-line options have an IDE equivalent).
Command-line default options are marked by a bullet (.). A more detailed
explanation of options, including the IDE option names, follows the table.
Table 9.3: TLiNK options
Default

Option

IDE Linker option

For

13

Linkerl16-bit LinkerlEnable 32-bit processing

Accepts and links 32-bit code produced by
TASM or a compatible assembler.
32-bit
Specifies application type, where
laa targets Windows applications
lap targets console applications.
16/32-bit Specifies page alignment within .EXE file.
32-bit
Specifies image base address (in
hexadecimal).
16/32-bit Treats case as significant in symbols.

lax
Target AttributeslTarget Model

IA:dd
16-bitlSegment Alignment
IB:xxxxxx 32-bit Linkerllmage based address

Ic

GeneraliCase-sensitive link

Chapter 9, Using the linker: TLiNK

Description

16-bit

147

Table 9.3: TLINK options (continued)

•

Ie

General/Case-sensitive exports, imports

16-bit

Id

WarningslWarn duplicate symbol in .LlB

16-bit

IE

16-bit LinkerlProcess extended dictionaries

16-bit

IEnn

32-bit LinkerlMaximum linker errors

32-bit

Ie

16-bitiProcess extended dictionaries (uncheck)

16-bit

If

16-bit Linkerllnhibit optimizing far to near

16-bit

IGx
IGn
IGr

16-bit LinkerlDiscard nonresident name table
16-bitiTransfer re$ident to nonresident table

16/32-bit
16-bit
16-bit

Map FilelPrint mangled names in map file
16-bit Linkerllnitialize segments
Map Filellnclude source line numbers

16/32-bit
16-bit
16-bit

DirectorieslLibrary (not under Linker in /DE)
Map FilelPublic
General/Default Libraries
Overlay module (Node attributes dialog box)
General/Pack code segments
ResourcelPack fast load area (not under. Linkef)


32-bit LinkerlStack size
Map FilelDetailed


16/32-bit
16/32-bit
16-bit
16-bit
16-bit
16-bit
32-bit
32-bit
32-bit
16-bit
16-bit
16-bit

IGm

n

II

•

•
•

IL
1m
In
10
IP
IRk
IRv
IRexxxx
IS:xxxxxx
Is
It
ITdx
ITpx


TargetExpert Platform
TargetExpert Platform

32-bit

ITwx

TargetExpert Target Type

16-bit

Iv
Iwxxx
Ix
lye
Iyx

Generalllnciude debug information
Warnings (see page 153 for information)
Map FilelOff



16/32-bit
32-bh
16/32-bit
16-bit
16-bit

•

148

<

Treats case as significant in EXPORTS and
IMPORTS section of module-definition file.
Warns you if there are duplicate symbols in
libraries.
Enables processing of extended
dictionaries in libraries.
Specifies maximum errors before
termination.
Ignores extended dictionaries in libraries.
This is the opposite of the IE option.
Inhibits optimization of far calls to near
data.
"Goodies" options where x is n, r, or m.
Discard nonresident name table.
Transfer Resident names to nonresident
names table.
Put Mangled names in map file.
Initializes all segments.
Includes source line numbers
(lowercase L).
Specifies library search paths.
Creates map file with publics.
Don't use default libraries.
Overlays modules or libraries.
Packs code segments.
Sends options to RLlNK.EXE.
Verbose resource binding.
Renames the executable to xxxx.
Specifies stack size (in hexadecimal).
Creates detailed map of segments.
Creates a tiny-model DOS .COM file.
Specifies application target, where
ITde means build a DOS .COM file.
ITde means build a DOS .EXE file.
Specifies application target, where
ITpe means build a 32-bit .EXE file.
ITpd means build a 32-bit DLL.
Specifies Windows 3.x target application,
where
ITwe builds a Windows .EXE file.
ITwd builds a Windows DLL.
Includes full symbolic debug information.
Enable or disable warnings (see page 153).
Doesn't create a map file.
Uses expanded memory for swapping.
Configures TLlNK's use of extended
memory swapping.

Borland C++ Users Guide

13 (32-bit code) 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.

la (application type) lets you specify the type of EXE image:
./aa targets Windows applications .
• lap targets console applications that can be run in a window.
IA:dd (align pages) specifies page alignment for code and data within the

executable file where dd must be a decimal power of 2. For example, if you
specify an alignment value of IA:12, the sections in the image are stored on
4096-byte boundaries. The operating system seeks pages for loading based
on this alignment value. The default is IA:9, which means sections are
aligned on 512-byte boundaries within the executable file.
IB:xxxxxx (base address) specifies an image base address for an

application. If this option is used, internal fixups are removed from the
image, and the requested load address of the first object is set to the
hexadecimal number given with the option. 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
since the operating system no longer has to apply internal fixups. Because
NT loads all .EXE images at 64K, you're advised to link all .EXEs with
IB:Ox10000.
Ic (case sensitivity) makes the case significant in public and external

symbols.
Ie (case sensitivity) makes the case significant in the EXPORTS and
IMPORTS sections in module-definition files.
Id (duplicate symbols) warns you if a symbol appears in more than one

library file. If the symbol must be included in the program, TLINK uses the
symbol from the first file containing the symbol that is specified on the
command line (or in a response file). This option also warns you if symbols
appear in both an .OBJ file and a .LIB file (TLINK uses the first one linked
in and ignores the others).
IEnn (maximum errors) specifies the maximum number of errors the linker

reports before terminating. lEO (the default) reports an infinite number of
errors (that is, as many as possible).
IE (extended dictionaries) processes extended dictionaries. The library files

in Borland C++ contain an extended dictionary with information that lets
TLINK use less memory and link faster with those libraries. You can add
the extended dictionary to other library files using TLIB's IE option (see the

Chapter 9, Using the linker: TLINK

149

TLIB section on page 170). Avoid using IE with programs linked with
libraries that have been built without an extended dictionary (third-party
libraries that have been provided without source code, for example). To use
extended dictionaries, all linked libraries must have extended dictionaries.
Ie (ignore extended dictionaries) ignores extended dictionaries. This is the

opposite of the IE option, and is the default.
If (inhibit far optimizations) inhibits the optimization of far calls to near

data.
IGx (Goodies) are options where x can be

n = Discard nonresident name table.
r = Transfer resident names to nonresident table.
m = (TLINK32) Put mangled names in map file; this can help you
identify how names are mangled.

Ii (uninitialized trailing segments) outputs uninitialized trailing segments

into the executable file even if the segments don't contain data records.
II (line numbers) creates a section in the .MAP file for source-code line

numbers. Linked .OBJ files must be compiled with debug information
using -y or -v. If you use Ix to suppress map file creation, the II
(lowercase L) option has no effect.
IL (library search paths) lets you list directories for TLINK to search if you

don't type an explicit path for a library or the C or C++ initialization
module. TLINK searches the current directory first (where you typed
TLINK). For example,
TLINK /Lc:\BC4\lib;c:\rnylibs splash logo",utils .\logolib

first searches the current directory for UTILS.LIB, then searches C: \ BC4 \
LIB, then C: \MYLIBS. Because LOGOLIB explicitly names the current
directory, TLINK doesn't search the libraries specified with the IL option to
find LOGOLIB. LIB.
1m (detailed map file) creates a more complete map than TLINK normally

does by adding a list of sorted public symbols to the map file. This kind of
map file is useful in debugging. Many debuggers can use the list of public
symbols, which lets you refer to symbolic addresses when you're
debugging. If you don't specify map file options (1m, Is, or Ix), then the
option Map File I Segments is used. See also Is.
1M (map mangled) maps with mangled public names.

150

Borland C++ Users Guide

In (ignore default libraries) ignores default libraries specified by some compilers. Use this option when linking modules that are written in another
language.

/0 (overlays) overlays code in all the modules or libraries that follow the
option on the command line (this option works for DOS applications only).
Use /0- on the command line to turn off overlays. If you specify a class
name after this option, all the segments in that class are overlaid (you can
do this for multiple classes). If you don't specify any name after this option,
all segments of classes ending with CODE are overlaid. This option uses
the default overlay interrupt number of 3FH. To specify a different
interrupt number, use /o#xx, where xx is a two-digit hexadecimal numbet:
IP (pack code segments) combines as many code segments as possible in

one physical segment up to (and never greater than) the code-segment
packing limit. TLINK starts a new segment if it needs to. The default codesegment packing limit is 8,192 bytes (8K). To change it, use jP=n where n
specifies the number of bytes 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 and 8K might pack more efficiently.
Because each maintained segment has some system overhead, codesegment packing typically increases performance. IP- turns off codesegment packing (useful if you've turned it on in the configuration file and
want to disable it for a particular link).
Is (detailed segment map) creates a map file with the same features as the
1m option, but adds a detailed segment map. If you don't specify map file
options (1m, Is, or Ix), then the option Map File I Segments is used. For each

segment in each module, this map file includes the address, length in bytes,
class, segment name, group, module, and ACBP information. If the same
segment appears in more than one module, each module appears as a
separate line. Except for the ACBP field, the information in the detailed
segment map is self-explanatory.
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, the A, C, and B fields. The ACBP value in the map is
printed in hexadecimal. The following values of the fields must be OR' ed
together to arrive at the ACBP value printed.

Chapter 9, Using the linker: TLINK

151

Field

Value

The A field (alignment)

00
20
40
60

80

AD
The C field (combination)

00

08
The B field (big)

00
02

Description

An absolute segment.
A byte-aligned segment.
A word-aligned segment.
A paragraph-aligned segment.
A page-aligned segment.
An unnamed absolute portion of storage.
Cannot be combined.
A public combining segment.
Segment less than 64K.
Segment exactly 64K.

With the Is option, public symbols with no references are flagged "idle."
An idle symbol is a publicly-defined symbol in a module that wasn't
referenced by an EXTDEF record 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 Symbo13 aren't referenced by the image
being linked:
0002:00000874
0002:00000CE4
0002:000000E7

Idle
Idle

Symboll
Symbo12
Symbo13

IS:xxxxxx (stack size) sets the application stack size in hexadecimal where
xxxxxx is a hexadecimal string. Specifying the stack size with IS overrides

any stack size setting in a module-definition file.
It (tiny model DOS .COM file) creates a DOS tiny-model.COM file (this
option works the same as fTdc, except you can use It with BCC.EXE). DOS
.COM files can't exceed 64K in size, have segment-relative fixups, or define
a stack segment. They 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, then recompile and link
as a .COM file.
fTdx(DOS target) produces a DOS .EXE (fTde) or a DOS .COM (fTdc) file.
fTpx(protected target) produces a protected mode .EXE (fTpe) or .DLL file
(fTpd).
fTwx (target type) produces a Windows .EXE (fTwe) or .DLL file (fTwd).

This option isn't necessary if you include a module-definition file with an
EXETYPE Windows statement because TLINK creates an application (.EXE)
if the module-definition file has a NAME statement or a DLL if the
module-definition file has a LIBRARY statement.

152

Borland C++ Users Guide

Iv (debugging information) includes debugging information in the
executable file. If this option is found anywhere on the command line,

debugging information is included in the executable file for all object
modules that contain debugging information. You can use the Iv+ and Ivoptions to selectively enable or disable debugging information on a
module-by-module basis (but not on the same command line as Iv). For
example, the command
TLINK modi

/Vt

mod2 mod3 /v- mod4

includes debugging information for modules mod2 and mod3; but not for
modl and mod4.
Iwxxx (warning control) turns on (/wxxx) or off (/w-xxx) TLINK warnings,

where xxx can be one of the following (defaults mean TLINK will send the
warning without you specifically turning it on):
Table 9.4
TLlNK32 warnings

Default

Iwoption

IDE description

---.-------b~d-I-----U-s-in-g-b-as-e-d-lin-k-in-g-in-D-L-Ls-(~m-ig-ht-c-a-us-e-th-e-D-L-L-to-m-a-If~un-c-tio-n~)----

•
•
•

def
dpl
dup
ent
imt
inq
srf

No .DEF file; using defaults
Warn duplicate symbol in .LlB
Duplicate symbol (warning for .OBJs)
No entry point
Import doesn't match previous definition
Extern not qualified with _ jmport
Self-relative fixup overflowed
"No stack" warning

Ix (no map file) tells TLINK to not generate a map file. TLINK usually
creates map files that list segments in the program, the program start
address, and any TLINK warning or error messages (the Map File I
Segments option, which has no command-line option, is on by default).
lye (expanded memory) controls TLINK's use of expanded memory for I/O
buffering. If TLINK 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, TLINK 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.

Chapter 9, Using the linker: TUNK

153

This option has several forms, shown below

• lye or Iye+ enables expanded memory swapping (this is the default).
• ye- disables expanded memory swapping (this is off by default).

Iyx (extended memory) controls TLINKs use of extended memory for I/O
buffering. By default, TLINK can use up to BMB of extended memory. You
can change TLINK's use of extended memory with one of the following
forms of this option:
./yx+ uses all available extended memory up to 8MB .
• /yxn uses only up to n KB extended memory.

Module-definition file reference
IMPDEF creates
module-definition
files, and IMPLIB
creates import
libraries from
module-definition
files. See Chapter 10
for more information
on these tools.

This section describes module-definition files and the statements that
appear in them. A module-definition file provides information to TLINK
about the contents and system requirements of a Windows application.
More specifically, a module-definition file
•
•
•
•

Names the .EXE or .DLL.
Identifies the application type.
Lists imported and exported functions.
Describes the code and data segment attributes, and lets you specify
attributes for additional code and data segments.
• Specifies the size of the stack.
• Provides for the inclusion of a stub program.

See the Programmer's Guide for uses and examples of module-definition files.
CODE statement

CODE defines the default attributes of code segments. Code segments can
have any name, but must belong to segment classes whose name ends in
CODE (such as CODE or MYCODE). The syntax is
TLINK

TLINK32

CODE [FIXED IMOVEABLE]
[DISCARDABLEINONDISCARDABLE]
[PRELOAD ILOADONCALL]

[PRELOAD I LOADONCALL]
[EXECUTEONLY I EXECUTEREAD]

• FIXED (the default) means the segment remains at a fixed memory
location; MOVEABLE means the segment can be moved.
• PRELOAD means code is loaded when the calling program is loaded.
LOADONCALL (the default) means the code is loaded when called by
the program.

154

Borland C++ Users Guide

• DISCARDABLE means the segment can be discarded if it is no longer
needed (this implies MOVABLE). NONDISCARDABLE (the default)
means the segment can't be discarded.
• EXECUTEONLY means a code segment can only be executed.
EXECUTEREAD (the default) means the code segment can be read and
executed.
• PRELOAD means the segment is loaded when the module is first loaded.
LOADONCALL (the default) means the segment is loaded when called.
DATA statement

DATA defines attributes of data segments. The syntax is
DATA [NONE I SINGLE I MULTIPLE]
[READONLY I READWRITE]
[PRELOAD I LOADONCALL]
[SHARED I NONSHARED]

• NONE means that there is no data segment created. This option is
available only for libraries. SINGLE (the default for .DLLs) means a
single data segment is created and shared by all processes. MULTIPLE
(the default for .EXEs) means a data segment is created for each process.
• READONLY means the data segment can be read only. READWRITE
(the default) means the data segment can be read and written to.
• PRELOAD means the data segment is loaded when a module that uses it
is first loaded. LOADONCALL (the default) means the data segment is
loaded when it is first accessed (this is ignored for 32-bit applications).
• SHARED (the default for 16-bit .DLLs) means one copy of the data
segment is shared among all processes. NONSHARED (the default for
programs and 32-bit .DLLs) means a copy of the data segment is loaded
for each process needing to use the data segment.
DESCRIPTION
statement

DESCRIPTION (optional) inserts text into the application module and is
typically used to embed author, date, or copyright information. The syntax
is
DESCRIPTION 'Text'

Text is an ASCII string delimited with single quotes.
EXETYPE
statement

EXETYPE defines the default executable file (.EXE) header type for 16-bit
application. You can leave this section in for 32-bit application for
backward compatibility, but if you need to change the EXETYPE, see the
NAME statement on page 158. The syntax for EXETYPE is
EXETYPE WINDOWS

Chapter 9, Using the linker: TUNK

155

EXPORTS
statement

EXPORTS defines the names and attributes of functions to be exported. The
EXPORTS keyword marks the beginning of the definitions. It can be
followed by any number of export definitions, each on a separate line. The
syntax is
EXPORTS
ExportName [Ordinal] [RESIDENTNAME] [Parameter]

• ExportName specifies an ASCII string that defines the symbol to be
exported:
EntryName [=InternalNarne]

InternalName is the name used within the application to refer to this
entry. EntryName is the name listed in the executable file's entry table
and is externally visible.
• Ordinal defines the function's ordinal value as follows:
@ordinal

where ordinal is an integer value that specifies the function's ordinal
value.
When an application or OLL module calls a function exported from a
OLL, the calling module can refer to the function by name or by ordinal
value. It's faster to refer to the function by ordinal because string
comparisons aren't required to locate the function. To use less memory,
export a function by ordinal (from the point of view of that function's
OLL) and import/ call a function by ordinal (from the point of view of
the calling module).
When a function is exported by ordinal, the name resides in the
nonresident name table. When a function is exported by name, the name
resides in the resident name table. The resident name table for a module
is in memory whenever the module is loaded; the nonresident name
table isn't.
• RESIOENTNAME specifies that the function's name must be resident at
all times. This is useful only when exporting by ordinal (when the name
wouldn't be resident by default).

• Parameter is an optional integer value that specifies the number of words
the function expects to be passed as parameters.

156

Borland C++ User's Guide

IMPORTS
statement

IMPORTS defines the names and attributes of functions to be imported
from DLLs. Instead of listing imported DLL functions in the IMPORTS
statement, you can either
• Specify an import library for the DLL in the TLINK command line, or
• Include the import library for the DLL in the project manager in the IDE.
If you're programming for 32-bits, you must use _ _ import to import any
function, class, or data you want imported; for 16-bits you must use
_ _ import with classes. See the Programmer's Guide for more information on
using _ _ import.

The IMPORTS keyword marks the beginning of the definitions; it is
followed by any number of import definitions, each on a separate line. The
syntax is
IMPORTS
[InternalName=] ModuleName. Entry

• InternalName is an ASCII string that specifies the unique name the
application uses to call the function.
• ModuleName specifies one or more uppercase ASCII characters that define
the name of the executable module containing the function. The module
name must match the name of the executable file. For example, the file
SAMPLE.DLL has the module name SAMPLE.
• Entry specifies the function to be imported-either an ASCII string that
names the function or an integer that gives the function's ordinal value.
LIBRARY
statement

LIBRARY defines the name of a DLL module. A module-definition file can
contain either a LIBRARY statement to indicate a DLL or a NAME
statement to indicate a program.
A library's module name must match the name of the executable file. For
example, the library MYLIB.DLL has the module name MYLIB. The syntax
is
LIBRARY LibraryName [INITGLOBAL I INITINSTANCE]

• LibraryName (optional) is an ASCII string that defines the name of the
library module. If you don't include a LibraryName, TLINK uses the file
name with the extension removed. If the module-definition file includes
neither a NAME nor a LIBRARY statement, TLINK assumes a NAME
statement without a ModuleName parameter.
• INITGLOBAL means the library-initialization routine is called only when
the library module is first loaded into memory. INITINSTANCE means

Chapter 9, Using the linker: TLINK

157

the library-initialization routine is called each time a new process uses
.
the library.
NAME statement

NAME is the name of the application's executable module. The module
name identifies the module when exporting functions. For 32-bit
applications, NAME must appear before EXETYPE. If NAME and
EXETYPE don't specify the same target type, the type listed with NAME is
used. The syntax is
NAME ModuleName [WINDOWSAPI) I [WINDOWCOMPAT)

ModuleName (optional) specifies one or more uppercase ASCII characters
that name the executable module. The name must match the name of the
executable file. For example, an application with the executable file
SAMPLE.EXE has the module name SAMPLE.
If ModuleName is missing, TLINK assumes the module name matches the
file name of the executable file. For example, if you don't specify a module
name and the executable file is named MYAPP.EXE, TLINK assumes the
module name is MYAPP.
If the module-definition file includes neither a NAME nor a LIBRARY
statement, TLINK assumes a NAME statement without a ModuleName
parameter.

WINDOWAPI is a Windows executable, and is equivalent to the TLINK32
option/aa.
WINDOWCOMPAT is a Windows-compatible character-mode executable,
and is equivalent tio the TLINK32 option lap.
.
SEGMENTS
statement

SEGMENTS defines the segment attributes of additional code and data
segments. The syntax is
SEGMENTS
SegmentName [CLASS 'ClassName') [MinAlloc)
[SHARED I NONSHARED)
[PRELOAD I LOADONCALL)

• SegmentName is a character string that names the new segment. It can be
any name, including the standard segment names _TEXT and _DATA,
which represent the standard code and data segments .
• ClassName (optional) is the class name of the specified segment. If no
class name is specified, TLINK uses the class name CODE .
• MinAlloc (optional) is an integer that specifies the minimum allocation
size for the segment. TLINK and TLINK32 ignore this value.

158

Borland C++ User's Guide

• SHARED (the default for 16-bit .DLLs) means one copy of the segment is
shared among all processes. NONSHARED (the default for programs
and 32-bit .DLLs) means a copy of the segment is loaded for each process
needing to use the data segment.
• PRELOAD means that the segment is loaded immediately;
LOADONCALL means that the segment is loaded when it is accessed or
called (this is ignored by TLINK32). The resource compiler might
override the LOAD ONCALL option and preload segments instead.
STACKSIZE
statement

STACKSIZE defines the number of bytes needed by the application for its
local stack. An application uses the local stack whenever it makes function
calls. Don't use the STACKSIZE statement for dynamic-link libraries. The
syntax is
STACKSIZE bytes

bytes is an integer value that specifies the stack size in bytes.
STU B statement

STUB appends a DOS executable file specified by FileName to the beginning
of the module. The executable stub displays a warning message and
terminates if the user attempts to run the executable stub in the wrong
environment (running a Windows application under DOS, for example).
Borland C++ adds a built-in stub to the beginning of a Windows
application unless a different stub is specified with the STUB statement.
You shouldn't use the STUB statement to include WINSTUB.EXE because
the linker does this automatically. The syntax is
STUB "FileName"

FileName is the name of the DOS executable file to be appended to the
module. The name must have the DOS file name format.
If the file named by FileName isn't in the current directory, TLINK searches

for the file in the directories specified by the PATH environment variable.
Module-definition
file defaults

The module-definition file isn't strictly necessary to produce a Windows
executable under Borland C++.
If no module-definition file is specified, the following defaults are assumed:
CODE
DATA
HEAPSIZE
STACKSIZE

Chapter 9, Using the linker: TUNK .

PRELOAD MOVEABLE DISCARDABLE
PRELOAD MOVEABLE MULTIPLE (for applications)
PRELOAD MOVEABLE SINGLE (for DLLs)
4096
5120 (1048576 for TLINK32)

159

To replace the EXETYPE statement, the Borland C++ linker can discover
what kind of executable you want to produce by checking settings in the
IDE or options on the command line.
You can include an import library to substitute for the IMPORTS section of
the module definition file.
You can use the _export keyword in the definitions of export functions in
your C and C++ source code to remove the need for an EXPORTS section.
Note, however, that if _export is used to export a function, that function is
exported by name rather than by ordinal (ordinal is usually more efficient).
If you want to change various attributes from the default, you'll need to
have a module-definition file.

160

Borland C++ Users Guide

c

H

A

p

T

E

R

10

Using resource tools
This chapter describes the Borland resource tools.
• BRCC.EXE and BRCC32.EXE are the Borland resource compilers. They
compile resource script files (.RC files) and produce the binary .RES file.
• RLINK.EXE and RLINK32.DLL (through TLINK32.EXE) 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.
• BRC.EXE and BRC32.EXE are shells through which both BRCC or
BRCC32 and RLINK or RLINK32 (through TLINK32) can be started in a
single step.
All 32-bit resource tools work exactly like the 16-bit tools unless specified in
this chapter.
Windows programs provide a familiar and standard user interface for all
applications. The components of the user interface are known as resources
and can include:
• Menus
• Bitmaps
• Dialog boxes
• Pointers

• Strings
II Accelerator keys

• Fonts
• Icons
Resources are defined external to your source code, and then- attached to
the executable file during linking. The application calls resources into
memory only when needed, thus minimizing memory usage.
Resource script (.RC) files are text files that describe the resources a
particular application will use. BRCC and RC use the .RC file to compile the
resources into a binary format resource (.RES) file. RLINK then attaches the
.RES file, which contains your resources, to your executable (this is called
resource linking).
r,

Chapter 10, Using resource tools

161

BRCC.EXE: The resource compiler
BRCC is a command-line version of Resource Workshop's resource
compiler. It accepts a resource script file (.RC) as input and produces a
resource object file (.RES) as output. BRCC uses the following commandline syntax:
BRCC [options) .RC

Table 10.1 lists all BRCC options. Note that options are not case-sensitive (-r
is the same as -R).
Table 10.1
BRCC (Borland
resource compiler)

Switch

Description

@responsefile

Takes instructions from the specified command file.

-d[=]

Defines a preprocessor symbol.

-fo

Renames the output .RES file. (By default, BRCC creates the
output .RES file with the same name as the input .RC file.)

-kpath>

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
-x

Prints progress messages (verbose).

-? or-h

Displays switch help.

-30

Builds Windows 3.0-compatible .RES files.

-31

Builds Windows 3.1-compatible .RES files.

-w32

Builds Win32-compatible .RES files.

Deletes the current include path.

Like Resource Workshop's resource compiler, BRCC 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
gr~atly speed up compilation:
#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

162

Borland C++ User's Guide

The following example adds two directories to the include path and
produces a .RES file with the same name as the input .RC file.
bree -ii .RC

This example produces an output .RES file with a name different from the
input .RC file name:
bree -fo.RES .RC

RLINK: the resource linker
RLINK combines 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
stringtables and messagetables and then binding these linked resources to
the executable.
RLINK uses the following command-line syntax:
rlink [options] .RES .EXE

RLINK accepts these options:
Table 10.2
RLiNK switches

Switch

Description

@

Takes instructions from the specified command file.

-d

Removes resources from the .EXE file (no .RES file is specified).

-fe

Renames the output .EXE file.

-fi

Renames the input .RES file.

-k

Don't reorder segments for fastload.

-v
-vx

Lists resources but does not bind to EXE file.

-? or-h

Displays switch help.

-30

Builds Windows 3.0-compatible .RES files.

'-31

Builds Windows 3.1-compatible .RES files.

Prints progress messages (verbose listing).

The following example binds the resources in the .RES file into the .EXE
file.
rlink .RES .EXE

Chapter 10, Using resource tools

163

The next example links the resources in the two
to the .EXE file.

.R~S

files and binds them

rlink -fi.RES .RES .EXE

The next 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

The final 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

BRC.EXE: the resource shell
The Borland Resource Compiler (BRC) is a resource compiler shell. It
invokes either BRCC or RLINK or both, depending on the command-line
syntax. The command-line syntax for BRC is as follows:
brc [switches] .RC [.EXE]

BRC accepts these switches:
Table 10.3
BRC switches

164

Switch

Description

-ckname>=string

Defines a symbol you can test with the #IFDEF preprocessor directive.

-fo

Renames the .RES file.

-fe

Renames the .EXE file.

-fi

Specifies additional .RES files.

-kpath>

Adds one or more directories (separated by semicolons) to the include
search path.

-k

Don't create fastload area.

-r

Creates a .RES file only. The compiled .RES file is not added to the .EXE.

-v

Prints progress messages (verbose listing).

Borland C++ User's Guide

Table 10.3: BRC switches (continued)

-x

Directs the compiler to ignore the INCLUDE environment variable when it
searches for include or resource files.

-31

Builds Windows 3.1-compatible .RES files.

-w32

Builds Win32-compatible .RES files.

Depending on your task, there are several variations on the basic BRC
command-line syntax:
(

• The following statement compiles the .RC file, creates a .RES file, and
adds the .RES file to the executable file.
brc .RC [.EXE]

BRC 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 the .RC
file's.
• 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.
brc -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.
brc .RES [.EXE]

Chapter 10, Using resource tools

165

166

Borland C++ Users Guide

c

H

A

p

T

E

R

11

Using libraries
This chapter describes several tools that let you work with library files. You
can use these tools from either the IDE or the command line .
• IMPLIB creates import libraries, and IMPDEF creates module definition
files (.DEF files). Import libraries and module definition files provide
information to the linker about functions imported from dynamic-link
libraries (DLLs) .
• TLIB is a utility that manages libraries of individual.OBJ (object module)
files. A library is a convenient tool for dealing with a collection of object
modules as a single unit.

Using IMPLIB: The import librarian
The IMPLIB utility creates import libraries. IMPLIB takes as input DLLs,
module definition files, or both, and produces an import library as output.
The IDE uses IMP LIB as'a translator for a DLL target (see Chapter 2 for
information on the project manager and targets). When you add a DLL as a
target, the project manager compiles and links the DLL's dependent files to
create the .DLL file, then runs IMPLIB to create a .LIB file. You can also run
IMPLIB from the IDE (see page 20 for information on using tools from the
IDE).
Import libraries contain records. Each record contains the name of a DLL,
and specifies where in the DLL the imported functions reside. These
records are bound to the application by TLINK or the IDE linker, and
provide Windows with the information necessary to resolve DLL function
calls. An import library can be substituted for part or all of the IMPORTS
section of a module definition file.
If you've created a Windows application, you've already used at least one
import library, IMPORT.LIB, the import library for the standard Windows
DLLs. (IMPORT. LIB is linked automatically when you build a Windows
application in the IDE and when using BCC to link. Youhave to explicitly
link with IMPORT. LIB only if you're using TLINK to link separately.)

Chapter 11, Using libraries

167

An import library lists some or all of the exported functions for one or more
DLLs. IMPLIB creates an import library directly from DLLs or from module
definition files for DLLs (or a combination of the two).
To create an import library for a DLL, type.
IMPLIB Options LibName [ DefFiles ... I DLLs ...
A DLL can also have
an extension of .EXE
or .DRV, not just
.DLL.

Table 11.1
IMPLIB options

Options must be
lowercase and
preceded by either a
hyphen or a slash.

where Options is an optional list of one or more IMP LIB options (see Table
ILl), LibName is the name for the new import library, DefFiles is a list of one
or more existing module definition files for one or more DLLs, and DLLs is
a list of one or more existing DLLs. You must specify at least one DLL or
module definition file.
Option

Description

-c

Accepts case-sensitive symbols. If you have two symbols that differ only in case (like
MYSYM and mysym) and you don't use -c, IMPLIB uses the first symbol and treats the
second one as a duplicate.
Tells IMPLIB to ignore WEP, the Windows exit procedure required to end a DLL. Use
this option if you are specifying more than one DLL on the IMPLIB command line.
No warnings.

-i
-w

Using IMPDEF: The module-definition file manager
Import libraries
provide access to the
functions in a
Windows DLL. See
page 167 for more
details.

IMPDEF takes as input a DLL name, and produces as output a module
definition file with an export section containing the names of functions
exported by the DLL. The syntax is
IMPDEF DestName.DEF SourceName.DLL

This creates a module definition file named DestName.DEF from the file
SourceName.DLL. The resulting module definition file would look
something like this:
LIBRARY

FileName

DESCRIPTION 'Description'
EXPORTS

ExportFuncName

@Ordinal

ExportFuncName

@Ordinal

where FileName is the DLL's root file name, Description is the value of the
- DESCRIPTION statement if the DLL was previously linked with a module
definition file that included a DESCRIPTION statement, ExportFuncName

168

Borland C++ Users Guide

names an exported function, and Ordinal is that function's ordinal value (an
integer).
Classes in a DLL

IMPDEF is useful for a DLL that uses C++ classes. If you use the _export
keyword when defining a class, all of the non-inline member functions and
static data members for that class are exported. It's easier to let IMPDEF
make a module definition file for you because it lists all the exported
functions, and automatically includes the member functions and static data
members.
Since the names of these functions are mangled, it would be tedious to list
them all in the EXPORTS section of a module definition file simply to create
an import library from the module definition file. If you use IMPDEF to
create the module definition file, it includes the ordinal value for each
exported function. If the exported name is mangled, IMPDEF also includes
that function's unmangled, original name as a comment following the
function entry. So, for instance, the module definition file created by
IMPDEF for a DLL that used C++ classes would look something like this:
LIBRARY

FileName

DESCRIPTION 'Description'
EXPORTS

MangledExportFuncName @Ordinal

ExportFuncName

MangledExportFuncName @Ordinal

ExportFuncName

where FileName is the DLL's root file name, Description is the value of the
DESCRIPTION statement if the DLL was previously linked with a module
definition file that included a DESCRIPTION statement,
MangledExportFuncName provides the mangled name, Ordinal is that
function's ordinal value (an integer), and ExportFuncName gives the
function's or.iginal name.
Functions in a
DLL

•

IMPDEF creates an editable source file that lists all the exported functions
in the DLL. You can edit this .DEF file to contain only those functions that
you want to make available to a particular application, then run IMPLIB on
the edited .DEF file. This results in an import library that contains import
information for a specific subset of a DLL's export functions.
Suppose you're distributing a DLL that provides functions to be used by
several applications. Every export function in the DLL is defined with
_export. Now, if all the applications u~ed all the DLL's exports, then you
could use IMP LIB to make one import library for the DLL. You could
deliver that import library with the DLL, and it would provide import

Chapter 11, Using libraries

169

information for all of the DLL's exports. The import library could be linked
to any application, thus eliminating the need for the particular application
to list every DLL function it uses in the IMPORTS section of its module
definition file.
But let's say you want to give only a few of the DLL's exports to a particular
application. Ideally, you want a customized import library to be linked to
that application-an import library that provides import information only
for the subset of functions that the application uses. All of the other export
functions in the DLL are hidden to that client application.
To create an import library that satisfies these conditions, run IMPDEF on
the compiled and linked DLL. IMPDEF produces a module definition file
that contains an EXPORT section listing all of the DLL's export functions.
You can edit that module definition file, remove the EXPORTS section
entries for those functions you don't want in the customized import library,
and then run IMPLIB on the module definition file. The result is an import
library that contains import information for only those export functions
listed in the EXPORTS section of the module definition file.

Using TLIB: the Turbo Librarian
When it modifies an
existing library, TUB
always creates a
copy of the original
library with a .BAK
extension.

The libraries included with Borland C++ were built with TLIB. You can use
TLIB to build and modify your own libraries, or to modify the Borland C++
libraries, libraries furnished by other programmers, or commercial libraries
you've purchased. You can also use TLIB to
•
•
•
•
•
•

See the section on
the IE option (page
172) for details.

Create a new library from a group of objectmodules.
Add object modules or other libraries to an existing library.
Remove object modules from an existing library.
Replace object modules from an existing library.
Extract object modules from an existing library.
List the contents of a new or existing library.

TLIB can also create (and include in the library file) an extended dictionary,
which can be used to speed up linking.
Although TLIB is not essential for creating executable programs with
Borland C++, it saves you time on large development projects.

Why use object
module libraries?

170

When you program in C and C++, you often create a collection of useful
functions and classes. Because of C and C++'s modularity, you are likely to
split those functions into many separately compiled source files. Any

Borland C++ Users Guide

particular program might use only a subset of functions from the entire
collection.
An object module library manages a collection of functions and classes.
When you link your program with a library, the linker scans the library and
automatically selects only those modules needed for the current program.
The TLiB

command line

The TLIB command line takes the following general form, where items
listed in square brackets are optional:
tlib [@respfile] [option] libname [operations] [, listfile]

For an online
summary of TLiB
options, type TLIB
and press Enter.

In the IDE, you can create a library as a target in a project file. Using
TargetExpert, choose Static Library for the target type (see Chapter 2 for
help using the project manager). TLIB is the default translator for a library
file and it uses options you set in the Project Options dialog box under the
Librarian section (choose Options I Project from the main menu).

Tab,le 11.2: TLiB options
Option

Librarian (IDE option)

@respfile

The path and name of the response file you want to include. You can specify more
than one response file.
The DOS path name of the library you want to create or manage. Every TLiB command must be given a Iibname. Wildcards are not allowed. TLiB assumes an extension of .LlB if none is given. Use only the .LlB extension because the command-line
compilers (BCC and BCC32) and the IDE require the .LlB extension to recognize
library files. Note: If the named library does not exist and there are add operations,
TLiB creates the library.
Case-sensitive library
The ,case-sensitive flag. This option is not normally used; see page 172 for a
detailed explanation.
Create extended dictionary Creates Extended Dictionary; see page 172 for a detailed explanation.
Library Page Size
Sets the library page size to size; see page 172 for a detailed explanation.
Purge comment records
Removes comment records from the library.
The list of operations TLiB performs. Operations can appear in any order. If you only
want to examine the contents of the library, don't give any operations.
Generate list file
The name of the file that lists library contents. It must be preceded by a comma. No
listing is produced if you don't give a file name. The listing is an alphabetical list of
each module. The entry for each module contains an alphabetical list of each public
symbol defined in that module. The default extension for the Iistfile is .LST. You can
direct the listing to the screen by using the Iistfile name CON, or to the printer by
using the name PRN.

Iibname

Ie

IE
IPsize

10
operations
Iistfile

Using response
files

Description

When you use a large number of operations, or if you find yourself
repeating certain sets of operations over and over, you will probably want
to use response files. A response file is an ASCII text file (which can be
created with the Borland C++ editor) that contains all or part of a TLIB

Chapter 11, Using libraries

171

command. Using response files, you can build TLIB commands larger than
would fit on one command line. Response files can
• Contain more than one line of text; use the ampersand character (&) at
the end of a line to indicate that another line follows.
• Include a partial list of commands. You can combine options from the
command line with options in a response file.
• Be used with other response files in a single TLIB command line.
Using casesensitive symbols:
The IC option
Don't use Ie if you
plan to use the library
with other linkers or
let other people use
the library.

Creating an
extended
dictionary: The IE
option

TLIB maintains a dictionary of all public symbols defined in the modules of
the library. When you add a module to a library, its symbol must be
unique. If you try to add a module to the library that duplicates a symbol,
TLIB displays an error message and doesn't add the module.
Because some linkers aren't case-sensitive, TLIB rejects symbols that differ
only in case (for example, the symbols lookup and LOOKUP are treated as
duplicates). TLINK, however, can distinguish case, so if you use your
library only with TLINK, you can use the TLIB Ie option to add a module
to a library that includes symbols differing only in case.
To increase the linker's capacity for large links, you can use TLIB to create
an extended dictionary and append it to the library file. This dictionary
contains, in a compact form, information that is not included in the standard library dictionary and that lets the linker (TLINK) preprocess library
files so that any unnecessary modules are not preprocessed.
To create an extended dictionary for a library that you're modifying, use
the IE option when you start TLIB to add, remove, or replace modules in
the library. You can also use the IE option to create an extended dictionary
for an existing library that you don't want to modify. For example, if you
type TLIB IE rnylib the linker appends an extended dictionary to the
specified library.
If you use IE to add a library module containing a C++ class with a virtual
function, you'll get the error message Library contains COMDEF
records--extended dictionary not created.

Setting the page
size: The IP option

Every DOS library file contains a dictionary that appears at the end of the
.LIB file, following all of the object modules. For each module in the library,
the dictionary contains a 16-bit address of that particular module within the
.LIB file; this address is given in terms of the library page size (it defaults to
16 bytes).
The library page size determines the maximum combined size of all object
modules in the library, which cannot exceed 65,536 pages. The default (and

172

Borland C++ Users Guide

minimum) page size of 16 bytes allows a library of about 1 MB in size. To
create a larger library, use the IP option to increase the page size. The page
size must be a power of 2, and it cannot be smaller than 16 or larger than
32,768.
All modules in the library must start on a page boundary. For example, in a
library with a page size of 32 (the lowest possible page size higher than the
default 16), an average of 16 bytes is lost per object module in padding. If
you attempt to create a library that is too large for the given page size, TLIB
issues an error message and suggests that you use IP with the next
available higher page size.
Removing comment
records: The /0
option

The operation list

Use the 10 option to remove comment records, which reduces the size of a
library. For example, you might have debugging or browsing information
in a library, but you no longer need to use that information; the 10 option
removes that information.
The operation list describes what actions you want TLIB to do. It consists of
a sequence of operations given one after the other. Each operation consists
of a one- or two-character action symbol followed by a file or module name.
You can put whitespace around either the action symbol or the file or
module name but not in the middle of a two-character action or in a name.
You can put as many operations as you like on the command line, up to
DOS's COMMAND. COM-imposed line-length limit of 127 characters. The
order of the operations is not important. TLIB always applies the
operations in a specific order:

To replace a module,
remove it, then add
the replacement
module.
Wildcards are never
allowed in file or
module names.

1. All extract operations are done first.
2. All remove operations are done next.
3. All add operations are done last.
TLIB finds the name of a module by stripping any drive, path, and extension information from the given file name. TLIB always assumes reasonable
defaults. For example, to add a module that has an .OBJ extension from the
current directory, you need to supply only the module name"not the path
and .OBJ extension.

Chapter 11, Using libraries

173

TLIB recognizes three action symbols (-, +, *), which you can use singly or
combined in pairs for a total of five distinct operations. The action symbols
and what they do are listed here:
Table 11.3
TUB action symbols

Action
symbol

To create a library,
add modules to a
library that does not
yet exist.

+

You can't directly
rename modules in a
library. To rename a
module, extract and
remove it, rename the
file just created, then
add it back into the
library.

Examples

Name

Description

Add

TUB adds the named file to the library. If the file has no extension, TUB
assumes an extension of .OBJ. If the file is itself a library (with a .UB
extension), then the operation adds all of the modules in the named library
to the target library. If a module being added already exists, TUB displays
a message and does not add the new module.

Remove

TUB removes the named module from the library. If the module does not
exist in the library, TUB displays a message. A remove operation needs
only a module name. TUB lets you enter a full path name with drive and
extension included, but ignores everything except the module name.

*

Extract

TUB creates the named file by copying the corresponding module from the
library to the file. If the module does not exist, TUB displays a message
and does not create a file. If the named file already exists, it is overwritten.

-*
*-

Extract & TUB copies the named module to the corresponding file name and then
Remove
removes it from the library.

-+
+-

Replace

TUB replaces the named module. with the corresponding file.

These examples demonstrate some of the things you can do with TLIB:
• To create a library named MYLIB.LIB with modules X.OBJ, Y.OBJ, and
Z.OBJ, type tlib mylib +x +y +z.
• To create a library named MYLIB.LIB and get a listing in MYLIB.LST too,
type tlib mylib +x +y. +z, mylib.lst.
• To replace module X.OBJ with a new copy, add A.OBJ and delete Z.OBJ
from MYLIB.LIB, type tlib mylib -+x +a -z.
• To create a new library (ALPHA) with modules A.OB], B.OBJ ... G.OBJ
using a response file:
• First create a text file, ALPHA.RSP, with
+a.obj +b.obj +c.obj &
+d.obj +e.obj +f.obj &
+g.obj

• Then use the TLIB command, which produces a listing file named
ALPHA.LST: tlib alpha @alpha. rsp, alpha .lst

174

Borland C++ Users Guide

c

H

A

p

T

E

R

12

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).
This chapter covers the following topics:
_ MAKE basics
_ Using MAKE macros
_ Makefile contents
_ Using MAKE directives
_ Using explicit and implicit rules

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 files to recompile or link, but the commands can be nearly
any operating system command).
MAKE accepts * and
? as wildcards.

The general syntax for MAKE is

To get command-line
help for MAKE, type
MAKE -?orMAKE

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.

-h.

Chapter 12, Using MAKE

MAKE [options ... J [targets [s JJ

175

If you type MAKE at the command prompt, MAKE performs the following
default tasks:
To place MAKE
instructions in a file
other than
MAKEFILE, see the
section titled "MAKE
options."

1. 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 BUILTINS.MAK,
MAKE looks for a file called MAKE FILE or MAKEFILE.MAK. If MAKE
can't find any of these files, it gives you an error message.
2. 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 "Using makefiles" for more information on instructions in
makefiles.
3. 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.
4. 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 192.
You can stop MAKE by using Ctrl+Break or Ctrl+C.

BUlLTINS.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 Ctt - (C) Copyright 1992 by Borland International
#

CC = BCC
AS = TASM
RC= RC
.asm.obj:
$ (AS)
.e.exe:
$(CC)
.e.obj:
$(CC)
.epp.obj:
$(CC)

176

$ (AFLAGS) $&.asm
$ (CFLAGS) $&.e
$ (CFLAGS) Ie $&.e
$ (CPPFLAGS) Ie $&.epp

Borland C++ Users Guide

.rc.res:
$(RC) $ (RFLAGS) /r $&
. SUFFIXES: .exe .obj .asm .c .res .rc

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 "newe.r" than the files that depend on it.

Using
TOUCH.EXE

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:
You can use
wildcards * and? with
TOUCH.

touch filename [filename ... ]

TOUCH updates the file's creation date and time.
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.

Important!

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 make file, type MAKE -fPROJECTA.MAK (a space after-f
is optional). Many of the command-line options have equivalent directives
that are used in the make file (see page 188 for more information on
directives).

MAKE optio,ns

Table 12.1: MAKE options

Option

Description

-h or -?

Displays MAKE options and shows defaults with a trailing plus sign.

-B

Builds all targets regardless of file dates.

-Dmacro

Defines macro as a single character, causing an expression !ifdef macro written in the makefile to
return true.

[-D]macro=[string]

Defines macro as string. If string contains any spaces or tabs, enclose string in quotation marks. The
-D is optional.

-I directory _

Searches for include files in the current directory first, then in directory.

-K

Keeps temporary files that MAKE creates (MAKE usually deletes them). See also KEEP on page 179.

-N

Executes MAKE like Microsofts NMAKE (see the section following this table for more information).

-Umacro

Undefines previous definitions of macro.

-W

Writes the current specified non-string options to MAKE.EXE making them defaults.

-ffilename

Uses filename or filename.MAK instead of MAKEFILE (space after -1 is optional).

Chapter 12, Using MAKE

177

Table 12.1: MAKE options (continued)

-a

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.

-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).

-ddirectory

Used with -S to specify the drive and directory MAKE uses when it swaps out of memory. The option is
ineffective when used with the MAKER.

-e

Ignores a macro if its name is the same as an environment variable (MAKE uses the environment
variable instead of the macro).

-i

Ignores the exit status of all programs run from

-m
-n

Displays the date and time stamp of each file as MAKE processes it.

-p

Displays all macro definitions and implicit rules before executing the makefile.

-q

Returns 0 if the target is up-to-date and nonzero if is is not (for use with batch files).

MAK~

and continues the build process.

Prints the commands but doesn't actually perform them, which is helpful for debugging a makefile.

, -r

Ignores any rules defined in BUlLTINS.MAK.

-s
-S

Suppresses onscreen command display.
Swaps MAKER out of memory while commands are executed, reducing memory overhead and
allowing compilation of large modules. This option has no effect on MAKER.

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 MAKE -m- -W to turn off the default option. When MAKE asks you to
write changes to MAKE.EXE, type Y.
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 -Woption
doesn't work with the fC?llowing MAKE options:

_ -Dmacro
_ -Dmacro=string
_ -ddirectory
_-Usymbol
Compatibility with
Microsofts NMAKE

178

_ -ffilename
_ -? or -h
_ -Idirectory

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:

Borland C++ Users Guide

• 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.
«TEMPFILE.TXT!
text
!KEEP

If you don't want to keep a temporary file, type NOKEEP or type only
the temporary file name. 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 $ «D)
normally returns C: \CPP\, the -N option makes it return C: \CPP.
• Unless there's a matching .suffixes directive, MAKE searches rules from
bottom to top of the makefile.
• The $* macro always expands to the target name instead of the
dependent in an implicit rule.

Using makefiles
A makefile is an ASCII file of instructions for MAKE.EXE. MAKE assumes
your makefile is called MAKEFILE or MAKEFILE.MAK unless you use the
-f option (see page 177).
MAKE either builds targets you specify at the MAKE command line or it
builds only the first target it finds in the makefile (to build more than one
target, see the section "Symbolic targets.") Makefiles can contain:
.• Comments
• Macros
• Directives
• Explicit rules
• Implicit rules
Symbolic targets

A symbolic target forces MAKE to build multiple targets in a make file (you
don't need to rely on linked dependencies). The dependency line lists all
the targets you want to build. You don't type any commands for a symbolic
target.
In the following makefile, the symbolic target allFiles builds both FILE1;EXE
and FILE2.EXE.
-

Chapter 12, Using MAKE

179

allFiles: filel.exe file2.exe
filel.exe: filel.obj
bee file1. obj
file2.exe: file2.obj
bee file2. obj

Rules for symbolic
targets

#Note this target has no commands.

Observe the following rules with symbolic targets:
• Symbolic targets don't need a command line.
• Give your symbolic target a unique name; it can't be the name of a file in
your current directory.
• Name symbolic targets according to the operating system rules for
naming files.

Explicit and implicit rules
The explicit and implicit rules that instruct MAKE are generally defined as
follows:
• Explicit rules give MAKE instructions for specific files.
• Implicit rules give general instructions that MAKE follows when it can't
find an explicit rule.
Rules follow this general format:
Dependency line
Commands

The dependency line is different for explicit and implicit rules, but the
commands are the same (for information on linked dependencies see
page 176).
MAKE supports multiple rules for one target. You can add dependent files
after the first explicit rule, but only one should contain a command line. For
example,
Targetl: dependentl dep2 dep3 dep4 dep5
Targetl: dep6 dep7 dep8
bee -e $**

Explicit rule
syntax

180

Explicit rules are instructions to MAKE that specify exact file names. The
explicit rule names one or more targets followed by one or two colons. One

Borland e++ Users Guide

colon means one rule is written for the target; two colons mean that .two or
more rules are written for the target.
Explicit rules follow this syntax:
Braces must be
included if you use
the paths parameter.

target [target. .. ]: [:] [{path}] [dependent [s] ... ]
[commands]

to

The name and extension of the file be updated (target
must be at the start of the line-no spaces or tabs are
allowed). One or more targets must be separated by spaces
or tabs. Don't use a target's name more than once in the
target position of an explicit ru'ie in a makefile.
• path
A list of directories, separated by semicolons and enclosed
in braces, that points to the dependent files.
• dependent The file (or files) whose date and time MAKE checks to see if
it is newer than target (dependent must be preceded by a
space). If a dependent file also appears in the makefile as a
target, MAKE updates or creates the target file before using
it as a dependent for another target.
• commands Any operating system command. Multiple commands are
allowed in a rule. Commands must be indented by at least
one space or tab (see the section on commands on page 183).
• target

If the dependency or command continues on to the next line, use the
backslash (\) at the end of the line after a target or a dependent file name.
For example:
MYSOURCE.EXE: FILE1.OBJ\
FILE2.0BJ\
FILE3.0BJ
bee filel.obj file2.obj file3.obj

Single targets with
multiple rules

A single target can have more than one explicit rule. You must use the
double colon:: after the target name to tell MAKE to expect multiple
explicit rules. The following example shows how one target can have
multiple rules and commands .
. epp.obj:
bee -e -neobj $<
.asrn.obj:
tasrn /rnx $<, asrnobj\\
mylib.lib :: fl.obj f2.obj
echo Adding C files

Chapter 12, Using MAKE

181

tlib mylib -+cobj\fl -+cobj\f2
mylib.lib :: f3.obj f4.obj
echo Adding ASM files
tlib mylib -+asmobj\f3 -+asmobj\f4

Implicit rule
syntax

An implicit rule starts with either a path or a period and implies a targetdependent file relationship. Its main components are file extensions
separated by periods. The first extension belongs to the dependent, the
second to the target.
'

If implicit dependents are out-of-date with respect to the target or if they
don't exist, MAKE executes the commands associated with the rule. MAKE
updates explicit dependents before it updates implicit dependents.

Implicit rules follow this basic syntax:
[{source_dirs}] . source_ext [{target_dirs}] .target_ext:
[commands]

• {source_dirs} The directory of the dependent files. Separate multiple
directories with a semicolon.
• .source_ext
The dependent file-name extension.
• {target_dirs} The directory of the target (executable) files. Separate
multiple directories with a semicolon.
• .target_ext
The target file-name extension. Macros are allowed here.
•:
Marks the end of the dependency line.
• commands
Any operating system command. Multiple commands are
allowed. Commands must be indented by one space or
tab (see the section on commands on page 183).
If two implicit rules match a target extension but no dependent exists,
MAKE uses the implicit rule whose dependent's extension appears first in
the .sUFFIXES list. See the ".suffixes" section on page 192.
Explicit rules with
implicit commands

See page 186 for
information on default
macros.

182

A target in an explicit rule can get its command line from an implicit rule.
The following example shows an implicit rule and an explicit rule without
a command line .
. c.obj:
bcc -c $<

#This command uses a macro $< described later.

myprog.obj:

#This explicit rule ,uses the command: bcc -c myprog.c

The implicit rule command tells MAKE to compile MYPROG.C (the macro
$< replaces the name myprog. obj with myprog. c).

Borland C++ Users Guide

Commands
syntax

Commands can be any operating system command, but they can also
include MAKE macros, directives, and special operators that operating
systems can't recognize (note that I can't be used in commands). Here are
some sample commands:
cd ..
bcc -c rnysource.c
COpy *.OBJ C:\PROJECTA

bcc -c $(SOURCE)

#Macros are explained later in the chapter.

Commands follow this general syntax:
[prefix ... J commands
Command prefixes

Table 12.2
Command prefixes

Commands in both implicit and explicit rules can have prefixes that modify
how MAKE treats the commands. Table 12.2 lists the prefixes you can use
in makefiles; each prefix is explained in more detail following the table.
Option

Description

@

Don't display command while it's ,being executed.

-num

Stop processing commands in the makefile when the exit code returned from
command exceeds num. Normally, MAKE aborts if the exit code is nonzero. No
white space is allowed between - and num.
Continue processing commands in the makefile, regardless of the exit code
returned by them.

&

Using

@

Expand either the macro $**, which represents all dependent files, or the macro
$?, which represents all dependent files stamped later than the target. Execute the
command once for each dependent file in the expanded macro.

The following command uses the modifier @, which prevents the
command from displaying onscreen when MAKE executes it.
diff.exe : diff.obj
@bcc dif f. obj

Using -num and -

Chapter 12, Using MAKE

The -nurn and - modifiers control MAKE processing under error
conditions. You can choose to continue with the MAKE process if an error
occurs or only if the errors exceed a given number.

183

In the following example, MAKE continues processing if BCC isn't run
successfully:
target.exe : target.obj
target.obj : target.cpp
bee -c target.cpp

The & modifier issues a command once for each dependent file. It is
especially useful for commands that don't take a list of files as parameters.
For example,

Using &

eopyall : filel.epp file2.epp
© $** e:\temp

results in COpy being invoked twice as follows:
copy filel.cpp e:\temp
copy file2.epp c:\temp
/

Without the & modifier, COpy would be called only once.
Command
operators
Table 12.3
Command operators

Debugging with
temporary files

You can use any operating system command in a MAKE commands
section. MAKE uses the normal operators (such as +,-, and so on), but it
also has other operators you can use.
Operator

Description

<

Take the input for use by command from file rather than from standard input.

>

Send the output from command to file.

»

Append the output from command to file.

«

Create a temporary, in line 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.

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

184

Borland C++ Users Guide

TLINK Ie &&!
eOs.obj $**
prog.exe
prog.map
maths.lib es.lib

The response file created by && contains these instructions:
eOs.obj a.obj b.obj
prog.exe
prog.map
maths.lib es.lib

Using MAKE macros
Macros are casesensitive: MACR01 is
different from
Macro1.

A MAKE macro is a string that is expanded (used) wherever the macro is
called in a makefile. Macros let you create template makefiles that you can
change to suit different projects. For example, to define a macro called
LIBNAME that represents the string "mylib.lib," type LIBNAME = mylib.lib.
When MAKE encounters the macro $ (LIBNAME), it uses the string mylib.lib.
If MAKE finds an undefined macro in a makefile, it looks for an operating-

system 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 the manuals for your
operating system for information on defining environment variables.)
Defining macros

The general syntax for defining a macro in a make file is MacroName =
expansion_text.

• MacroName is case-sensitive and is limited to 512 characters .
• expansion_text is limited to 4096 characters consisting of alphanumeric
characters, punctuation, and white space.
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 -0 (see page
177). 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 eornrnand="bee -e"

Chapter 12, Using MAKE

185

make command=bcc option=-c

The following differences in syntax exist between macros entered on the
command line and macros written in a makefile.
Table 12.4
Command line vs.
makefile macros

Using a macro

Syntax

Makefile

Command line

Spaces allowed before and after =

Yes

No

Space allowed before macroName

No

Yes

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:
I

• 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.
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=$(MY~XT))

Default MAKE
macros

186

#Changes fl.cpp to fl.C, etc.

MAKE contains several default macros you can use in your makefiles.
Table 12.5 lists the macro definition and what it expands to in explicit and
implicit rules.

Bor/and c++ Users Guide

Table 12.5: Default macros
Macro

Expands in implicit:

Expands in explicit:

Example

$*

path\dependent file

path\target file

C:\PROJECTA\MYTARGET

$<

path\dependent file+ext

path\target file+ext

C:\PROJ ECTA\MYTARG ET.OBJ

$:

.
$.

path for dependents

path for target

C:\PROJECTA

dependent file+ext

target file + ext

MYSOURCE.C

$&

dependent file

target file

MYSOURCE

$@

path\target file+ext

path\target file+ext

C:\PROJECTA\MYSOURCE.C

$**

path\dependent file+ext

all dependents file+ext

FILE1.CPP FILE2.CPP FILE3.CPP

$?

path\dependent file+ext

old dependents

FILE1.CPP

Table 12.6
Other default macros

Macro

Expands to:

__MSDOS_ _

Modifying default
macros

Comment

--------------------------------------------------------If running under DOS.

__ MAKE__

Ox0370

MAKEs hex version number.

MAKE

make

MAKEs executable file name.

MAKEFLAGS

options

The options typed at the command line.

MAKEDIR

directory

Directory where MAKE.EXE is located.

When the default macros listed in Table 12.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 12.7 lists macro modifiers and provides examples of their use.

Table 12.7
File-name macro
modifiers

Chapter 12, Using MAKE

Modifier

Part of file name expanded

Example

Result

0

Drive and directory

$«0)

C:\PROJECTA\

F

Base and extension

$«F)

MYSOURCE.C

B

Base only

$«B)

MYSOURCE

R

Drive, directory, and base

$«R)

C:\PROJECTA\MYSOURCE

187

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 12.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 12.8
MAKE directives

Directive

Option

Description

.autodepend

-a

Turns on autodependency checking .

!elif

Acts like a C else if.

!else

Acts like a C else.

!endif

Ends an !if, !ifdef, or !ifndef statement.

!error

Stops MAKE and prints an error message.

!if

Begins a conditional statement.

!ifdef

If defined that acts like a C ifdef, but with macros rather than
#define directives.

!ifndef

If not defined .

.ignore

-i

!include

Specifies a file to include in the makefile.

!message

Lets you print a message from a makefile .

.noautodepend

-a-

Turns off autodependency checking.

.nolgnore

-i-

Turns off .Ignore.

.nosilent

-s-

Displays commands before MAKE executes them.

.noswap

-S-

Tells MAKE not to swap itself out of memory before executing a
command.

.path.ext

Tells MAKE to search for files with the extension .ext in path
directories.

.precious

Saves the target or targets even if the build fails .

.silent

-s

.suffixes
.swap
!undef

188

MAKE ignores the return value of a command.

Executes without printing the commands.
Determines the implicit rule for ambiguous dependencies.

-S

Tells MAKE to swap itself out of memory before executing a
command.
Clears the definition of a macro.

Borland C++ Users Guide

.autodepend

!error

Autodependencies occur in .OBJ 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 .OBJ. If the dates and times of the files used to
build the .OBJ are different from the date-time stamp of the.OBJ file, the
.OBJ file is recompiled. You can use .autodepend or -a in place of linked
dependencies (see page 176 for information on linked dependencies).
Thi~

is the syntax of the !error directive:

lerror 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
lerror MYMACRO isn't defined
lendif

If MYMACRO in the example isn't defined, MAKE prints the following
message:
Fatal makefile 4: Error directive: MYMACRO isn't defined

Summing up errorchecking controls

Chapter 12, Using MAKE

Four different controls turn off error checking:
• The .ignore directive turns off error checking for a selected portion of the
makefile.
• The -i command-line option turns off error checking for the entire
makefile.
• The -num comm~nd operato:t; 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.

189

!if and other
conditional
directives

The !it directive works like C it statements (see the Programmer's Guide if
you don't understand it statements). As shown here, the syntax of !it 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)
, !ifndef macro and! if, ! $d (macro)
These rules apply to conditional directives:
_ One !else directive is allowed between lit, !itdet, or !itndet and !endit
directives.
_ Multiple !elif directives are allowed between lit, !itdet, or !itndet and
!else directives and !endif.
_ You can't split rules across conditional directives.
_ You can nest conditional directives.
_ lit, !ifdef, and !ifndet must have matching !endit directives within the
same source file.
The following information can be included between !it and !endit
directives:
_ Macro definition
_ !include directive
_ Explicit rule
_ terror directive
, _ Implicit rule
_ !undet directive

Condition in it statements represents a conditional expression consisting of
decimal, octal, or hexadecimal constants and the operators shown in
Table 12.9.

190

Borland C++ User's Guide

Table 12.9
Conditional operators

Operator

Description
Negation

Operator

?:

Bit complement

Description
Conditional expression
Logical NOT

Addition

»

Right shift

Subtraction

«

Left shift

Multiplication

&

Bitwise AND

Division

I

Bitwise OR

%

Remainder

Bitwise XOR

&&

"

Logical AND

>=

Greater than or equal*

II

Logical OR

<=

Less than or equal*

>

Greater than

--

Equality*

<

Less than

!=

Inequality*

+

·Operator also works with string expressions.

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 havi:J;lg trouble with
a macro definition, you could put this line in your makefile:
!message The macro is defined here as: $ (MacroName)

Chapter 12, Using MAKE

191

When MAKE interprets this line, it will print onscreen The macro is defined
here as: . CPP, if th~ 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:\CSOURCEiC:\CFILES
.path.obj = C:\OBJS

.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 want
the library to be 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. suffixes: . 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: .asrn .c .cpp
rnyprog.exe: rnyprog.obj
tlink rnyprog.obj
.cpp.obj:
bcc -P $<
.asrn.obj:

192

Borland C++ Users Guide

tasm /mx $<
.e.obj:
bee -p- $<

The syntax of the !undef directive is:

!undef

!undef MaeroName
!undef (undefine) clears the given macro, MacroName, causing an !ifdef

MacroName test to fail.
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

Caution!

Null macros

#If DEBUG is defined,
#eompile with debug information;
#otherwise (else)
#don't include debug information.

Don't use the $d macro when MAKE is invoked with the -N option.
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 =

One of the following lines can define a null macro on the MAKE command
line:
NULLMACRO=" "

or
-DNULLMACRO

Chapter 12, Using MAKE

193

194

Borland C++ Users Guide

p

A

R

T

II

Using Resource Workshop
This section of the User's Guide describes how to use Resource Workshop, a
tool that integrates the entire process of designing and compiling resources
for applications running under Microsoft Windows, Version 3.0 and later.
. Resource Workshop,
• Works with resources in either text or binary format. It includes
graphics~oriented editors that let you editbinary files and a text editor
that lets you edit the fil~s as resource scripts.
• Makes it easy to manage hundreds of resources stored in dozens of files.
• Includesmultilevel Undo and Redo features that let you step back
through changes you've made.
• Includes all the compilers you need and lets you compile your resources
.
only when you need to.
• Decompiles birlary resource files, so you can change a program's
resources even if you don't have access to the source code.
• Includes features that automatically check for errors, making it easy to
test .resources for errors like incorrect syntax and duplicate .resource IDs.
There arefouronlme files for Resource Workshop. These filesinc1ude
.
advanced information that most users don't need.
• BWCCAPI.TXT
• CUSTCNTLTXT

Describes the BWCCApplication Program Interface
(API).
Describes how to create custom control classes.·It
inchides sample code for C++.andfascaLYou
should be familiar with this material ifyou plan to
createy()ur owncustoIIl. control classes.
Describes some of the considerations that wenfiftto
designing Borlan

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
Create Date                     : 2013:01:15 19:13:55-08:00
Modify Date                     : 2013:01:15 22:29:38-08:00
Metadata Date                   : 2013:01:15 22:29:38-08:00
Producer                        : Adobe Acrobat 9.52 Paper Capture Plug-in
Format                          : application/pdf
Document ID                     : uuid:faa97905-722c-48f3-ba43-70dc30d6e9d0
Instance ID                     : uuid:f9106f5c-47bc-4289-b340-60ef3e91ede5
Page Layout                     : SinglePage
Page Mode                       : UseNone
Page Count                      : 462
EXIF Metadata provided by EXIF.tools

Navigation menu