Welcome to Borland C++ 4.0 -------------------------- This README file contains important information about Borland C++. For the latest information about Borland C++ and its accompanying programs and manuals, read this entire file. ----------------- TABLE OF CONTENTS ----------------- 1. How to Get Help 2. Installation 3. Features -Compiler -Linker -IDE -Turbo Debugger -Resource Workshop -Documentation 4. Important Information -General -New Tools -Running from a Windows 3.1 DOS Prompt -C/C++ Language Changes -Developing for NT -Libraries and Startup Code -New Compiler and Linker Switches -Converting Your Borland C++ 3.1 Windows Code to Borland C++ 4.0 -Class Libraries -Casting Macros -IDE/Integrated Debugging -Floating Point Formats -Turbo Debugger for Windows -Using Tools with NTFS ------------------ 1. HOW TO GET HELP ------------------ If you have any problems, please read this file, the HELPME!.DOC and other files in your DOC subdirectory, and check the on-line help and the Borland C++ manuals first. If you still have a question and need assistance, help is available from the following sources: 1. For instant on-line access to the Borland forums with their libraries of technical information and answers to common questions, type GO BCPPDOS - for questions pertaining to DOS or GO BCPPWIN - for questions pertaining to Windows If you are not a member of CompuServe, see the enclosed special offer, and write for full details on how to receive a free IntroPak containing a $15 credit toward your first month's on-line charges. 2. Borland offers a wide variety of Technical Support plans providing a range of assistance from installation and general usage of Borland C++ to language syntax, programming, and debugging help. For information about these support programs, call 1-800-523-7070. 3. Borland's TECHFAX service. Call (800) 822-4269 for a FAX catalog of technical document entries. 4. Borland DLBBS. Dial (408) 431-5096 (up to 9600 baud, 8-N-1) for a host of free technical documents and example programs. --------------- 2. INSTALLATION --------------- Important! ---------- Do not install Borland C++ 4.0 files over previously installed Borland C++ directories. The files in this distribution will not work with previously shipped tools and libraries. This is particularly true for configuration files from previous shipping releases, like TDCONFIG.TDW and BCCONFIG.BCW. Also, be especially careful to avoid using object files and libraries from Borland C++ 3.1 with binaries created with this release, as they are not compatible and may cause unpredictable link failures or executables. Installing Borland C++ 4.0 on your hard disk: -------------------------------------- Installing from floppy disks: 1. Select File|Run from Windows 3.1, Windows for Workgroups 3.1x, or Windows NT. 2. Enter A:INSTALL (or B:INSTALL) on the input line. 3. Under "Installation Options", you have the option of not installing Win32s, which should be turned off if you are installing under Windows NT. (NOTE that BCW does not run under NT, so if you are only using NT, you may wish to not install it.) 4. Fill in directories as appropriate, and INSTALL will create appropriate Windows groups, install Win32s, and install the new Borland C++ 4.0 software according to the directories you select. Installing from the CDROM: 1. Go to the CDROM, and change directories to INSTALL. 2. Select File|Run from Windows 3.1, Windows for Workgroups 3.1x, or Windows NT. 3. Enter X:INSTALL on the input line (where X: is your CDROM drive). 4. Under "Installation Options", you have the option of not installing Win32s, which should be turned off if you are installing under Windows NT. 5. Fill in directories as appropriate, and INSTALL will create appropriate Windows groups, install Win32s, and install the new Borland C++ 4.0 software according to the directories you select. To use the built-in transfer tools and Help, make sure their location is in your path (the \BIN directory for Borland C++ 4.0). After installing, make sure your path is set correctly, and restart Windows before using Borland C++ 4.0. NOTE: If you want to install the Win32s debug kernel, use the SWITCH.BAT file provided with the Microsoft Win32s tools, found on the NT SDK CD-ROM distribution. This will ensure that the proper files are copied to the appropriate places. Not copying the files correctly will result in obscure load errors. Configuring Borland Pascal and Borland C++ ------------------------------------------ The install program for Borland C++ 4.0 will configure your system to allow the use of Borland C++ 4.0 and Borland Pascal 7.0 on the same machine. As long as you have installed Borland Pascal prior to (rather than after) installing Borland C++ there are very few guidelines you must follow: - The two Windows hosted IDEs may not be run simultaneously. - Each must use their respective copies of tools and utilities that depend on debug information, most notably Turbo Debugger for Windows (TDW). You may find it useful to rename the Borland Pascal version of TDW.EXE to something like BPTDW.EXE to avoid confusing filenames in your path. - Both versions of TDW may not be run simultaneously. - Make sure that old copies of TDW.INI are removed from your system. (Running the utility TDWINI.EXE will make sure that this takes place.) That's all there is to it! To reduce disk space requirements, you may wish to remove duplicate versions of utilities that do not require debug information, such as WinSight and Resource Workshop. In these cases, you will want to use the versions that came with Borland C++ 4.0 so that you will have the latest features. If you wish to use TDWGUI.DLL with TDW version 3.1 you need to manually add UseTimer=Yes to the VideoOptions section of TDW.INI. Note that this option should not be set when using TDW version 4.0. This means that you would need to hand change your TDW.INI file each time you switched between versions of TDW. For this reason, we recommend the non-windowed video DLLs (such as SVGA.DLL) for customers who debug both BP and BC applications. If you are installing Borland Pascal 7.0 AFTER Borland C++ 4.0 has been installed, you will have to manually change the system settings that allow these products to coexist: In your system.ini file, check your [386Enh] section for multiple entries for the device TDDEBUG.386. Remove duplicate entries of TDDEBUG.386 so that only the version from Borland C++ is loaded. On disk, you may also want to rename or remove the BP7 versions of TDDEBUG.386 and TDWIN.DLL to avoid their accidental loading. You must restart Windows after making changes to system.ini. Win32s and minimum swap file size --------------------------------- Borland recommends that you have a minimum of 12 MB of memory available to run Win32s applications. For example, if your machine has 8 MB of memory available to Windows, you should configure your "Virtual Memory" (swapfile) to at least 4 MB. This will reduce the risk of out-of-memory errors occuring in Win32s. Changes to SYSTEM.INI file -------------------------- The install program makes these changes to the SYSTEM.INI file: 1) Adds "device=c:\bc4\bin\windpmi.386" to support our 32-bit tools. 2) Adds "device=c:\bc4\bin\tddebug.386" to support our debugger. Configuring the Windows NT command prompt ----------------------------------------- To run 16-bit protected-mode programs (bcc, tlink) under an NT command prompt you need to add the following line to CONFIG.NT: ntcmdprompt Under the default NT command-line prompt, DOS COMMAND.COM is run after returning from a TSR (such as RTM.EXE which bcc and tlink load). Adding the above line will cause the original NT CMD.EXE to be run. Outdated versions of Win32s --------------------------- If you are running an outdated version of Win32s, the INSTALL program will instruct you to remove it before installation. To remove an old version of Win32s perform the following steps: 1. Change directory to the WINDOWS directory on your hard drive. This is most likely C:\WINDOWS. 2. Edit the SYSTEM.INI file and remove the line in the [386Enh] section that reads: device=C:\WINDOWS\SYSTEM\WIN32S\W32S.386 (The actual path in the above line may be different to reflect your configuration.) 3. Change directory to the SYSTEM subdirectory. 4. Remove the following files: W32SYS.DLL WIN32S.INI WIN32S16.DLL 5. Change directory to the WIN32S subdirectory. 6. Remove all files here. 7. Change directory back to SYSTEM and remove the WIN32S subdirectory. You will now be ready to run the INSTALL program. Be sure to select in the INSTALL program so that the newer version of Win32s will be installed on your system. ----------- 3. FEATURES ----------- Compiler: --------- - Support for writing 16- and 32-bit Windows applications that target Win32s and Windows NT, and 16-bit DOS applications. - Support for ANSI C++ exception handling, structured exception handling under C, and mixed C/C++ exception handling. All exception handling constructs are available for both 16- and 32-bit. - Support for three character types as provided in ANSI C++. - Support for ANSI C++ operator new[] and operator delete[]. - Runtime Library support for the ANSI C++ string class. - Additional optimizations and faster compile time. - Support for ANSI C++ runtime type identification (RTTI). - Support for ANSI C++ new style cast dynamic_cast, and proposed casts static_cast, const_cast, and reinterpret_cast. - Linker (16-bit and 32-bit): --------------------------- - Now handles binding of resources; no need for a separate RC or RLINK step. - Linker debug capacity expanded. IDE --- - Expanded editor support, including column blocking and window splitting. TEMC now called KEYMAPR. - Integrated GUI debugging for 16-bit Windows applications. - A new project manager that supports multiple targets, drag-and-drop, and Style Sheets for associating options. - AppExpert, which simplifies the process of creating ObjectWindows applications through code generation. - ClassExpert, which simplifies adding and managing classes in your AppExpert application. - Includes both 16- and 32-bit tools (compiler, linker, resource compiler, resource binder, and library manager) Turbo Debugger: --------------- - Built in large model for greater capacity. - Turbo Debugger (TD32) for Win32s and Windows NT. - Remote debugging with TDW. - Support for OS exception handling. - Support C/C++ exception handling. - Session state saving. - Windows NT thread support. - Process attach for Windows NT. - Video DLL to run TDW in a window. - Turbo Debugger Video Configuration Utility (TDWINI.EXE). Resource Workshop: ------------------ - Support for Win32s, Win32. - Resource preview - DialogExpert (gallery) - Auto ID numbering - Auto mapping of accelerators and help hints to menu items - Support for VBX controls - SpeedMenus - Dialog editor property inspector - Slave mode interaction with ClassExpert and IDE project manager - 16 and 32-bit resource support - Win32 resource extensions language Documentation: -------------- This distribution includes printed and online documentation to help you understand and use the new features of Borland C++ 4.0, as well as online Help. For C++ Language and Programming information: See the Library Reference the Programmer's Guide, and the DOS Reference. See also the online Help. For information on using MAKE, TLINK, and resource tools: See the User's Guide. See also the online Help. For information on keyboard mapping and KEYMAPR (used to be called TEMC): See the online Help. For information on using the IDE, AppExpert & ClassExpert, the Integrated Debugger, and compiling options: See the User's Guide. See also the online Help. For information on using the new Project Manager: See the online Help. For information on converting your ObjectWindows 1.0 code to ObjectWindows 2.0: See the ObjectWindows Programmer's Guide. For information on programming in ObjectWindows 2.0: See the ObjectWindows Reference Guide, and the ObjectWindows Programmer's Guide. See also the online text file, owldoc.wri. For help using Turbo Debugger: See the online text files helpme!.tdw and hints.tdw. See also the online Help. To use the online Help, make sure the Borland C++ 4.0 \BIN directory is on your path. ------------------------ 4. IMPORTANT INFORMATION ------------------------ GENERAL ------- Note that if you have only 8 MB of RAM, you might experience some out-of-memory problems building and using 32-bit applications. Please see the section below titled, "Out of memory and MAKESWAP". BCC and precompiled headers --------------------------- When BCC32.EXE creates precompiled header files, the default name is BC32DEF.CSM. This file is created in the BIN directory where BCC32 resides. Similarly, BCC creates a file called BCDEF.CSM. 32-bit DLL entry point ---------------------- The 32-bit DLL entry point has been changed. In the previous field test, the entry point was LibMain(HINSTANCE, ULONG,LPVOID). This is inconsistent with Win32, and can cause serious runtime problems if you use the older 16-bit version of LibMain. The new, correct entry point for 32-bit DLLs only is BOOL WINAPI DllEntryPoint(HINSTANCE, DWORD, LPVOID) See Chapter 9 in the Programmer's Guide for more information on DllEntryPoint. RTL Change ---------- The 16-bit DOS-only functions and libraries are documented in the DOS Reference The names of 5 RTL global variables and 7 functions have changed in Borland C++ 4.0. Several global variables and library functions have been renamed. See the Library Reference, Chapter 1. RC Users -------- RC.EXE is not included in Borland C++ 4.0. You should use Borland C++ 4.0's BRC or BRC32 instead of RC. Network problems ---------------- If you have problems running TDW, TD32, or MAKE when running under Windows For Workgroups or Windows for Workgroups/Win32s, it is advisable to remove network support. This includes removing the network parameters from AUTOEXEC.BAT and CONFIG.SYS. Object File Format ------------------ This product is designed to use and generate only object files which adhere to the Intel OMF (Object Module Format) specification. This means that TLINK32 and TLIB only accept files of this format, and all provided libraries use this format. There is no support in the linker or librarian for COFF object modules produced by Microsoft C tools. MAKE ---- MAKE will not put a space between two sets of file list macros as in BC++ 3.1 and before. The example makefile below illustrates this; simply execute MAKE in the directory containing the makefile. The output is: ALLOBJS1 = one onetwo two ALLOBJS2 = one one two two makefile: OBJS1 = \ one \ one OBJS2 = \ two \ two ALLOBJS1 = $(OBJS1)$(OBJS2) ALLOBJS2 = $(OBJS1) $(OBJS2) ..: @@echo ALLOBJS1 = $(ALLOBJS1) @@echo ALLOBJS2 = $(ALLOBJS2) Out of Memory and MAKESWAP -------------------------- If you get "Out of Memory" errors from DOS when running the command-line tools, create a swap file with the MAKESWAP utility. (Note that this applies to DOS only, not to DOS boxes opened under Windows.) MAKESWAP takes the size of the file to create in KBytes, for example: MAKESWAP 12000 will create a 12MB swap file in the current directory called EDPMI.SWP for use by Borland command line tools. To enable the swap file, use the DPMIMEM environment variable by issuing the following command at the DOS prompt: set DPMIMEM=SWAPFILE \EDPMI.SWP Note that you must clear this environment variable by issuing the command set DPMIMEM= before running Paradox or other 16-bit DPMI-hosted executables, such as Borland C++ 3.1 command-line tools. Threads ------- When creating secondary threads, the _beginthread or _beginthreadNT and _endthread() RTL functions must be used to ensure the proper RTL initialization and cleanup. Using NT's CreateThread and ExitThread functions will result in undefined behavior if an implicit or explicit call is made to the RTL. Note that using exception handling and/or RTTI can lead to implicit RTL calls. DDVT functions and RTTI ----------------------- When compiling code that contains DDVT functions, do not use run-time type information. If you attempt this, you will receive an error message. In order to compile without using run-time type information, compile all code that uses DDVTs (for instance OWL 1.0x libraries and applications) with the -RT- switch (Options|Project|C++ Options|Exception handling\RTTI in the IDE). ---------- New Tools ---------- The 16-bit linker has been modified to allow for more than 64K symbols in the symbol table in the debug information for an .exe. This required a modification to the format of the debug info being generated (by the linker, not the compiler). As a result, the following tools have been updated to correspond to this modification to TLINK: TDW, TDUMP, TDUMP32, the IDE Debugger, the IDE Browser These tools have been "versioned" so that if you attempt to use any of them with "old" EXEs, they will output an error message and refuse to run. The "solution" to this error condition is to relink using the new TLINK.EXE. Unfortunately, if you use an old TDUMP or TDUMP32 (i.e., the BETA1 version) it checks for version 4.0 AND GREATER. If you dump an exe and get GARBAGE, please check the symbolic debug version number contained in the header. If it is 4.01, make sure that you are using the correct version of TDUMP (the TDUMP and TDUMP32 versions print out "Version 4.1" in the banner when they are run). Note that these changes are for TLINK and all tools dependent on the output from TLINK. ------------------------------------- Running from a Windows 3.1 DOS Prompt ------------------------------------- If you run BCC32 or TLINK32 from a Windows DOS box and you get out of memory errors, increase the XMS memory (in the 'Maximum' setting) allocated for the DOS box by editing the appropriate .PIF file (usually DOSPRMPT.PIF). BCC32.EXE needs about 4MB to compile medium-sized .CPP files, and might need more memory for large .CPP files with debugging information. NOTE: You must set the 'Maximum:' setting to the amount needed, not the 'Required:' setting. Using the 'Required:' setting only sets aside memory for XMS, NOT for DPMI services and hence any amount set in the 'Required:' setting box is unavailable. Following is a sample MAKEFILE for creating a 32-bit Windows application: # # This is a template makefile for creating a Win32s app. # LIBDIR=\bc4\lib libs = import32.lib imprtw32.lib cw32.lib app.exe: app.obj app.res app.def tlink32 /Tpe/aa/L$(LIBDIR) $(LIBDIR)\c0w32.obj app.obj,\ app,\ ,\ $(libs),\ app.def app.res app.def: echo EXETYPE WINDOWS > app.def app.obj: app.c bcc32 -I\bc4\include -c -W app.c app.res: app.rc brcc32 -i\bc4\include app.rc ##### End of MAKEFILE ################################## ------------------ Developing for NT ------------------ To do development on NT, use the command-line tools, Resource Workshop, and TD32. Using the IDE under NT is not currently supported. ---------------------- C/C++ Language Changes ---------------------- Many changes were made to the compiler in compliance with the latest changes proposed by the ANSI C++ committee. These include three distinct char types, enhancements to templates, support for virtual functions differing in return types, and other improvements listed here. See the Library Reference and the Programmer's Guide for complete details on these changes and how they affect your code. wchar_t is a fundamental data type in C++ programs. In C programs it continues to be a typedef defined in stddef.h. See online Help. Enum operator overloading is also supported in this compiler. The runtime library now supports the ANSI C++ string class. If you already have a string class, it must be renamed for Borland C++ 4.0. In addition, operator new and operator new[] now throw an exception (xalloc), as specified by the ANSI C++ committee. To get the old behavior, you can issue set_new_handler(0). (Note, however, that set_new_handler(0) does not work with ObjectWindows or string classes.) See Chapter 3 of the Programmer's Guide. Note that arrays are now being allocated through operator new[]() and deleted by operator delete[](). An example is provided in Chapter 3 of the Programmer's Guide. Borland C++ 4.0 implements ANSI C++ runtime type identification (RTTI). See the Library Reference, "C++ runtime support", for a description of class Type_info. RTTI and operator typeid() are fully described in Chapter 3 of the Programmer's Guide. Borland C++ 4.0 provides a full implementation of exception handling under C++ and C. C exceptions can be handled in C or C++ code; C++ exceptions can be handled only in C++ code. The C++ exceptions are described in the Library Reference, "C++ run-time support." See Chapter 4 of the Programmer's Guide for a full description of how to use exception handling. Borland C++ 4.0 also implements the accepted and proposed ANSI C++ new style casts. See the Chapter 3 of the Programmer's Guide for information and examples. -------------------------- Libraries and Startup Code -------------------------- The contents of the LIB directory are described in the online Help. See the DOS Reference for a description of DOS-only libraries and start-up code. There are two new functions that provide access to 32-bit operating system file handles. See online Help for a description of _open_osfhandle and _get_osfhandle. Member function Type_info::fname() is not available. To link 32-bit executables, use the following libraries and startup code. ==================================================================== Win32 GUI Target Compiler Linker Startup Static Dynamic RTL RTL ---------------- -------- ------ ------- ------ ------- EXE -W -Tpe -aa c0w32 cw32 cw32i Multi-thread EXE -WM -W -Tpe -aa c0w32 cw32mt cw32mti DLL, all funcs -WD -Tpd -aa c0d32 cw32 cw32i exportable DLL, explicit -WDE -Tpd -aa c0d32 cw32 cw32i funcs exported Multi-thread DLL, -WM -WD -Tpd -aa c0d32 cw32mt cw32mti all funcs exported Multi-thread DLL, -WM -WDE -Tpd -aa c0d32 cw32mt cw32mti explicit funcs exported Win32 Console Compiler Linker Startup Static Dynamic Target RTL RTL ---------------- -------- ------ ------- ------ ------- EXE */-WC -Tpe -ap c0x32 cw32 cw32i Multi-thread EXE -WM */-WC -Tpe -ap c0x32 cw32mt cw32mti DLL, all funcs -WCD -Tpd -ap c0d32 cw32 cw32i exportable DLL, explicit -WCDE -Tpd -ap c0d32 cw32 cw32i funcs exported Multi-thread DLL, -WM -WCD -Tpd -ap c0d32 cw32mt cw32mti all funcs exported Multi-thread DLL, -WM -WCDE -Tpd -ap c0d32 cw32mt cw32mti explicit funcs exported NOTES: ------ * In the above tables, (default) indicates that BCC32 defaults to this target. Note: For Win32 EXEs only, there is no difference between "explicit functions exported" and "all functions exportable". Therefore, -WE and -WCE are not available. Note: The compiler defines __MT__ when the -WM switch is used. Note: The compiler defines __CONSOLE__ when the default, -WC, -WCD, and -WCDE switches are used. ---------------------------------- Compiler and Linker Switch Changes ---------------------------------- See the User's Guide for information on new compiler and linker switches. You may get this 32-bit Linker warning: Warning: External symbol was not qualified with __IMPORT in module If the symbol is a function, you can ignore this warning. If the symbol is data, then you must qualify the symbol with __IMPORT. If the warning refers to __pure_error_, you can ignore the warning. BCC32 provides support for the Pentium processor. This support is enabled by the -5 compiler switch. ----------------------------------------------------------------------- Converting Your Borland C++ Version 3.1 Windows Code to Borland C++ 4.0 ----------------------------------------------------------------------- To get your BC++ 3.1 code to compile and run successfully under Borland C++ 4.0, you can modify your code to reflect three character types where compiler errors occur when using the Borland C++ 4.0 RTL includes. Otherwise, you can use the -K2 compiler option with the RTL includes from BC++ 3.1. This option provides for only two character types. (Note that -K2, a backward compatibility switch, is supported only in the 16-bit compiler.) Also, use operator new[]() and delete[]() syntax for class arrays. Note that certain 32-bit to 8-bit conversions allowed by ANSI are flagged by BCC32 with "Conversion may lose significant digits in function XXXXX". You can safely ignore this message if you are doing certain types of 32-bit to 8-bit casts (for instance, int to char) and you're not worried about losing significant digits in those cases. ------------------------------ Changes to the Class Libraries ------------------------------ Only the version of the class library implemented with C++ templates is distributed and directly supported in Borland C++ 4.0. The class library "object-based" include files are provided in the \BC4\INCLUDE\CLASSLIB\OBSOLETE subdirectory. The object-based libraries themselves are not supplied, but can be built using the instructions found in the \BC4\SOURCE\CLASSLIB makefile (see the comments located there). TSArray and TSArrayIterator classes have been added to the class libraries. They are aliases for TSArrayAsVector and TSArrayAsVectorIterator. The Flush and Delete member functions for direct containers (except dictionaries) no longer take a delete parameter (this parameter had been ignored since direct containers have their own copy of the contained element). For example: TMArrayAsVector arr(10); arr.Flush(); // legal arr.Flush(1); // illegal - causes syntax error arr.Detach(index); // legal arr.Detach(index,1); // illegal - causes syntax error TMIArrayAsVector arr1(10); arr1.Flush(); // legal arr1.Flush(1); // legal. arr1.Detach(index); // legal arr1.Detach(index,1); // legal Bag and set container member function FindMember is now called Find. It takes the same parameters. Association containers now have a member function called DeleteElements: void DeleteElements() The dictionary containing the associations determines whether pointed-to objects should be deleted, and, if so, calls DeleteElements for each of the associations it holds. The Detach and Flush member functions for the TMDictionaryAsHashTable template (and all templates derived from it) have been changed to the following: int Detach( const T &t, DeleteType dt = DefDelete ) void Flush( DeleteType dt = DefDelete ) These changes to the direct versions of the dictionary templates makes them similar to an indirect container in how they handle object ownership. Here is an example: TDIAssociation assoc( 3, new int(4) ); //create an association TDictionaryAsHashTable dict; //creates a dictionary dict.Add( assoc ); //copies assoc into the dictionary dict.OwnsElements(); //tell dict that it should delete pointed-to objects dict.Flush(); //deletes the int created by new in the first line. All list and double-list containers now have the DetachAtHead member function. This function removes items from the head of a list without searching for a match. The syntax is int DetachAtHead() // for direct lists int DetachAtHead( int del = 0 ) //for indirect lists Example: TMListImplist; //create list to hold MyObjects list.Add(MyObject()); //construct a MyObject, add to list list.Add(MyObject()); //add second MyObject list.DetachAtHead(); //remove MyObject at head of list Changes to class diagnostics ---------------------------- Previously, in order to create a diagnostic group you had to declare it and define it in the same file: DIAG_DECLARE_GROUP( Sample ); DIAG_DEFINE_GROUP( Sample, 1, 0 ); We also provided a macro that did both of these together: DIAG_CREATE_GROUP( Sample, 1, 0 ); A change in the diagnostic software makes it illegal to have both DECLARE and DEFINE in the same file. So code that creates a diagnostic group now does it in one step: DIAG_DEFINE_GROUP( Sample, 1, 0 ); DIAG_CREATE_GROUP has been removed. DIAG_DECLARE_GROUP still creates an extern declaration for a diagnostic group (see file CHECKS.H and CHECKS.CPP). Code that uses both DIAG_DECLARE_GROUP and DIAG_DEFINE_GROUP in the same file must be changed to remove DIAG_DECLARE_GROUP. Old code: DIAG_DECLARE_GROUP( Sample ); DIAG_DEFINE_GROUP( Sample, 1, 0 ); New code: DIAG_DEFINE_GROUP( Sample, 1, 0 ); Any use of DIAG_CREATE_GROUP must be changed to DIAG_DEFINE_GROUP. Old code: DIAG_CREATE_GROUP( Sample, 1, 0); New code: DIAG_DEFINE_GROUP( Sample, 1, 0 ); Also if a header file uses DIAG_DECLARE_GROUP (so that the group declaration is automatically available to files that #include the header), the source file that contains the DIAG_DEFINE_GROUP invocation for that group will generate a redefinition error (this isn't done anywhere in OWL or class lib). The solution here to conditionalize the header file so that the declaration goes away when the source file with the DIAG_DEFINE_GROUP invocation is built: foo.h ------- #if !defined( BUILD_FOO_GROUP ) DIAG_DECLARE_GROUP( Foo ); #endif foo.cpp ----------- #define BUILD_FOO_GROUP #include "foo.h" Changes to Object Streaming --------------------------- The implementation of Object Streaming formerly used in ObjectWindows and Turbo Vision has been moved into the class library. There have been several changes made to the streaming mechanism, but they should be transparent to existing class library code. See the Programmer's Guide for details on streaming. The header file OBJSTRM.H defines several macros that will make creating streamable objects easier. See that header file for further documentation. There are two types of streamable objects: - Resident objects which may be streamed out but which are not reconstructed when streamed back in - Dynamic objects which are reconstructed when streamed in. Resident objects include static objects and objects present when an application starts, such as its main window. These objects must be streamed out via a reference rather than via a pointer. Dynamic objects, on the other hand, must be streamed out via pointers, causing them to be reconstructed when streamed back in. Resident objects must be streamed out before any objects which stream out pointers to the resident objects, else duplicate objects will be constructed when streaming in. When streaming objects in, Streamer::Read must insure that all data fields are initialized, because the streaming constructor doesn't initialize any of the data fields. Any data members not streamed in must be set to meaningful values. Care must be taken to initialize the members before streaming in base class data or pointers to objects which have pointers back to the current object. Virtual functions are enabled in Streamer::Read. Changes to the string class --------------------------- The following sections correct string class member function definitions. size_t find_first_of( const string _FAR &s ) const Locates the first occurrence in the target string of any character contained in string s. If the search is successful find_first_of returns the character location. If the search fails it returns NPOS. size_t find_first_of( const string _FAR &s, size_t pos ) const Locates the first occurrence in the target string of any character contained in string s after position pos. If the search is successful, it returns the character position within the target string. If the search fails or if pos > length(), it returns NPOS. size_t find_first_not_of( const string _FAR &s) const Locates the first occurrence in the target string of any character not contained in string s. If the search is successful, find_first_not_of returns the character position within the target string. If the search fails it returns NPOS. size_t find_first_not_of( const string _FAR &s, size_t pos ) const Locates the first occurrence in the target string of any character not contained in string s after position pos. If the search is successful find_first_not_of returns the character position within the target string. If the search fails or if pos > length(), find_first_not_of returns NPOS. size_t find_last_of( const string _FAR &s ) const Locates the last occurrence in the target string of any character contained in string s. If the search is successful find_last_of returns the character position within the target string. If the search fails it returns 0. size_t find_last_of( const string _FAR &s, size_t pos ) const Locates the last occurrence in the target string of any character contained in string s after position pos. If the search is successful find_last_of returns the character position within the target string. If the search fails or if pos > length(), find_last_of returns NPOS. size_t find_last_not_of( const string _FAR &s ) const Locates the last occurrence in the target string of any character not contained in string s. If the search is successful find_last_not_of returns the character position within the target string. If the search fails it returns NPOS. size_t find_last_not_of( const string _FAR &s, size_t pos ) const Locates the last occurrence in the target string of any character not contained in string s after position pos. If the search is successful find_last_not_of returns the character position within the target string. If the search fails or if pos > length(), find_last_not_of returns NPOS. -------------- Casting Macros -------------- The following casting macros have been provided, and are defined in DEFS.H: TYPESAFE_DOWNCAST(object,toClass) Converts the pointer referred to by 'object' into a pointer to an object of type 'toClass'. Note that the macro parameters to TYPESAFE_DOWNCAST are in the opposite order from the rest of the macros here. When using a compiler that supports new style casts and runtime type information this is done with dynamic_cast<> and will return 0 if the cast cannot be done. When using a compiler that does not support new-style casts and runtime type information this is done with fake runtime type information generated by the IMPLEMENT_CASTABLE macro. STATIC_CAST(targetType,object) Converts the data object referred to by 'object' into the type referred to by 'targetType'. When using a compiler that supports new style casts, this is done with static_cast<> and will fail if the cast cannot be done without runtime type information. When using a compiler that does not support new-style casts, this is done with an old-style dangerous cast. CONST_CAST(targetType,object) Converts the data object referred to by 'object' into the type referred to by 'targetType'. When using a compiler that supports new style casts, this is done with const_cast<> and will fail if the cast changes the type of the object in any way other than adding or removing const and volatile qualifiers. When using a compiler that does not support new-style casts, this is done with an old-style dangerous cast. REINTERPRET_CAST(targetType,object) Converts the data object referred to by 'object' into the type referred to by 'targetType'. When using a compiler that supports new style casts, this is done with reinterpret_cast<>. When using a compiler that does not support new-style casts, this is done with an old-style dangerous cast. ------------------------- IDE/Integrated Debugging ------------------------- Using the IDE under NT is not currently supported. The default extension for Borland C++ 4.0 project files is IDE. Using the Microsoft DBWIN utility interferes with the Event log's ability to display those same messages. If you wish to see those messages in the Event log, either quit DBWIN or select Options|No Output in DBWIN. If you step over or into a throw() call, the application will run until it reaches a breakpoint or program termination, instead of stopping at the appropriate catch() function. If you wish to debug catch() functions, you must set breakpoints within them. Run to Cursor (F4) will do nothing if the source line you wish to run to is the same source line that the execution point is on. Thus, using F4 to iterate through any loop structure will not work. Setting a breakpoint on a line in the loop, and using Ctrl-F9 (Debug|Run) to iterate through the loop, is the easiest work-around. Once finished with the loop, the breakpoint can be removed. ---------------------- Floating Point Formats ---------------------- Floating point formats are a collection of formatting information used to manipulate floating point numbers in certain runtime library functions such as scanf() and atof(). This section discusses why you might get the error FLOATING POINT FORMATS NOT LINKED : ABNORMAL PROGRAM TERMINATION and tells you how to resolve it. There are no current plans to fix this because it is not a bug. The intent is to avoid linking the floating point formats (about 1K of overhead) when they are not required. The tradeoff of this feature is that the programmer must explicitly request that the floating point formats be linked in for some programs that manipulate floats in a limited and specific fashion. Because you can get the error in a number of different ways, check the following list of potential causes to find out how to resolve the error. These are listed in order of most common to least common causes. 1. CAUSE: Floating point set to . You have your floating point option set to None when it should be set to either Fast or Normal. FIX: Set Floating Point to Fast or Normal. 2. CAUSE: Either the compiler is overoptimizing, or the floating point formats really do need to be linked in because your program manipulates floats in a limited and specific fashion. Under certain obscure conditions, the compiler will ignore floating point usage in scanf(). (e.g., trying to read into a float variable that is part of an array contained in a structure.) FIX: Add the following to one source module: extern _floatconvert; #pragma extref _floatconvert 3. CAUSE: Forgetting to put the address operator & on the scanf variable expression. For example, float foo; scanf("%f", foo); FIX: Change the code so that the & operator is used where it is needed. For example, the above code should be float foo; scanf("%f", &foo); -------------------------- Turbo Debugger for Windows -------------------------- You can use TD32 to debug under Win32s. However, to do so, you must ensure you use SVGA.DLL or equivalent support in the VideoDLL entry in the [TurboDebugger] section of TDW.INI. TD32 can support dual monitor debugging under Win32s. Ensure that a monochrome adapter is installed in your machine and set the Mono=yes flag in the [VideoOptions] section of TDW.INI: [VideoOptions] MONO=yes See the online text file called td_help!.txt for more information on using TD32 and TDW. --------------------- Using Tools with NTFS --------------------- When using Borland C++ 4.0 tools under NTFS, there are issues to be aware of related to extension assumptions. If Borland C++ 4.0 tools see an extension, they assume no default. Therefore, with "bcc32test.1.cpp", BCC32 spawns TLINK32 with "-ap c0x32.obj test.1, test.1, import32 imprtw32 cw32". As TLINK32 sees an extension on test.1, it makes NO assumptions about a .obj or .exe extension. It attempts to look for test.1 (instead of test.1.obj) and to create test. (instead of test.1.exe). Embedded blanks in filenames are not currently supported. It is legal for a file such as this: "This is an interesting file name.cpp". The response file processing for all 32-bit tools cannot handle this type of file. 16-bit tools running on NT cannot use NTFS filenames.