Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Why doesn't this work with bcc32c?



Permlink Replies: 4 - Last Post: Aug 27, 2017 9:33 AM Last Post By: Albert Wiersch
Albert Wiersch

Posts: 37
Registered: 11/27/08
Why doesn't this work with bcc32c?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 25, 2017 10:02 PM
This cost me hours of time to track down... someone please help me understand what's going on and if it's me or the compiler.

I made a little C++Builder project in 10.2.1 which you can download here:
https://www.htmlvalidator.com/test/Broken.zip

Run the app and click the big button.

bcc32c with 'Debug' build: WORKS
bcc32 with 'Release' or 'Debug' build: WORKS
bcc32c with 'Release' build: ACCESS VIOLATION

Bug in my code or bug in the compiler or something else?

Main code from Unit1.cpp:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 Label1->Caption=TestClass::getCodePageFromString(L"utf-8");
}
//---------------------------------------------------------------------------


Main code from Unit2.h:

class TestClass {
 struct codepageinfo {
  const wchar_t *cpname;
  codepage_t cpid;
 };
 
 public:
  static codepage_t getCodePageFromString(const wchar_t *string);
 
  static const TestClass::codepageinfo codepagearray[]; // new 2008-05-22
};
//---------------------------------------------------------------------------


Main code from Unit2.cpp:

codepage_t TestClass::getCodePageFromString(const wchar_t *string) {
 size_t index(0);
 
 while (true) {
  const codepageinfo *cpinfo(codepagearray+index);
  if ( (!cpinfo) || (cpinfo->cpid==CODEPAGE_NA) ) break; // end of list
  if (_wcsicmp(string,(cpinfo->cpname))==0) return cpinfo->cpid;
  index++;
 }
 
 return CODEPAGE_NA;
}
//---------------------------------------------------------------------------
 
const TestClass::codepageinfo TestClass::codepagearray[]={
 // "popular" ones first
 {L"utf-8",CODEPAGE_UTF8},
 {L"utf-16",CODEPAGE_UTF16BE}, // assume BE, but first two chars of text should still be checked for a BOM
 {L"utf-16be",CODEPAGE_UTF16BE},
 {L"utf-16le",CODEPAGE_UTF16LE},
 {L"iso-8859-1",CODEPAGE_ISO_8859_1},
 {L"us-ascii",CODEPAGE_US_ASCII},
<snip>
 {NULL,CODEPAGE_NA}
};
//---------------------------------------------------------------------------


Edited by: Albert Wiersch on Aug 25, 2017 10:03 PM

Edited by: Albert Wiersch on Aug 25, 2017 10:06 PM
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: Why doesn't this work with bcc32c? [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2017 4:18 AM   in response to: Albert Wiersch in response to: Albert Wiersch
El 26/08/2017 a las 7:07, Albert Wiersch escribió:
This cost me hours of time to track down... someone please help me understand what's going on and if it's me or the compiler.

I made a little C++Builder project in 10.2.1 which you can download here:
https://www.htmlvalidator.com/test/Broken.zip

Run the app and click the big button.

bcc32c with 'Debug' build: WORKS
bcc32 with 'Release' or 'Debug' build: WORKS
bcc32c with 'Release' build: ACCESS VIOLATION

Bug in my code or bug in the compiler or something else?

Apparently the problem is in the compiler or probably in the linker when optimizations are enabled. In that case the
code tries to access an incorrect base address of codepagearray.

With this modification the problem seems to disappear:

codepage_t TestClass::getCodePageFromString(const wchar_t *string) {
    const codepageinfo *cpinfo= codepagearray;
 
    while ( cpinfo->cpname && _wcsicmp(string, cpinfo->cpname)!=0 )
       cpinfo++;
 
    return cpinfo->cpid;
}

Also the problem disappear if you move the declarations of the codepageinfo struct out of the class and remove the
declaration of the codepagearray variable:

//Unit2.h
...
class TestClass {
public:
   static codepage_t getCodePageFromString(const wchar_t *string);
};
...


//Unit2.cpp
...
namespace {
struct codepageinfo {
    const wchar_t *cpname;
    codepage_t cpid;
};
 
const codepageinfo codepagearray[]={
  // "popular" ones first
  {L"utf-8",CODEPAGE_UTF8},
  {L"utf-16",CODEPAGE_UTF16BE}, // assume BE, but first two chars of text should still be checked for a BOM
  {L"utf-16be",CODEPAGE_UTF16BE},
  {L"utf-16le",CODEPAGE_UTF16LE},
  {L"iso-8859-1",CODEPAGE_ISO_8859_1},
  {L"us-ascii",CODEPAGE_US_ASCII},
 
  {L"iso-8859-2",static_cast<codepage_t>(28592)},
  {L"iso-8859-3",static_cast<codepage_t>(28593)},
  {L"iso-8859-4",static_cast<codepage_t>(28594)},
  {L"iso-8859-5",static_cast<codepage_t>(28595)},
  {L"iso-8859-6",static_cast<codepage_t>(28596)},
  {L"iso-8859-7",static_cast<codepage_t>(28597)},
  {L"iso-8859-8",static_cast<codepage_t>(28598)},
  {L"iso-8859-9",static_cast<codepage_t>(28599)},
  {L"iso-8859-15",static_cast<codepage_t>(28605)},
  {L"shift-jis",static_cast<codepage_t>(932)}, // hyphen
  {L"shift_jis",static_cast<codepage_t>(932)}, // underscore
  {L"utf-32",static_cast<codepage_t>(12001)}, // assume big endian
  {L"utf-32be",static_cast<codepage_t>(12001)},
  {L"utf-32le",static_cast<codepage_t>(12000)},
  {L"utf-7",static_cast<codepage_t>(65000)},
  {L"windows-874",static_cast<codepage_t>(874)},
  {L"windows-1250",static_cast<codepage_t>(1250)},
  {L"windows-1251",static_cast<codepage_t>(1251)},
  {L"windows-1252",static_cast<codepage_t>(1252)},
  {L"windows-1253",static_cast<codepage_t>(1253)},
  {L"windows-1254",static_cast<codepage_t>(1254)}, // new 2017-03-06
  {L"windows-1255",static_cast<codepage_t>(1255)}, // new 2017-03-06
  {L"windows-1256",static_cast<codepage_t>(1256)}, // new 2017-03-06
  {L"windows-1257",static_cast<codepage_t>(1257)},
  {L"windows-1258",static_cast<codepage_t>(1258)},
  {NULL,CODEPAGE_NA}
};
 
} // namespace
//---------------------------------------------------------------------------
codepage_t TestClass::getCodePageFromString(const wchar_t *string) {
  size_t index(0);
 
  while (true) {
   const codepageinfo *cpinfo(codepagearray+index);
   if ( (!cpinfo) || (cpinfo->cpid==CODEPAGE_NA) ) break; // end of list
   if (_wcsicmp(string,(cpinfo->cpname))==0) return cpinfo->cpid;
   index++;
  }
 
  return CODEPAGE_NA;
}
 
// OR
/*
codepage_t TestClass::getCodePageFromString(const wchar_t *string) {
    const codepageinfo *cpinfo= codepagearray;

    while ( cpinfo->cpname && _wcsicmp(string, cpinfo->cpname)!=0 )
       cpinfo++;

    return cpinfo->cpid;
}
*/


You should submit a bug report at the Quality Portal about this issue:
https://quality.embarcadero.com
Albert Wiersch

Posts: 37
Registered: 11/27/08
Re: Why doesn't this work with bcc32c? [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2017 7:53 AM   in response to: Antonio Estevez in response to: Antonio Estevez
{quote:title=Antonio Estevez wrote:}
You should submit a bug report at the Quality Portal about this issue:
https://quality.embarcadero.com

Thanks for checking this out. I had already found out that moving codepageinfo and codepagearray out of the class would work but I still wanted to know if it was me or a bug.

I've reported the issue/bug here:
https://quality.embarcadero.com/browse/RSP-18930
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: Why doesn't this work with bcc32c? [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2017 8:21 AM   in response to: Albert Wiersch in response to: Albert Wiersch
El 26/08/2017 a las 16:53, Albert Wiersch escribió:
{quote:title=Antonio Estevez wrote:}
You should submit a bug report at the Quality Portal about this issue:
https://quality.embarcadero.com

Thanks for checking this out. I had already found out that moving codepageinfo and codepagearray out of the class would work but I still wanted to know if it was me or a bug.

I've reported the issue/bug here:
https://quality.embarcadero.com/browse/RSP-18930

You should upload the zip file to the bug report by clicking the "Attach Files" button instead of providing a download
url. Not everyone likes to download files from unknown sources.
Albert Wiersch

Posts: 37
Registered: 11/27/08
Re: Why doesn't this work with bcc32c? [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 26, 2017 8:41 AM   in response to: Antonio Estevez in response to: Antonio Estevez
You should upload the zip file to the bug report by clicking the "Attach Files" button instead of providing a download
url. Not everyone likes to download files from unknown sources.

Thanks. Done!
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02