List of Bug Fixes in Update 3 for C++Builder 2009

Written by Embarcadero USA on Posted in PROGRAMMING

This article lists all the fixes included in Update 3 for C++Builder 2009.

If you have the initial release of C++Builder 2009, you can download updates free of charge from the registered users page.

If you're unsure which release you have, select Help | About in the IDE.

  Fix List

 

QC #: Date Reported: Area:
15272 8/19/2005 IDE\Project Management\Project Manager
Description: Steps:
[QC Short Description]
It is possible to add to projects with same name to a project group

[QC Description]
If you have two projects (Delphi win32 or C++) with the same name, i.e. Project1.bdsproj adding them to a project group should give an error.
Instead, you can add them, and save the project group, but when you re-load the project group, only one Project1 is there.

N.B. BCB6 would give the error "Cannot add duplicate project, "Project1.exe" when attempting to add the second project1.
QC Entry 15272

[BCH]
Start DeXter. Click New->C++Builder Projects->VCL Forms Application. Click Save All and save in a new sub-directory named "Project1". File->Close All. Click New->C++Builder Projects->VCL Forms Application Click "Save All" and save in a new sub-directory named "Project2". File->Close All. Click New->Other Files->Project Group. Right click ProjectGroup1->Add Existing Project... Select Project1 in directory Project1. Open. Right click ProjectGroup1->Add Existing Project... Select Project1 in directory Project2. Open. *** Should see an error message here! *** File->Save All. File->Close All. Now Open the project group. Result - only one project is there.
QC #: Date Reported: Area:
20433 10/21/2005 IDE\Performance
Description: Steps:
[QC Short Description]
Updating project options

[QC Description]
I don't know what the operation is that takes so long with projects but it seems to me that it could at least be avoided if the project options dialog was a little more clever.

If I change the run time arguments prior to debugging there is the usual (for me) half a minute delay and then DeXter rebuilds the project from scratch.

That seems a lot hassle for just changing one option that doesn't even affect compilation.
QC Entry 20433
Load a C++ project (preferably a large one). 1.Build and run the project under the IDE. 2.Change 'Parameters' field in \Project Options\Debugger, click [OK] 3.Run the project under the IDE again. Note how (3) initiates a Build :-/
QC #: Date Reported: Area:
67333 9/30/2008 IDE\Project Management\Project Options
Description: Steps:
[QC Short Description]
Improper order of options in IDE-generated bcc command line

[QC Description]
Some BCC command line options (specifically -v and -vi) have precedence rules and can't be rearranged without consequences. IDE generates BCC command lines where -v and -vi are in wrong order.
QC Entry 67333

See also QC 67080 / RAID 265437

It appears that the -v switch sets -vi- and that the -v- switch sets -v. I can find no documention of this tie between the two options in CB 2009.

BCB5/6 docs do say that -v forces -vi- but says nothing about -v- forcing -vi.
Background: -------------------------------------- -vi- No inline calls -vi Inline calls -v Turn on source debugging (implicitly turns inline expansion off: -vi-) -v- Turn off source debugging Precedence rules: The last option typed overrides any earlier one. For both debugging and inline expansion on: -v -vi -------------------------------------- Steps: Create new VCL app and build it in Release mode with debug info (Release options->C++->Debugging->Debug information=true). See generated command line: c:\program files\codegear\rad studio\6.0\bin\bcc32.exe -DNDEBUG;NO_STRICT -D_RTLDLL;USEPACKAGES -I <...> -c -tWM -tW -C8 -oRelease\Project1.obj -w-par -O2 -vi -v -H=Release\Project1.pch -H Project1.cpp Note: -v overrides -vi.
QC #: Date Reported: Area:
67513 10/3/2008 IDE\Packages
Description: Steps:
[QC Short Description]
BPI/LIB output setting is ignored

[QC Description]
CB2009 appears to ignore the "BPI/LIB output" setting for a C++Builder personality package project. No matter what value I place in this field my .bpi and .lib files get written to the default location specified in "Tools | Options | Environment Options | C++ Options | Paths and Directories". By default the value is ${BDSCOMMONDIR}\DCP.
QC Entry 67513
- Start the IDE (I have both personalities loaded) - Create a new C++Builder Package - Edit the project options - Click on the "Directories and Conditionals" page - Change the "BPI/LIB output" path to anything that exists (like ".") - For good measure set "Final output directory" and "Intermediate output" as well - Click OK - Save the project somewhere on your harddrive (I chose C:\test) - Build the project At this point (on my system) the IDE reports a successful build. If I open explorer and navigate to "C:\test" the files that are there are .cbproj, .cpp, .res, .local, .bpl, .map, and .tds. If I then navigate to ${BDSCOMMON} (which is C:\Users\Public\Documents\RAD Studio\6.0) I see that my .lib and .bpi have been added to the DCP sub directory.
QC #: Date Reported: Area:
67615 10/7/2008 IDE\File Handling
Description: Steps:
[QC Short Description]
IDE Vanishes on attempt to add file open in editor to project

QC Entry 67615
File | New | Other | C++ Builder Projects | Console Application
File | New | Other | Other Files | Text
File | Save As | File1.h - match file name to the existing .cpp file
Project | Add to Project - File1.h should be the default
Ok

Exp: File will be added to the project

Act: IDE vanishes
QC #: Date Reported: Area:
67901 10/14/2008 IDE\Packages
Description: Steps:
[QC Short Description]
Package ignores option set's include and library paths

[QC Description]
I have created an option set that all of my C++Builder packages make reference to. I have modified the option set's "Include path" and "Library path" settings. When applying an option set to a new C++Builder package the package ignores these settings by default.

Note, Delphi packages have "Inherits" set to "True" by default for "Conditional defines" and "Search path". This leads me to the conclusion that the behavior should be the same for C++Builder packages.
QC Entry 67901
- Create a new C++Builder package project - Add an existing option set that has an "Include path" or "Library path" override (If you don't have one then make a new one) - Edit the project options of the package and click the plus (+) next to "Library path" or "Include path" - "Inherits" will be set to False
QC #: Date Reported: Area:
67511 10/3/2008 RTL\C++\Codeguard
Description: Steps:
[QC Short Description]
CodeGuard doesn’t like std::_wfopen

[QC Description]
A file opened with std::_wfopen generates an error message for every file function.
QC Entry 67511
std::FILE * file = std::_wfopen( L"Test_FILE.txt", L"a" ); std::fwrite( "abc", 1, 3, file ); // -> CodeGuard message: "Wrong parameter …"
QC #: Date Reported: Area:
68466 10/31/2008 RTL\C++\Header Files
Description: Steps:
[QC Short Description]
ctype.h lacks isblank

[QC Description]
is ctype.h the method isblank() is missing, see the link below for the opengroup standard

http://www.opengroup.org/onlinepubs/000095399/basedefs/ctype.h.html

also iswblank is missing
QC Entry 68466
 
QC #: Date Reported: Area:
68401 10/29/2008 TASM/TD\TASM32
Description: Steps:
[QC Short Description]
tasm32 build does not generate .obj and fails silently

[QC Description]
The project settings can add too many include file search paths (/i) onto the tasm32 command line. When this fails to build the object file, it fails silently. The output from tasm32 is the normal help screen. The linker will eventually fail when it needs something that was in the assembler files.

A simple (non-sense) project has been created and will be attached. Several worthless include file path items have been added to reach the error.

Snippet from output:
Task "BCC32"
Command:
c:\program files\codegear\rad studio\6.0\bin\bcc32.exe -D_DEBUG -D_RTLDLL;_NO_VCL;USEPACKAGES -Iasmtest;"C:\Program Files\CodeGear\RAD Studio\6.0\include\boost_1_35\boost\tr1\tr1";"c:\program files\codegear\rad studio\6.0\include";"c:\program files\codegear\rad studio\6.0\include\dinkumware";"c:\program files\codegear\rad studio\6.0\include\vcl";"C:\Program Files\CodeGear\RAD Studio\6.0\include\boost_1_35";c:;c:\temp;c:\windows;c:\windows\system32;"c:\program files";"c:\program files\codegear";"C:\Program Files\CodeGear\RAD Studio";"C:\Program Files\CodeGear\RAD Studio\6.0";"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage";"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage\css";"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage\Images";"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage\xml";"c:\program files\codegear\rad studio\6.0\ObjRepos\Cpp";"c:\program files\codegear\rad studio\6.0\include\Indy10";"c:\program files\codegear\rad studio\6.0\RaveReports\Lib" -y -k -r- -c -B -tWC -tWM -C8 -oDebug\asmtest.obj -w-par -Od -vi- -v -H=Debug\asmtest.pch -H asmtest.cpp
Command:
c:\program files\codegear\rad studio\6.0\bin\tasm32.exe /iasmtest /i"C:\Program Files\CodeGear\RAD Studio\6.0\include\boost_1_35\boost\tr1\tr1" /i"c:\program files\codegear\rad studio\6.0\include" /i"c:\program files\codegear\rad studio\6.0\include\dinkumware" /i"c:\program files\codegear\rad studio\6.0\include\vcl" /i"C:\Program Files\CodeGear\RAD Studio\6.0\include\boost_1_35" /ic: /ic:\temp /ic:\windows /ic:\windows\system32 /i"c:\program files" /i"c:\program files\codegear" /i"C:\Program Files\CodeGear\RAD Studio" /i"C:\Program Files\CodeGear\RAD Studio\6.0" /i"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage" /i"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage\css" /i"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage\Images" /i"C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage\xml" /i"c:\program files\codegear\rad studio\6.0\ObjRepos\Cpp" /i"c:\program files\codegear\rad studio\6.0\include\Indy10" /i"c:\program files\codegear\rad studio\6.0\RaveReports\Lib" /ml Debug\asmtest.asm , Debug\asmtest.obj
The "TASM32" task is using "tasm32" from "c:\program files\codegear\rad studio\6.0\bin\tasm32.exe".
Turbo Assembler Version 5.3 Copyright (c) 1988, 2007 CodeGear
Syntax: TASM [options] source [,object] [,listing] [,xref]
/a,/s Alphabetic or Source-code segment ordering
/c Generate cross-reference in listing
/dSYM[=VAL] Define symbol SYM = 0, or = value VAL
/e,/r Emulated or Real floating-point instructions
/h,/? Display this help screen
/iPATH Search PATH for include files
/jCMD Jam in an assembler directive CMD (eg. /jIDEAL)
/kh# Hash table capacity # symbols
/l,/la Generate listing: l=normal listing, la=expanded listing
/ml,/mx,/mu Case sensitivity on symbols: ml=all, mx=globals, mu=none
/mv# Set maximum valid length for symbols
/m# Allow # multiple passes to resolve forward references
/n Suppress symbol tables in listing
/os,/o,/op,/oi Object code: standard, standard w/overlays, Phar Lap, IBM
/p Check for code segment overrides in protected mode
/q Suppress OBJ records not needed for linking
/t Suppress messages if successful assembly
/uxxxx Set version emulation, version xxxx
TASM32 : /w0,/w1,/w2 Set warning level: w0=none, w1=w2=warnings on
/w-xxx,/w+xxx Disable (-) or enable (+) warning xxx
/x Include false conditionals in listing
/z Display source line with error message
/zi,/zd,/zn Debug info: zi=full, zd=line numbers only, zn=none
Done executing task "BCC32".
QC Entry 68401
1 - Download and open attached project.
2 - F9
exp: compile and run
act: [ILINK32 Error] Fatal: Unable to open file 'ASMTEST.OBJ'
3 - Go to: Project | Option | Directories and Conditionals | Include Path
4 - Delete all include paths from "C:\Program Files\CodeGear\RAD Studio\6.0\Welcomepage\css;" to the last one.
5 - F9
act and exp: compile and run

---- Original Steps from QC: ----
1) Create project with C++ source file with inline assembly language code.

2) Have numerous items in the project include file path option.

3) Compile to failure. In the detailed build output, the tasm32 help screen can be seen where it should instead be assembling.
QC #: Date Reported: Area:
70003 12/18/2008 Linker
Description: Steps:
[QC Short Description]
ilink32 crashes while generating map file

[QC Description]
A large project crashes with an access violation from the linker (ilink32.exe) when using the -s option to generate a detailed segment map.

Map file was to be used for generating some usable debug symbols for using with Debugging Tools for Windows, see Report# 66994.
QC Entry 70003
Private linkset available for CodeGear

To recreate, browse to linkpackage\data and run
from the commandline: ilink32 @ilink.txt


QC #: Date Reported: Area:
70703 1/21/2009 RTL\C++
Description: Steps:
[QC Short Description]
Including the <utility> header causes errors in Boost source code.

[QC Description]
Something seems to be wrong in the default configuration of Boost.

The project options of the newly created project specify the following include paths:
$(CG_BOOST_ROOT)\boost\tr1\tr1
$(BDS)\include
$(BDS)\include\dinkumware
$(BDS)\include\vcl
$(CG_BOOST_ROOT)
QC Entry 70703


---
Preprocessing problem. The order of include files given above results in cpp32 choking. Placing the first at the bottom results in everything working fine. The issue is evidently that dinkumware must be included before we include any of the boost libraries.
- Create a new console application (no VCL required)
- Add an "#include <utility>" statement at the top
- Compile.

Exp.: compiles
Act.: 16 errors, the first two being:
[BCC32 Fehler] tuple.hpp(53): E2209 include-Datei 'boost/fusion/include/tuple.hpp' cannot be opened
[BCC32 Fehler] tuple.hpp(54): E2209 include-Datei 'boost/fusion/include/std_pair.hpp' cannot be opened

This is a regression from the released version (with patch 2 applied)

Part 2:
Go to Project Options. Move $(CGBOOST)/tr1 to the bottom.
Recompile
exp: Same errors
act: Builds.


Command line:

Doesn't Work
cpp32 -I"C:\Program Files\CodeGear\RAD Studio\6.0\include\boost_1_35\boost\tr1\tr1";"c:\program files\codegear\rad studio\6.0\include\dinkumware"

Works
cpp32 -I"c:\program files\codegear\rad studio\6.0\include\dinkumware";"C:\Program Files\CodeGear\RAD Studio\6.0\include\boost_1_35\boost\tr1\tr1"
QC #: Date Reported: Area:
68740 11/9/2008 VCL\Dialog Controls\TOpenDialog
Description: Steps:
[QC Short Description]
Lost focus after TOpenDialog when MainFormOnTaskBar is set

[QC Description]
I have a really annoying problem in an application with a TMemo and a TOpenDialog.
After you've opened the TOpenDialog dialog you've lost focus on the TMemo and can only get it back by alt+tabbing from the application and back.

This problem dos not occur if MainFormOnTaskBar is set to false.
QC Entry 68740
1. File | New | VCL Forms Application
2. Drop a TopenDialog
3. Drop a TEdit
4. Drop a TSpeedButton
5. In the SpeedButton's OnClick enter:
UseLatestCommonDialogs := False;
Opendialog1.Execute;
6. Run
7. Click in the Edit control, click on the SpeedButton, select any file, click OK
// Exp: focus returns to the edit control
// Act: focus does not return to the edit control


----- Orig ------
1. Create a new solution in C++Builder 2009
2. Add a TMemo and a TOpenDialog
3. Somwhere in the code call Execute on the TOpenDialog
4. Close the OpenDialog

Now you've lost focus on the TMemo and can only get it back by mouse clicking it or alt+tabbing from the application and back.

edit:
The problem only appears on Windows XP.
QC #: Date Reported: Area:
68549 11/3/2008 Compiler\C++
Description: Steps:
[QC Short Description]
W8114: __DATE__ macro returns invalid string under Japanese locale

[QC Description]
With Japanese edition, __DATE__ macro returns invalid string and compiler generates W8114.
For example,
const char* date = __DATE__;
result in this warning and we can not get valid string.
[BCC32 ??] Unit1.cpp(19): W8114 ????? '\u6220' ?????????????????? (932) ????????

This issue is due to "C:\CodeGear\RAD Studio\6.0\bin\comp32x.jp".

Please take a look at attached screenshot.
QC Entry 68549
1) start C++Builder 2009 Japanese edition 2) create a new project 3) compile the code as below const char* date = __DATE__; 4) compler generates this warning [BCC32 ??] Unit1.cpp(19): W8114 ????? '\u6220' ?????????????????? (932) ????????
QC #: Date Reported: Area:
70285 1/5/2009 Compiler\C++\Front End\Preprocessor
Description: Steps:
[QC Short Description]
Preprocessor errors with wide character literals

[QC Description]
As best I can tell, the preprocessor fails to recursively expand macros that occur after a wide character literal within the same macro parameter.


Added by Sysop
<<<<<<<<<<<<<
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
// [BCC32 Error] File1.cpp: E2451 Undefined symbol 'NULL'
assert(L"" != NULL);
assert(wcscmp(L"", NULL) != 0);
return 0;
}
>>>>>>>>>>>>>
QC Entry 70285
bcc32 Test267545.cpp

Exp: no warning/error.
Act: Error E2451 Test267545.cpp 6: Undefined symbol 'N' in function main()


QC #: Date Reported: Area:
31756 7/26/2006 IDE\Docking
Description: Steps:
[QC Short Description]
Changing IDE Configuration hides Table labels

[QC Description]
With the designer embedded, if the IDE configuration is changed while a DataModule is opened, all labels to the DataModule's components disappear when the view is redrawn. Closing and reopening the form view does not solve the problem. The only solution is to exit the IDE and restart.
QC Entry 31756
With the designer embedded, create a DataModule with some TTable components on it (with names of course) Using the Desktop speedsetting drop down, change the IDE configuration (in my case from "Classic Undocked" to "Default Layout"). When the view is redrawn, the labels to the TTables will be gone.
QC #: Date Reported: Area:
69993 12/18/2008 IDE
Description: Steps:
[QC Short Description]
Installing D2009 Update#1 and/or Update#2 deletes all "Tools" from IDE menu

[QC Description]
After installing D2009 Update#1 , any previously configured IDE tools are lost, and must be reconfigured manually from scratch.

I've rated this as "data loss", because the tool configuration is totally lost, and needs recreating manually - which is a /major/ pain if you had more than one or two.

QC Entry 69993
Install D2009 w/o updates Start IDE Menu : Tools/Configure Tools... Add a dummy tool command. Verify new tool shown in menu. Close IDE Install Update #1 or #2 Start IDE Expected: Tools menu still contains previously configured "tool" Actual: Tools menu is empty
QC #: Date Reported: Area:
64211 7/7/2008 Tools CL
Description: Steps:
[QC Short Description]
rsvars.bat incorrect on 64-bit machines

[QC Description]
MSBuild sometimes fails when making a project with an error like the following:

The "BccDependencyCheck" task failed unexpectedly.
System.BadImageFormatException:
An attempt was made to load a program with an incorrect format. (Excepti
on from HRESULT:
0x8007000B)
at Borland.Build.Tasks.Cpp.BCCDependencyCheck.CppShouldCompile(String cppName
, String objName)
at Borland.Build.Tasks.Cpp.BCCDependencyCheck.CheckDependencies()
at Borland.Build.Tasks.Shared.DependencyCheck.Execute()
at Microsoft.Build.BuildEngine.TaskEngine.ExecuteTask(ExecutionMode howToExec
uteTask, Hashtable projectItemsAvailableToTask, BuildPropertyGroup projectProper
tiesAvailableToTask, Boolean& taskClassWasFound)

I've only seen this with C++ projects, but I very rarely use Delphi. It alsmost always happens if on the command line you make a project, stop it halfway through the make, and make again.

The fix appears to be to change the .Net framework directory to the 32-bit version, ie in rsvars.bat, change:
@SET FrameworkDir=C:\Windows\Microsoft.NET\Framework64\
to
@SET FrameworkDir=C:\Windows\Microsoft.NET\Framework\

Using RAD Studio 2007 with all updates as of 8th July 08. Occurs on two Vista64 machines, (one SP1, one not.) We haven't tested on XP64.

QC Entry 64211
Build or make a C++ project on the command line, and cancel it halfway through. Then make the project. Only occurs on Vista64. Note that the .targets files are (incorrectly?) installed in the 32-bit .Net folder on Vista 64, so to compile on the command line using rsvar.bat's default framework path, the 64-bit one, you will need to copy them to the Framework64 folder.
QC #: Date Reported: Area:
54900 11/15/2007 Compiler\Delphi\Header Generation
Description: Steps:
[QC Short Description]
PACCESS_MASK is not declared as EXTERNALSYM

[QC Description]
In Windows.pas, PACCESS_MASK is not declared as EXTERNALSYM. ACCESS_MASK is, however. In C++, this causes Windows::PACCESS_MASK from Windows.hpp to conflict with ::PACCESS_MASK from winnt.h, resulting in the following ambiquity error:

E2015 Ambiguity between 'PACCESS_MASK' and 'Windows::PACCESS_MASK'

This error exists in previous versions of Delphi/BCB and thus has been around for many years.
QC Entry 54900
In a C++ VCL project (Console or GUI, doesn't matter): 1) #include the aclapi.h header file (or any other header file that uses PACCESS_MASK) in any unit, ie: #include <vcl.h> #include <windows.h> #pragma hdrstop #include <aclapi.h> #pragma argsused WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { return 0; } 2) Alternatively, simply declare a PACCESS_MASK variable anywhere without using an additional #include statement, ie: #include <vcl.h> #include <windows.h> #pragma hdrstop #pragma argsused WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { PACCESS_MASK pMask = NULL; return 0; }
QC #: Date Reported: Area:
62503 5/23/2008 Debugger\Evaluator\C++
Description: Steps:
[QC Short Description]
Evaluator fails to display/evaluate const vector items

[QC Description]
After breaking after a const std::vector initialization, attempting to use the debugger to evaluate the vectors contents fails with:

"E2522 Non-const function std::vector<double, std::allocator<double> >::std::vector<double, std::allocator<double> >::operator [](unsigned int) called for const object"

May apply to other const object assignments as well.
QC Entry 62503
See attached test project 261698.zip

Example:

const std::vector<double> TestVector(3,3);
int x =0;

When I "break" at the x assignment and try to evaluate TestVector[0], I get the E2522 error message.

Similarly, evaluating TestVector.size() fails, even when the object is non-const.
"E2451 Undefined symbol 'std::vector<int, std::allocator<int> >::size()'"




QC #: Date Reported: Area:
67498 10/3/2008 VCL\Emulation Classes
Description: Steps:
[QC Short Description]
using function FmtLoadStr of AnsiString class cause compiler error

QC Entry 67498
bcc32.exe -WCV raid265670.cpp

res:

CodeGear C++ 6.10 for Win32 Copyright (c) 1993-2008 CodeGear
raid265670.cpp:
Error E2193 C:\Program Files\CodeGear\RAD Studio\6.0\Include\vcl\dstring.h 265:
Too few parameters in call to '_fastcall AnsiStringBase::FmtLoadStr(int,const TV
arRec *,int,int)' in function _fastcall AnsiString::FmtLoadStr(int,const TVarRec
*,int)
*** 1 errors in Compile ***

exp: clean compile
QC #: Date Reported: Area:
67508 10/3/2008 RTL\C++\Strings
Description: Steps:
[QC Short Description]
The UnicodeString( char *, int ) constructor is broken

[QC Description]
The result of UnicodeString(char *, int) constructor is always an empty string.
QC Entry 67508
UnicodeString str( "abc", 3); assert( str == L"abc" ); // str == L""
QC #: Date Reported: Area:
67783 10/10/2008 Compiler\Delphi\Header Generation
Description: Steps:
[QC Short Description]
C++ typedefs generated from Delphi class aliases are not correct

[QC Description]
When Delphi code contains an alias the generated HPP file references are incorrectly labeled as pointers to the base type. Example:

// Delphi code
type
TMyClass = class
end;

TMyClassAlias = TMyClass;

// Generate HPP
class TTest : public System::TObject ...

typedef TTest* TMyTest;

Note the erroneous pointer "*" in the typedef. The typedef should be as follows:

typedef TTest TMyTest;

In some cases the aliases are required for previous compiler versions since RAD2009 changed the names of some classes and aliased the old names for "backward compatibility". TZCompressionStream, TZDecompressionStream, and TPNGObject are three examples that have affected me.

Previous compiler versions (RAD2007, BCB6) generate the code correctly.
QC Entry 67783
To generate the problem for yourself follow these steps. - Create a new Delphi or C++Builder personality package - Edit the project options - Click on "Delphi Compiler | Linking" - Set "Linker output" to "Generate all C++Builder files" - Click "OK" - Add a new Delphi unit to the project - Add the following to the interface section type TMyClass = class end; TMyClassAlias = TMyClass; - Save the project and build - Open the generated HPP file and locate the typedef for TMyClassAlias - Notice the erroneous pointer in the typedef There are examples spread throughout the VCL code. Look in the following VCL files for examples: ( pngimage.hpp : line 650 ) typedef TPngImage* TPNGObject; ( ZLib.hpp : line 111 ) typedef TZCompressionStream* TCompressionStream; ( ZLib.hpp : line 134 ) typedef TZDecompressionStream* TDecompressionStream;
QC #: Date Reported: Area:
67890 10/14/2008 VCL
Description: Steps:
[QC Short Description]
Graphics::GetDIB causes linker error

[QC Description]
It is impossible to use the Graphics::GetDIB function because it leads to a linker error
QC Entry 67890
1. Create a VCL Forms Application 2. Add this line of code to the constructor Graphics::GetDIB(NULL, NULL, NULL, NULL); 3. Build 4. The linker reports: [ILINK32 Error] Error: Unresolved external '__fastcall Graphics::GetDIB(void *, void *, void *, void *)' referenced from C:\DOCUMENTS AND SETTINGS\OLOV\MY DOCUMENTS\RAD STUDIO\PROJECTS\DEBUG\UNIT1.OBJ
QC #: Date Reported: Area:
68076 10/19/2008 RTL\C++\Strings
Description: Steps:
[QC Short Description]
Implementation missing for UnicodeString::LastChar

[QC Description]
The method declaration UnicodeString::LastChar() in ustring.h is missing its matching definition in ustring.cpp. Compiling a program that makes use of this method will result in the following linker error:

[ILINK32 Error] Error: Unresolved external '__fastcall
System::UnicodeString::LastChar() const' referenced from ...
QC Entry 68076


266720
- Create a new C++Builder VCL Forms Application - Add the following lines of code to the main form's constructor String test; test.LastChar();
QC #: Date Reported: Area:
68290 10/26/2008 VCL\Core VCL Classes
Description: Steps:
[QC Short Description]
AnsiPos method of AnsiString class returns Unicode based index

[QC Description]
AnsiPos method of AnsiString class returns Unicode based index.
AnsiPos method of AnsiString class should call Ansistrings::AnsiPos function instead of Sysutils::AnsiPos function.

Please see dstring.hpp and implementation of AnsiString#AnsiPos.


Note:
Pos method of AnsiString class returns Ansi based index.
QC Entry 68290

//266150
Execute the code as below.

-----------------------
#include <AnsiStrings.hpp>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString ansistr = "a?b"; // ? is a Japanese Kanji Character(2 bytes)

// return 3 (NG)!! It is Unicode based index.
ShowMessage(IntToStr(ansistr.AnsiPos("b")));

// return 4 (OK). This is correct index which is based Ansi.
ShowMessage(IntToStr(Ansistrings::AnsiPos("b", ansistr)));
}
-----------------------
QC #: Date Reported: Area:
68291 10/26/2008 VCL\Core VCL Classes
Description: Steps:
[QC Short Description]
LastDelimiter method of AnsiString class returns Unicode based index

[QC Description]
LastDelimiter method of AnsiString class returns Unicode based index.

LastDelimiter method of AnsiString class should call Ansistrings::LastDelimiter function instead of Sysutils::LastDelimiter function.

Please see dstring.hpp and implementation of AnsiString#LastDelimiter.
QC Entry 68291

//266149
Execute the code as below
----------------
#include <AnsiStrings.hpp>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString ansistr = "a?b"; // ? is a Japanese Kanji Character(2 bytes)

// return 3 (NG)!! It is Unicode based index.
ShowMessage(IntToStr(ansistr.LastDelimiter("b")));

// return 4 (OK). This is correct index which is Ansi based.
ShowMessage(IntToStr(Ansistrings::LastDelimiter("b", ansistr)));
}
----------------
QC #: Date Reported: Area:
68215 10/23/2008 IDE\Unit Testing\Test Case Wizard
Description: Steps:
[QC Short Description]
C++ Unit Test TTestCase constructors are incorrect

[QC Description]
The Test Case wizard generates incorrect constructors using AnsiString instead of UnicodeString.

As a result, the constructors are never invoked and instance variables are in turn never constructed.



QC Entry 68215
1: Create a C++ Unit Test Project 2: File/New/Other Unit Test: Test Case 3: Select a C++ source file with a class, and click through the wizard to generate the test harness. 4: Examine the constructors for your test case classes, compiaring it with testframework.hpp: Created code: class TTestras_sync_obj_ : public TTestCase { public: __fastcall virtual TTestras_sync_obj_(AnsiString name) : TTestCase(name) {} // Should be UnicodeString! virtual void __fastcall SetUp(); virtual void __fastcall TearDown(); testframework.hpp: __fastcall virtual TTestCase(System::UnicodeString MethodName); 5: Add some code to the constructor in the Wizard-generated file, and set a breakpoint 6: Build and run the test project EXPECTED: Breakpoint is reached, code is executed ACTUAL: Breakpoint never reached, code doesn't run. NOTE: Also, constructors for any instance variables in your test case are never run.
QC #: Date Reported: Area:
67728 10/9/2008 Compatibility\BCB<->Delphi
Description: Steps:
[QC Short Description]
DynamicArray template class does not use VCL memory management

[QC Description]
The DynamicArray template class in sysdyn.h uses the C RTL malloc() and free() functions instead of the VCL RTL GetMem() and FreeMem() functions to manage the memory block for the array data. As long as dynamic arrays are used in C++ code only, or Delphi code only, this is not a problem. However, if dynamic arrays are passed between C++ and Delphi, this can lead to runtime crashes and CodeGuard errors because different memory managers are being used to allocate and free the array memory.
QC Entry 67728
1 - Open the attached project
2 - Enable codeguard if it is not enabled (Project->Option | Debbuging). Set enable codeguard to true (all 3 options).
3 - F9 (compile and run)
4 - Click the form button

res:
Resource from different RTL in process: TestProject.exe(6984) - c:\program files\codegear\rad studio\6.0\include\vcl\sysdyn.h#383
...
The memory block (0x00F7BEC0) [size: 4008 bytes] was allocated with SysGetMem
...
exp: no message like the one above. When clicking the button, the message: "Array allocated and freed!"
QC #: Date Reported: Area:
68472 10/31/2008 Compatibility\BCB<->Delphi
Description: Steps:
[QC Short Description]
Assigning TPen's Handle property crashes in C++ but not in Delphi

[QC Description]
Assigning any value to TPen's Handle property crashes with an AV. This is because there is an unconditional JMP statement that jumps execution to the TMetafileCanvas::CreateWithComment() constructor. This only happens in C++, not in Delphi.
QC Entry 68472
Create a new C++ VCL Forms Application and add this code to its constructor: __fastcall TForm1::TForm1(TComponent *Owner) : TForm(Owner) { Canvas->Pen->Handle = ::CreatePen(PS_SOLID, 1, 0); } The CPU disassembler shows the following instructions being executed: Unit1.cpp.15: Canvas->Pen->Handle = ::CreatePen(PS_SOLID, 1, 0); 00401C00 6A00 push $00 00401C02 6A01 push $01 00401C04 6A00 push $00 00401C06 E8DD1A0000 call $004036e8 <-- ::CreatePen() 00401C0B 50 push eax 00401C0C 8B45FC mov eax,[ebp-$04] 00401C0F E8F0190000 call $00403604 <- [email protected]@[email protected]$qqrv 00401C14 8B4010 mov eax,[eax+$10] 00401C17 5A pop edx 00401C18 E89F120000 call $00402ebc <- Graphics::TPen::SetHandle(Graphics::TPen * const ,void *) [email protected]@[email protected]$qqrv: 501F1B64 8B8090020000 mov eax,[eax+$00000290] 501F1B6A C3 ret Graphics::TPen::SetHandle(Graphics::TPen * const ,void *): 00402EBC E91F050000 jmp $004033e0 <- why is this here ??? 004033E0 FF25B4784000 jmp dword ptr [$004078b4] <- [email protected]@[email protected][email protected][email protected] As you can see, the code is jumping into some kind of lookup table that is reaching TMetafileCanvas. Compare that with the Delphi disassembly for equivilent code, and you will see a different result: Unit1.pas.27: Canvas.Pen.Handle := Windows.CreatePen(PS_SOLID, 1, 0); 00461C2F 6A00 push $00 00461C31 6A01 push $01 00461C33 6A00 push $00 00461C35 E8625EFAFF call CreatePen 00461C3A 50 push eax 00461C3B 8BC3 mov eax,ebx 00461C3D E8DA64FFFF call TCustomForm.GetCanvas 00461C42 8B4010 mov eax,[eax+$10] 00461C45 5A pop edx 00461C46 E8E946FCFF call TPen.SetHandle TCustomForm.GetCanvas: 0045811C 8B8090020000 mov eax,[eax+$00000290] 00458122 C3 ret TPen.SetHandle: 00426334 53 push ebx 00426335 56 push esi 00426336 83C4F0 add esp,-$10 ... the rest of the normal TPen.SetHandle() code here ...
QC #: Date Reported: Area:
68547 11/3/2008 RTL\C++\Strings
Description: Steps:
[QC Short Description]
Length calculation of the UTF32ToUTF16 function is incorrect

[QC Description]
static int UTF32ToUTF16(const char32_t* src, wchar_t* dst, int len)
{
int count = 0;
while ((len != 0) && *src) {
char32_t ch = *src++;
if (ch < 0x0000FFFF) {
count++;
if (dst)
*dst++ = (ch & 0x0000FFFF);
}
else if (ch < 0x0010FFFF) {
count++; // Here, it should be "count+=2;"
if (dst) {
ch -= 0x10000;
*dst++ = (ch >> 10) | 0xD800;
*dst++ = (ch & 0x3FF)| 0xDC00;
}
} else {
count++;
if (dst)
*dst++ = 0x0000FFFD;
}
if (len > 0)
len--;
}
return count;
}


//////////////////////////////////

The lines
else if (ch < 0x0010FFFF) {
count++;

should be changed to
else if (ch < 0x0010FFFF) {
count+=2;

QC Entry 68547
1. Run following code struct TUnicodeStringRec{ short codePage; short elemSize; int refCount; int length; }; TUnicodeStringRec *rec; char32_t a[]={0x01040F, 0x01042D, 0x01044C, 0x01042E, 0x01043F, 0x01042C, 0x01043C}; // "Unicode" in Deseret (refer to http://www.unicode.org/standard/WhatIsUnicode.html) UnicodeString s(a,7); // all characters are should be encoded with two wchar_t characters, so the length should be 14. rec = (TUnicodeStringRec *)(s.w_str()) - 1; // set break point here. You can see that the length is 7, not 14. ShowMessage(s.Length()); // an access violation error occurs
QC #: Date Reported: Area:
69704 12/8/2008 VCL\Emulation Classes
Description: Steps:
[QC Short Description]
TPicture::RegisterClipboardFormat Error

[QC Description]
Using TPicture::RegisterClipboardFormat to register a new format worked perfectly in C++ Builder 6.0,but it doesn't work in 2009.

The information is:

[ILINK32 Error] Error: Unresolved external '__fastcall Graphics::TPicture::RegisterClipboardFormatA(unsigned short, System::TMetaClass *)' referenced from C:\NewIMAGE.OBJ
QC Entry 69704
Attempt to use the following line in a VCL app.

TPicture::RegisterClipboardFormatA(2,GetClass("TPicture"));
QC #: Date Reported: Area:
70686 1/20/2009 Compiler\C++
Description: Steps:
[QC Short Description]
F1001 Internal code generator error

QC Entry 70686

dup of 265372 BUG2

To workaround we can add a destructor to AnsiStringT<CP>.
bcc32 -w- 267722.cpp

res:

CodeGear C++ 6.10 for Win32 Copyright (c) 1993-2008 CodeGear
267722.i:
Internal backend error TR2928 compiling ???(0)
*** 1 errors in Compile ***

--- old steps ---
bcc32 -w- -P 267722.i
QC #: Date Reported: Area:
66394 9/4/2008 IDE\Code Completion
Description: Steps:
[QC Short Description]
IDE Lockup after Code Completion use

[QC Description]
There is still an IDE instability from interaction with Code Completion.

The steps may be a little odd - I only do thinngs like this when testing QC reports - but I think this points out a basic instability in the IDE that needs to be resolved. The good thing here is that it's easily reproducible.

See AIR at QC 66393
QC Entry 66394
Set to Undocked Classic desktop layout with floating designer File | New | VCL Forms app - C++ File | Save All Place text insertion cursor after TForm1:: in the constructor Ctrl+Space to invoke Code Completion File | Close All - file must be unchanged since last save File | Reopen - choose same project Insertion point after opening { of constructor Enter Exp: New line will be inserted for code entry in the constructor Act: Access violation at address 207BE2BE in module 'coreide120.bpl'. Read of address 00000380 - need to close IDE with Task Manager
QC #: Date Reported: Area:
66957 9/18/2008 IDE\Code Completion
Description: Steps:
[QC Short Description]
use code templates will lead to access error or range check error

[QC Description]
Access violation at address 2079BE9A in module 'coreide120.bpl'. Read of address 00000000.
QC Entry 66957
new a console application (multi threaded), code like: int _tmain(int argc, _TCHAR* argv[]) { return 0; } in main, input "if",then press ctrl + space to call the code completion, press enter to input the code: int _tmain(int argc, _TCHAR* argv[]) { if (true) { } return 0; } now, the if condition 'true' has a blue rectangle, move the cursor after the if block ends flag "}", then press Backspace times, when the cursor back to the same row as "if (true) {", the error will recur.
QC #: Date Reported: Area:
68162 10/22/2008 IDE\Code Editor
Description: Steps:
[QC Short Description]
Editor produces stack overflow when pasting certain code snippet

[QC Description]
See steps.

This is a regression from C++Builder 2006.
QC Entry 68162
- Start the IDE, create a new C++ header file (no project required) - Paste this code: // ----- #define ___DECLARE_TYPE_ID(type,val) \ template <typename CharT> \ struct TypeID <CharT, type> \ { \ enum { value = val }; \ }; ___DECLARE_TYPE_ID (void, 0) #pragma defineonoption CBDE_FORMAT_CHAR_IS_UNSIGNED -K #ifdef CBDE_FORMAT_CHAR_IS_UNSIGNED ___DECLARE_TYPE_ID (char, 0) #undef CBDE_FORMAT_CHAR_IS_UNSIGNED #else ___DECLARE_TYPE_ID (char, 0) #endif ___DECLARE_TYPE_ID (signed char, 0) ___DECLARE_TYPE_ID (unsigned char, 0) ___DECLARE_TYPE_ID (wchar_t, 0) ___DECLARE_TYPE_ID (char16_t, 0) ___DECLARE_TYPE_ID (char32_t, 0) ___DECLARE_TYPE_ID (bool, 0) ___DECLARE_TYPE_ID (signed short, 0) ___DECLARE_TYPE_ID (signed int, 0) ___DECLARE_TYPE_ID (signed long, 0) ___DECLARE_TYPE_ID (signed long long, 0) ___DECLARE_TYPE_ID (unsigned short, 0) ___DECLARE_TYPE_ID (unsigned int, 0) ___DECLARE_TYPE_ID (unsigned long, 0) ___DECLARE_TYPE_ID (unsigned long long, 0) ___DECLARE_TYPE_ID (float, 0) ___DECLARE_TYPE_ID (double, 0) ___DECLARE_TYPE_ID (long double, 0) #undef ___DECLARE_TYPE_ID template <typename CharT, typename T> struct TypeID <CharT, T*> { enum { value = 0 + 0 }; }; // ----- Exp.: normal behaviour Act.: "Stack overflow" message appears and the IDE vanishes after a second
QC #: Date Reported: Area:
67095 9/23/2008 Compiler\C++
Description: Steps:
Forward class declaration inside template class
causes Internal Compiler Error in C++Builder 2009.

[QC Description]
While converting an existing C++Builder 5 project to C++Builder 9, I run into an internal compiler error in a third-party tree-class:

[BCC32 Fataler Fehler] tree.hpp(1414): F1004 Interner Compiler-Fehler at 0x44b23db with base 0x4420000

The code compiles fine with C++Builder 5.0.

To reproduce the problem, I created a preprocessor output, renamed it as a cpp-file and attached it to this report.
QC Entry 67095
bcc32 -w- -c 265459.cpp

res:

CodeGear C++ 6.10 for Win32 Copyright (c) 1993-2008 CodeGear
265459.cpp:
Fatal F1004 265459.cpp 67: Internal compiler error at 0x4947d3 with base 0x400000
Fatal F1004 265459.cpp 67: Internal compiler error

bcc 5.9.3 outputs:

CodeGear C++ 5.93 for Win32 Copyright (c) 1993, 2007 CodeGear
265459.cpp:
Error E2291 265459.cpp 67: } expected
*** 1 errors in Compile ***
QC #: Date Reported: Area:
68148 10/21/2008 Compiler\C++\Front End
Description: Steps:
compiler generates wrong code when ternary op used with func ptrs.

[QC Description]
The following program, if compiled and run, prints "bug!". It should not. BTW, I compile all my tests with the command line compiler but guess the result will be the same in the development environment as well. I remember that a similar bug was present in a very old Borland or TurboC. Welcome back ;)

#include <stdio.h>

static void wrong(int) { printf("bug!\n");}
inline void f1(void) { printf("good one\n"); }
inline void f2(void) { printf("good two\n"); }

int main(int argc)
{
(argc ? f1 : f2)();
}
QC Entry 68148
1 - download attached file
2 - bcc32 bug.cpp
3 - bug.exe

act: prints "bug!"

exp: prints "good one" or "good two"
QC #: Date Reported: Area:
68957 11/14/2008 Compiler\C++\Front End\Pre-Compiled Headers
Description: Steps:
[QC Short Description]
Pre-compiled headers do not work with some boost libraries

[QC Description]
It seems that complex template code (like some boost libraries) could not be pre-compiled

QC Entry 68957
bcc32 -w- -c -H=x.pch 266680.cpp
bcc32 -w- -c -H=x.pch 266680.cpp
exp: clean compile
act: ICE

--- old steps ---
Create Console application using default settings (PCH on)

#include <tchar.h>
#include <boost/regex.hpp>
int _tmain(int argc, _TCHAR* argv[])
{
std::string a("a");
std::string b("b" );
static boost::regex f("^a$");
bool r =boost::regex_match( a, f ); // replace a with b
return 0;
}

Compile
Make any change to the code (for example, replace a with b)
Compile again
[BCC32 Fatal Error] basic_regex.hpp(501): F1004 Internal compiler error at 0x4a742ba with base 0x49f0000


QC #: Date Reported: Area:
71114 2/3/2009 Compiler\C++\Interaction with the IDE
Description: Steps:
[QC Short Description]
IDE vanishes during compilation

[QC Description]
seems that the function template parameter with default value and using incorrect constructor parameters causes the problem.

Fraser Ross said that BDS2006 does not have this problem.

Moritz Beutel (who actually reduces my original code to one that included in "Steps") informed me that the same problem occurs in C++Builder 2009.

QC Entry 71114



Note from Tomohiro Takahashi
<<<<<<<<<<
C++Builder 2009 has same problem, too....
>>>>>>>>>>
1. create simple console application 2. replace File1.cpp content with template <typename> struct vector {}; void f (void); template <typename ValueT, void (*func) (void) = &f> struct C { C (vector<ValueT>); }; C <short> c; 3. start compilation
QC #: Date Reported: Area:
70671 1/20/2009 VCL\Graphics
Description: Steps:
[QC Short Description]
Unresolved externals when linking pngimage.obj

[QC Description]
Linking to pngimage.obj when German locale is installed causes lots of unresolved externals.

No namespaces are exported by pnglang.obj, although pngimage.obj expects them. Excerpts from TDUMP logs.

pngimage.obj:
006CD6 EXTDEF 286: '@[email protected]_EPNGInvalidIHDRText' Type: 0
006CF9 COMENT Purge: No , List: Yes, Class: 251 (0FBh), SubClass: 0 (00h)
EXTDEF Descriptions:
286: '@[email protected]_EPNGInvalidIHDRText' 00000001

pnglang.obj:
000193 COMDEF
Name: 3: '__EPNGInvalidIHDRText' virtual(_TEXT) Length: 0008 bytes
0001B0 COMDEF
Name: 4: '@[email protected]_16388' virtual(_TEXT) Length: 008c bytes
0001C9 COMENT Purge: No , List: Yes, Class: 251 (0FBh), SubClass: 13 (0Dh)
0000: 0D C0 04 00 ....

Apparently, the reason is that pnglang.pas was compiled with -JPH although -JPHN should have been used.

Occurs in German locale.
QC Entry 70671
- compile and link this code (bcc32 -WVC qcxxxxx.cpp): // ----- #include <vcl.h> #include <PngImage.hpp> #pragma hdrstop int main (void) { } // ----- Exp.: clean build Act.: lots of errors regarding unresolved externals which should have been exported by pnglang.obj
QC #: Date Reported: Area:
67190 9/26/2008 International\Translation
Description: Steps:
[QC Short Description]
"Benutzer Deklarationen" misses a hyphen

[QC Description]
See steps.
QC Entry 67190
Create a new VCL Forms project and open the main unit's header file in the editor. You will see this: ... class TForm1 : public TForm { __published: // IDE-verwaltete Komponenten private: // Benutzer Deklarationen public: // Benutzer Deklarationen __fastcall TForm1(TComponent* Owner); }; ... Both appearances of "Benutzer Deklarationen" should rather be "Benutzer-Deklarationen", as it was back in C++Builder 2006.
QC #: Date Reported: Area:
68298 10/27/2008 International\Translation
Description: Steps:
[QC Short Description]
Description comment for the ValidCtrCheck function has improper translation

[QC Description]
See Steps.
QC Entry 68298
Create a new VCL component. The component unit will contain this comment: // ValidCtrCheck wird benutzt um sicher zu stellen, dass die kreierten // Komponenten keine pur virtuelle Funktionen enthalten. // static inline void ValidCtrCheck(TConsole *) { new TWhateverNULL); } The comment translation is suboptimal. First, "kreieren" as a translation of "create" implies an artistic aspect. "erstellen" would fit better. Further, "pure virtual functions" are usually translated as "rein virtuelle Funktionen" in technical literature. And finally, "virtuelle" should have a trailing 'n' to match the case of "Funktionen". A possible translation would be: // ValidCtrCheck wird benutzt, um sicherzustellen, dass die erstellten // Komponenten keine rein virtuellen Funktionen enthalten.
QC #: Date Reported: Area:
14064 6/30/2005 Compiler\C++\Back End
Description: Steps:
[QC Short Description]
shift operation >>= for unsigned __int64 igenerates broken code under -Od

[QC Description]
I found crash bug related to __int64 in following situation.

1. unsigned __int64 value is in struct

2. "unary" shift operation is done for the value through
the "pointer" to struct,

3. when this operation is not well optimized? On my sample code,
I need -Od option to reproduce the problem. But on some
complicated code, even if -Od is not specified it crashes.

QC Entry 14064

[Comment by TArisawa]
#13747 is same report. This report was already closed, but the sample code of #13747 cause AV on DeXter compiler.
Do we reopen #13747?

[BCMF]
bcc32 -Od raid230977.cpp
raid230977.exe

res: crash
QC #: Date Reported: Area:
66972 9/19/2008 Compiler\C++\Front End\Exception Handling
Description: Steps:
[QC Short Description]
No destructor for base class of partially constructed object when derived contructor throws exception in Release mode

[QC Description]
See steps.
QC Entry 66972

OR

bcc32 -tCV 265381.cpp
bcc32 -tCV 265381.cpp
265381.exe

res:
----Test1----
Constructing A1
Constructing B1
Abort constructing B1
Caught exception:
A: 1
B: 0
C: 0
Failed
----Test2----
Constructing A1
Constructing A2
Constructing B1
Abort constructing B1
Caught exception:
Destructing A2
A: 1
B: 0
C: 0
Failed

expected:
----Test1----
Constructing A1
Constructing B1
Abort constructing B1
Destructing A1
Caught exception:
Passed
----Test2----
Constructing A1
Constructing A2
Constructing B1
Abort constructing B1
Destructing A2
Caught exception:
Destructing A1
Passed
QC #: Date Reported: Area:
67080 9/23/2008 Compiler\C++\Front End\Exception Handling
Description: Steps:
[QC Short Description]
Temporay objects are not desructed correctly on exception in Release mode
[QC Description]
Code derived from

Report No: 14979 (RAID: unavailable) Status: Closed(fixed)
Temporay objects bound to const & are not desructed correctly on expction
http://qc.codegear.com/wc/qcmain.aspx?d=14979
----------------------------------------------
Debug mode is OK,
release mode has wrong binary code.
----------------------------------------------

//qc67080a.cpp:

#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
#include <iostream>

using std::cout;
using std::endl;

int a14979=0;

class Test {
public:
explicit Test(int id) : id_(id) {
a14979++;
cout << " Test " << id_ << endl;
}
~Test() {
a14979--;
cout << "~Test " << id_ << endl;
}
private:
int id_;
};

typedef const Test &TTest;
class Ex{};

Test getTest(int id) { return Test(id); }

void test3(bool b)
{
TTest t1 = getTest(1); (t1);
{ TTest t2 = getTest(2); (t2); }
if(b) throw Ex();
}

int main()
{
a14979 = 0;
try { test3(false); }
catch(const Ex&){ cout << "caught" << endl; }
if( a14979 ) cout << "Failed" << endl; else cout << "Passed" << endl;

a14979 = 0;
try { test3(true); }
catch(const Ex&){ cout << "caught" << endl; }
if(a14979) cout << "Failed" << endl; else cout << "Passed" << endl;
return 0;
}

//qc67080.cpp:

#include <vcl.h>
#include <tchar.h>
#include <stdio.h>

void Log(AnsiString msg)
{
fprintf(stdout, "%s\n", msg.c_str());
}

int a14979=0;

class Test
{
public:
explicit Test(int id) : id_(id)
{
a14979++;
AnsiString s; s=" Test "+IntToStr(id_); Log(s);
}
~Test()
{
a14979--;
AnsiString s; s="~Test "+IntToStr(id_); Log(s);
}
private:
int id_;
};

typedef const Test &TTest;
class Ex{};

Test getTest(int id) { return Test(id); }

void test3(bool b)
{
TTest t1 = getTest(1);
{ TTest t2 = getTest(2); }
if(b) throw Ex();
}

int _tmain(int argc, _TCHAR* argv[])
{
a14979=0;
try { test3(false); }
catch(const Ex&){ Log("caught"); }
if(a14979) Log("Failed"); else Log("Passed");

a14979=0;
try { test3(true); }
catch(const Ex&){ Log("caught"); }
if(a14979) Log("Failed"); else Log("Passed");

return 0;
}
QC Entry 67080
bcc32 -WCV -vi- qc67080.cpp
qc67080 - note the output

Exp: Output

Test 1
Test 2
~Test 2
~Test 1
Passed
Test 1
Test 2
~Test 2
~Test 1
caught
Passed

Act: Output

Test 1
Test 2
~Test 2
~Test 1
Passed
Test 1
Test 2
~Test 2
caught
Failed

Note:
It appears on later testing that the -vi switch may be the actual culprit here. Testing with both -v and -vi passed produced these results, which are consistent with the assumption that the state of the -v switch controls the state of the -vi switch and that the -vi switch causes the failure:

-v -vi Fail
-v -vi- Pass
-v- -vi Fail
-v- -vi- Pass
-vi -v Pass
-vi -v- Fail
-vi- -v Pass
-vi- -v- Fail

If the same steps are used with qc67080a.cpp instead of qc67080.cpp, The output will show "Passed" in both the release and the debug build. Note that qc67080 does not require the -WCV flag, but the results are the same with or without the flag.

The difference between the two files is that qc67080 uses AnsiStrings passed to a logging function to produce the output. qc67080a instead passes string literals and int variables directly to std::cout, so no AnsiStrings are created.

Tested also with String (UnicodeString) in the logging function and got the same failure as with AnsiString.
QC #: Date Reported: Area:
68143 10/21/2008 Compiler\C++\Back End
Description: Steps:
[QC Short Description]
internal backend error C1980

[QC Description]
The following code causes internal backend error C1980:

typedef __int64 sval_t;
typedef unsigned __int64 uval_t;

// changing the type of idx to be sval_t fixes the problem.
bool bar(uval_t idx);

struct myclass
{
bool foo(sval_t idx) { return bar(idx); }
};

void func(void)
{
myclass x;
x.foo(0);
}


QC Entry 68143
bcc32 -c 266023.cpp

res:
CodeGear C++ 6.10 for Win32 Copyright (c) 1993-2008 CodeGear
266023.cpp:
Internal backend error C1980 compiling 266023.cpp(16)
*** 1 errors in Compile ***

exp: compiles
QC #: Date Reported: Area:
68772 11/10/2008 CodeGuard\CodeGuard 32
Description: Steps:
[QC Short Description]
CodeGuard causes access violation for __uuidof()

[QC Description]
CodeGuard seems to cause problems with the __uuidof() directive. The attached sample program demonstrates the problem.
QC Entry 68772
bcc32.exe -vGd qc68772.cpp
qc68772.cpp:

exp:

{00000000-0000-0000-C000-000000000046}

act: crash
QC #: Date Reported: Area:
69246 11/24/2008 Compiler\C++
Description: Steps:
[QC Short Description]
Object destroyed twice by exception handler

[QC Description]
Object destroyed twice when passed as argument of c'tor with __fastcall modifier and exception occurs in the c'tor, such as:

class Foo
{
public:
__fastcall Foo(ObjectDestroyedTwice obj)
{ throw Exception(""); }
}

This causes app crash.
QC Entry 69246
bcc32 -WCV raid266902_reduced.cpp
raid266902_reduced.exe

expected:
10099, created (1) 12FF80
10100, created (2) 12FF40
10100, destroyed 12FF40
10099, destroyed 12FF80

actual:

10099, created (1) 12FF80
10100, created (2) 12FF40
10100, destroyed 12FF40
4358108, destroyed 12FF78
-1, destroyed 12FF40
10099, destroyed 12FF80

The line:

4358108, destroyed 12FF78

is the return-value from the function being destructed (shouldn't be since the function call aborted)

And the line:

-1, destroyed 12FF40

is a duplicate destruction of the argument temporary.
QC #: Date Reported: Area:
69968 12/17/2008 Compiler\C++\Front End\Exception Handling
Description: Steps:
[QC Short Description]
Class member destructor is called twice after exception in constructor with inlining disabled

[QC Description]
See steps.
QC Entry 69968
bcc32 -vi- qc69968.cpp
qc69968.exe

Expected output:
DestructionLogger at 0x12FF84 constructed
DestructionLogger at 0x9130CC constructed
DestructionLogger at 0x9130CC destroyed
DestructionLogger at 0x12FF84 destroyed

Actual output:
DestructionLogger at 0x12FF84 constructed
DestructionLogger at 0x9130CC constructed
DestructionLogger at 0x9130CC destroyed
DestructionLogger at 0x9130CC destroyed
DestructionLogger at 0x12FF84 destroyed
QC #: Date Reported: Area:
70098 12/23/2008 Compiler\C++\Front End\Exception Handling
Description: Steps:
[QC Short Description]
AV when throwing an exception from a function which has non-trivial parameter and return value

[QC Description]
Compile the following code will cause an access violation and the destruction of the wrong object.

This is a real show-stopper when trying to write exception-safe COM wrapper functions.

Also, this is a regression from at least C++Builder 2006. Although former versions of C++Builder used to leak some of the objects, they did not fault. In five words: this prevents me from upgrading.

// -----
#include <unknwn.h>
#include <cstdio>
#include <typeinfo>
#pragma hdrstop


enum TConstructDestructAction
{
cdaConstructed = 0,
cdaCopyConstructed = 1,
cdaDestroyed = 2,
};

void logConstructionDestruction (TConstructDestructAction cda, const char* name, void* ptr)
{
static const char* actiondescs[] = {
"constructed",
"copy-constructed",
"destroyed",
};

char buf[200];
std::printf ("%s at 0x%.8X: %s\n", name, ptr, actiondescs[int (cda)]);
}

template <class I>
class InterfacePtr
{
private:
I* intf;

inline void intfAddRef (void)
{
if (intf)
intf->AddRef ();
}
static inline void intfAddRef (I*& _intf)
{
if (_intf)
_intf->AddRef ();
}
inline void intfRelease (void)
{
if (intf)
intf->Release ();
}

void logConstruction (void)
{
logConstructionDestruction (cdaConstructed, typeid (*this).name (), this);
}
void logDestruction (void)
{
logConstructionDestruction (cdaDestroyed, typeid (*this).name (), this);
}

public:
inline InterfacePtr (void)
: intf (0)
{
logConstruction ();
}
inline InterfacePtr (I* _intf)
: intf (_intf)
{
logConstruction ();
intfAddRef ();
}
inline InterfacePtr (const InterfacePtr& rhs)
: intf (rhs.intf)
{
logConstruction ();
intfAddRef ();
}
inline ~InterfacePtr (void)
{
logDestruction ();
intfRelease ();
}
inline const InterfacePtr& operator = (InterfacePtr rhs)
{
intfAddRef (rhs.intf);
intfRelease ();
intf = rhs.intf;
return *this;
}
};


typedef InterfacePtr <IUnknown> IUnknownPtr;


class TheClass
{
public:
IUnknownPtr callFoo (IUnknownPtr intf)
{
IUnknownPtr __retval;
HRESULT __result;
if ((__result = virtualFoo (intf, __retval)) != S_OK)
throw 1;
return __retval;
}
HRESULT virtualFoo (IUnknownPtr intf,
IUnknownPtr& __result)
{
try
{
__result = actualFoo (intf);
return 0;
}
catch (int)
{ return 1; }
}
IUnknownPtr actualFoo (IUnknownPtr intf)
{
throw 1;
}
};

int main (void)
{
try
{
TheClass u2;
u2.callFoo (0);
}
catch (...)
{}
}
// -----

QC Entry 70098
bcc32 qc70098.cpp
qc70098.exe

Expected output:
InterfacePtr<IUnknown> at 0x0012FF4C: constructed
InterfacePtr<IUnknown> at 0x0012FF38: constructed
InterfacePtr<IUnknown> at 0x0012FEFC: constructed
InterfacePtr<IUnknown> at 0x0012FEB4: constructed
InterfacePtr<IUnknown> at 0x0012FEB4: destroyed
InterfacePtr<IUnknown> at 0x0012FEFC: destroyed
InterfacePtr<IUnknown> at 0x0012FF38: destroyed
InterfacePtr<IUnknown> at 0x0012FF4C: destroyed

Actual output:
InterfacePtr<IUnknown> at 0x0012FF4C: constructed
InterfacePtr<IUnknown> at 0x0012FF38: constructed
InterfacePtr<IUnknown> at 0x0012FEFC: constructed
InterfacePtr<IUnknown> at 0x0012FEB4: constructed
InterfacePtr<IUnknown> at 0x0012FEB4: destroyed
InterfacePtr<IUnknown> at 0x0012FEB8: destroyed // note that the pointer is bogus
(Some access violation messages from Windows occur here.)
InterfacePtr<IUnknown> at 0x0012FF38: destroyed
InterfacePtr<IUnknown> at 0x0012FF4C: destroyed
QC #: Date Reported: Area:
70655 1/20/2009 Compiler\C++\Front End\Exception Handling
Description: Steps:
[QC Short Description]
Object declared in conditional clause is destroyed twice after exception

[QC Description]
Yet another bug in the well-known scheme: exception handling and declarations inside conditional clauses.

Bug was discovered by Zach Saw and discussed here:
https://forums.codegear.com/thread.jspa?threadID=10422

This is a regression from C++Builder 2006.

Note that BCC 5.8, although not destroying an object twice, still caused a leak:

Tracker <0> constructed at 0012FF84
Tracker <1> constructed at 0012FF7C
Tracker <0> destroyed at 0012FF84

This leak is present in BCC 6.1 as well.

Attached code:

#include <iostream>

template <unsigned ClassIndex>
struct Tracker {
Tracker (void)
{ std::cout << "Tracker <" << ClassIndex << "> constructed at " << this << std::endl; }
~Tracker (void)
{ std::cout << "Tracker <" << ClassIndex << "> destroyed at " << this << std::endl; }
Tracker (const Tracker& rhs)
{ std::cout << "Tracker <" << ClassIndex << "> copy-constructed at " << this << std::endl; }
inline operator bool() const
{ return true; }
};

Tracker <0> createTracker (void)
{ return Tracker <0> (); }

int main () {
try {
if (Tracker <0> tr1 = createTracker ())
for (Tracker <1> tr2;;)
throw 1;
} catch (...) {}
}
QC Entry 70655
download attachment
bcc32 qc70655.cpp
qc70655.exe

Expected output:
Tracker <0> constructed at 12ff84
Tracker <1> constructed at 12ff7c
Tracker <1> destroyed at 12ff7c
Tracker <0> destroyed at 12ff84

Actual output:
Tracker <0> constructed at 12ff84
Tracker <1> constructed at 12ff7c
Tracker <0> destroyed at 12ff84
Tracker <0> destroyed at 12ff84



Article originally contributed by Kris Houser

Tags: C++Builder bugs C++



Check out more tips and tricks in this development video: