📄 readme.txt
字号:
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.
The assign member funtion
assign( const string&, size_t = NPOS );
was changed to
assign( const string&, size_t = 0, size_t = NPOS );
The size_t parameter in the old version was the number of characters
to copy. In the new version that is the second size_t parameter; the
first one is the position in the passed string to start copying.
For example:
string s1 = "abcdef";
string s2;
s2.assign( s1, 2, 3 );
After executing this code, s2 should contain "cde".
The same change was made in several other functions. The following lists the
new form:
string( const string _FAR &, size_t, size_t );
string( const char _FAR *, size_t, size_t );
string( const char __far *, size_t, size_t );
assign( const string _FAR &, size_t, size_t );
append( const string _FAR &, size_t, size_t );
append( const char _FAR *, size_t, size_t );
prepend( const string _FAR&, size_t, size_t );
prepend( const char _FAR*, size_t, size_t );
compare( const string _FAR&, size_t, size_t );
insert( size_t, const string _FAR&, size_t, size_t );
replace( size_t, size_t, const string _FAR&, size_t, size_t );
--------------
Casting Macros
--------------
The following casting macros have been provided, and are defined in
\BC4\INCLUDE\CLASSLIB\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.
Project style sheets are inherited from the default project when you select
Project|New. You can set inheritance using the following option in the BCW.INI
file:
[projects]
inherit=0
where 0 inherits from the default project, 1 from the previous project,
and 2 from the shipping defaults (which are unchangeable).
The following listing explains some of the more useful BCW.INI settings:
[ToolDir] ; BCW's default paths
BcInclude=\bc4\include ;Default Include path, MPD Directories
BcLib=\bc4\lib ;Default Lib path, MPD Directories
[Project]
saveastext=1 ;PDL file with Style Sheets and Modified tools
readastext=1 ;Read Style Sheets and Tools
[IDE]
HelpDir=C:\BC4\BIN ;where to find the help files
DefaultDesktopDir=C:\BC4\BIN\ ;where to find bcconfig.bcw,
;bcwdef.bcw/dsw,*.tok,*.ckb
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. Instead, set a breakpoint on a line
in the loop and use Ctrl-F9 (Debug|Run) to iterate through the loop. Once
finished with the loop, the breakpoint can be removed.
The following combination of events will cause unusual behavior:
- Placing breakpoints in Windows procedures or OWL event handler which will
receive WM_KILLFOCUS or WM_WINDOWPOSCHANGED messages.
- Shifting focus from this application while debugging, directly to the IDE.
When focus is changed from the application being debugged to the IDE, Windows
initiates an intertask SendMessage from the IDE to the application. But the
breakpoint prevents SendMessage from completing, putting Windows into an
unstable state. Many GUI debuggers silently ignore a breakpoint in this
situation. The Borland Integrated Debugger displays a message box warning of
this situation giving you the choice of ignoring the breakpoint and continuing
the application, or aborting the application so you can make further changes to
the code or placement of breakpoints before running again. The best way to
avoid this situation is to not click on the IDE when you have a breakpoint in
the Window procecure or OWL event handler that could stop due to an intertask
SendMessage from the IDE. Instead click on some other application like the
Program Manager. This will still result in the WM_KILLFOCUS and related
messages and the intertask SendMessage, but the initiating task will not be the
IDE and thus completely avoids the Windows instability.
One further note: the first click of the mouse on the IDE immediately initiates
the MessageBox and the click in the OK box is the next mouse event captured, so
interesting visual effects may occur depending on where that first mouse click
occurred. For example, if the first click was in the title bar of the IDE, the
second click (in the MessageBox OK) will result in a move of the IDE Window
from its original location to the location of the OK mouse click. If this
happens, move the IDE back to where you want it.
----------------------
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 <None>. 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 "bcc32 test.1.cpp",
BCC32 spawns TLINK32 with "-ap c0x32.obj test.1, test.1, import32 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. For instance, under
the Windows NT NTFS file system it is legal to have a file named
"This is an interesting file name.cpp". The response file processing in our
32-bit tools cannot handle this type of file.
16-bit tools running on NT cannot use NTFS filenames.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -