Watch, Follow, &
Connect with Us

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


Welcome, Guest
Guest Settings
Help

Thread: Ambiguity in common functions, why?



Permlink Replies: 15 - Last Post: Mar 13, 2015 3:48 PM Last Post By: Remy Lebeau (Te...
Bo Berglund

Posts: 757
Registered: 10/23/02
Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 5:41 AM
Seems like a never ending story to go from BDS2006 to XE5 C++....
When I fixed the Graph include problem anotyher item popped up:
[bcc32 Error] FormMemStatus.cpp(313): E2015 Ambiguity between
'_fastcall System::Sysutils::IntToStr(int) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2934' and
'_fastcall System::Sysutils::IntToStr(__int64) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2935'
[bcc32 Error] FormMemStatus.cpp(326): E2015 Ambiguity between
'_fastcall System::Sysutils::IntToStr(int) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2934' and
'_fastcall System::Sysutils::IntToStr(__int64) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2935'
[bcc32 Error] FormMemStatus.cpp(327): E2015 Ambiguity between
'_fastcall System::Sysutils::IntToStr(int) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2934' and
'_fastcall System::Sysutils::IntToStr(__int64) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2935'
[bcc32 Error] FormMemStatus.cpp(342): E2015 Ambiguity between
'_fastcall System::Sysutils::IntToStr(int) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2934' and
'_fastcall System::Sysutils::IntToStr(__int64) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2935'

It seems like one cannot use simple functions like IntToStr anymore
because the compiler has trouble knowing the datatype of the passed
argument...
THere seems to be overloaded functions with 64 bit arguments...

Why in heavens name is this happening? I am on a Win32 only
application and there seems to be no way to stop this from happening.
I first had some such errors concerning floats vs doubles, so I had to
typecast into float.
But now these ambiguities pop up for IntToStr, which seems utterly
ridicilous....

Is there a global setting to get rid of this and have the compiler use
32 bit functions? After all I am compiling for Win32 and there is no
other platform in the project...
Borja Serrano

Posts: 172
Registered: 1/10/13
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 7:57 AM   in response to: Bo Berglund in response to: Bo Berglund
If you are using "int" variables you should not see this error (I have just made a quick test). If you are using "unsigned int" variables you should use UIntToStr instead.
Bo Berglund

Posts: 757
Registered: 10/23/02
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 8:20 AM   in response to: Borja Serrano in response to: Borja Serrano
On Wed, 11 Mar 2015 07:57:13 -0700, Borja Serrano <> wrote:

If you are using "int" variables you should not see this error
(I have just made a quick test). If you are using "unsigned int"
variables you should use UIntToStr instead.

The variables are from different places, like properties of
components. I earlier had problems with the Value field of a SpinEdit
component so I typecasted it.
But now more and more of these pop up and I wonder if there is not a
global way to handle it?
I don't want to change the code in a non-portable way and BDS2006 I
believe did not have a UIntToStr function..

A couple of these values to convert for display come from a struct
defined in winbase.h and I am not likely to modify that...
typedef struct _MEMORYSTATUS {
    DWORD dwLength;
    DWORD dwMemoryLoad;  <== This throws the error
    SIZE_T dwTotalPhys;
    SIZE_T dwAvailPhys;
    SIZE_T dwTotalPageFile;
    SIZE_T dwAvailPageFile;
    SIZE_T dwTotalVirtual;
    SIZE_T dwAvailVirtual;
} MEMORYSTATUS, *LPMEMORYSTATUS;

So IntToStr does not understand DWORD now, but it did in the past,
why?
Borja Serrano

Posts: 172
Registered: 1/10/13
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 8:24 AM   in response to: Bo Berglund in response to: Bo Berglund
Before there was only one version of the routine, and the automatic cast was enough. DWORD is an "unsigned long". Why don't you create your own IntToStr function that gets a DWORD? In its code, make the cast to "int" and it will work.
Bo Berglund

Posts: 757
Registered: 10/23/02
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 9:41 AM   in response to: Borja Serrano in response to: Borja Serrano
On Wed, 11 Mar 2015 08:24:05 -0700, Borja Serrano <> wrote:

Our posts crossed...

Before there was only one version of the routine, and the automatic cast was enough.
DWORD is an "unsigned long". Why don't you create your own IntToStr function that
gets a DWORD? In its code, make the cast to "int" and it will work.

Problem is I am a Delphi person, I don't know much about creating
functions and the like...

In Delphi I would have done as follows:
function IntToStr(Value: DWORD): String; overload;
var
  tmp: Cardinal;
begin
  tmp := Value;
  Result := IntToStr(tmp);
end;

If this was put on top of the file in the implementation section the
compiler would have picked it up instead of the standard function if
the argument is a DWORD.

But when I look around in C++ I see all kinds of confusing constructs
so I cannot even start writing an overloaded function....
In many cases there is __fastcall in the declaration.
If I just copy paste I can get to this:
UnicodeString __fastcall IntToStr(DWORD Value)/* overload */;
{
  unsigned long tmp = Value;
  return (UintToStr(tmp));
}


Will this be correct???

It really bugs me to have had an IntToStr function in Delphi for years
(19+) on end into which one could send literally any variable or
expression that evaluates to an integer value (in this case "integer"
means what it usually does: whole numbers).

I could not imagine that in C++ there are separate IntToStr functions
for every single kind of integer type (and is missing DWORD). And the
user needs to use the specific version. :(

I always thought that Delphi and C++ in the same level of the IDE had
the same functionality....
Borja Serrano

Posts: 172
Registered: 1/10/13
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 10:00 AM   in response to: Bo Berglund in response to: Bo Berglund
UnicodeString IntToStr(DWORD Value)
{
return UIntToStr((unsigned int)Value);
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DWORD i=6772;
Edit1->Text = IntToStr(i);
}

This works on my side
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 10:45 AM   in response to: Borja Serrano in response to: Borja Serrano
Borja wrote:

UnicodeString IntToStr(DWORD Value)

In Delphi, you might need such a function, but in C++ you don't need it at
all:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    DWORD i=6772;
    Edit1->Text = String(i);
}


Which can be simplified to the following, by allowing the compiler to create
a temp String object implicitly (something that cannot be done in Delphi):

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    DWORD i = 6772;
    Edit1->Text = i;
}


--
Remy Lebeau (TeamB)
Borja Serrano

Posts: 172
Registered: 1/10/13
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 12, 2015 8:04 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
That's the perfect answer
Bo Berglund

Posts: 757
Registered: 10/23/02
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2015 5:27 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
On Wed, 11 Mar 2015 10:45:55 -0700, Remy Lebeau (TeamB)
<no dot spam at no dot spam dot com> wrote:

Borja wrote:

UnicodeString IntToStr(DWORD Value)

In Delphi, you might need such a function, but in C++ you don't need it at
all:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   DWORD i=6772;
   Edit1->Text = String(i);
}


Which can be simplified to the following, by allowing the compiler to create
a temp String object implicitly (something that cannot be done in Delphi):

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   DWORD i = 6772;
   Edit1->Text = i;
}
How far back was this possible? Back until BDS2006?
In that case I could use this trick to get rid of the errors and still
be backwards compatible...
david hoke

Posts: 616
Registered: 2/9/07
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2015 8:24 AM   in response to: Bo Berglund in response to: Bo Berglund
"Bo Berglund" <bo dot berglund at nospam dot com> wrote in message
news:717543 at forums dot embarcadero dot com...
How far back was this possible? Back until BDS2006?
In that case I could use this trick to get rid of the errors and still
be backwards compatible...

A ways - the following are the AnsiString constructors in bds2006 (found in
dstring.h header):
__fastcall AnsiString(const char* src);
__fastcall AnsiString(const AnsiString& src);
// __fastcall AnsiString(const char* src, unsigned char len);
__fastcall AnsiString(const char* src, unsigned int len);
__fastcall AnsiString(const wchar_t* src);
__fastcall AnsiString(char src);
__fastcall AnsiString(short);
__fastcall AnsiString(unsigned short);
__fastcall AnsiString(int src);
__fastcall AnsiString(unsigned int);
__fastcall AnsiString(long);
__fastcall AnsiString(unsigned long);
__fastcall AnsiString(__int64);
__fastcall AnsiString(unsigned __int64);
__fastcall AnsiString(double src);
__fastcall AnsiString(const WideString &src);
Borja Serrano

Posts: 172
Registered: 1/10/13
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2015 8:26 AM   in response to: david hoke in response to: david hoke
unsigned long (DWORD) is included
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2015 3:48 PM   in response to: david hoke in response to: david hoke
david wrote:

the following are the AnsiString constructors in bds2006

All of those constructors exist all the way back to BCB 5 (I don't have an
earlier version installed to check, but I suspect they existed as far back
as BCB 3).

WideString (and UnicodeString in CB2009+) have similar constructors.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2015 3:38 PM   in response to: Bo Berglund in response to: Bo Berglund
Bo wrote:

How far back was this possible? Back until BDS2006?

All the way back to the very beginning when AnsiString was first introduced
in C++Builder in v3 (AnsiString was introduced in Delphi in v2, and there
was no C++Builder v2).

--
Remy Lebeau (TeamB)
Bo Berglund

Posts: 757
Registered: 10/23/02
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 8:29 AM   in response to: Bo Berglund in response to: Bo Berglund
On Wed, 11 Mar 2015 08:20:06 -0700, Bo Berglund
<bo dot berglund at nospam dot com> wrote:

On Wed, 11 Mar 2015 07:57:13 -0700, Borja Serrano <> wrote:

If you are using "int" variables you should not see this error
(I have just made a quick test). If you are using "unsigned int"
variables you should use UIntToStr instead.

I don't want to change the code in a non-portable way and BDS2006 I
believe did not have a UIntToStr function..
I went ahead and changed the IntToStr calls for local variables to
UIntToStr and it fixed the problem, but probably not if I go back to
BDS2006...

A couple of these values to convert for display come from a struct
defined in winbase.h and I am not likely to modify that...
typedef struct _MEMORYSTATUS {
   DWORD dwLength;
   DWORD dwMemoryLoad;  <== This throws the error</div>
... cut ...
<div class="jive-quote">} MEMORYSTATUS, *LPMEMORYSTATUS;

So IntToStr does not understand DWORD now, but it did in the past,
why?

Still after changing to UIntToStr for one of these lines I still have
the ambiguity errors:
sgdMemStatus->Cells[1][1] = UIntToStr(memory.dwMemoryLoad) + "%";
sgdMemStatus->Cells[1][1] = IntToStr(memory.dwMemoryLoad) + "%";

and here are the error output lines:
[bcc32 Error] FormMemStatus.cpp(313): E2015 Ambiguity between
'_fastcall System::Sysutils::UIntToStr(unsigned int) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2936' and
'_fastcall System::Sysutils::UIntToStr(unsigned __int64) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2937'
[bcc32 Error] FormMemStatus.cpp(342): E2015 Ambiguity between
'_fastcall System::Sysutils::IntToStr(int) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2934' and
'_fastcall System::Sysutils::IntToStr(__int64) at
c:\programs\embarcadero\rad
studio\12.0\include\windows\rtl\System.SysUtils.hpp:2935'

Note that the compiler still tries to fit the data into an int64,
without anyone asking for it.
How do you convert DWORD values to string using the standard
functions?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 10:43 AM   in response to: Bo Berglund in response to: Bo Berglund
Bo wrote:

The variables are from different places, like properties of
components.

That does not negate what Borja said. You have to pay attention to what
data types you are using, and use appropriate functions.

I earlier had problems with the Value field of a SpinEdit component so
I typecasted it.

Yes, because that particular property uses a 'long' instead of an 'int' or
'__int64'. IntToStr() only accepts 'int' and '__int64' values as input.
So a type-cast is needed to let the compiler know which overload of IntToStr()
to use.

But now more and more of these pop up and I wonder if there is not a
global way to handle it?

There is not. You have to handle it at the call site each time.

I don't want to change the code in a non-portable way and BDS2006 I
believe did not have a UIntToStr function..

Correct. It was introduced in BDS2009. The 'portable' solution is to use
the String constructor instead. It has overloads for many data types, including
'unsigned long' (which DWORD is an typedef for).

So IntToStr does not understand DWORD now,
but it did in the past, why?

It never understood DWORD, only 'int', and '__int64' in BCB5 onwards. So,
since BCB5, IntToStr() has always required a type-cast when passing it a
DWORD.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Ambiguity in common functions, why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 11, 2015 10:34 AM   in response to: Bo Berglund in response to: Bo Berglund
Bo wrote:

It seems like one cannot use simple functions like IntToStr anymore
because the compiler has trouble knowing the datatype of the passed
argument...

THere seems to be overloaded functions with 64 bit arguments...

The Int64 overload of IntToStr() has existed for a LONG LONG time, since
at least BCB 5 (and thus exists in BDS2006 as well). Delphi's Int64 type
was introduced in Delphi 4, not sure when __int64 first appeared in C++Builder
but it was probably around that same time.

Why in heavens name is this happening?

IntToStr() only accepts an 'int' or '__int64' as input. The ambiguity error
means you must be passing something else that implicitly converts to both
'int' and '__int64', so the compiler does not know which overload you want
to call. You have to use a type-cast or a local int/__int64 to resolve that.

Personally, I never use IntToStr() in C++. I use AnsiString/UnicodeString
constructors instead. They both have overloaded constructors for many many
more data types, and there is less ambiquity. For example:

sgdMemStatus->Cells[1][1] = String(memory.dwMemoryLoad) + "%";


Alternatively, use a formatting function instead:

sgdMemStatus->Cells[1][1] = String().sprintf(_D("%u%%"), memory.dwMemoryLoad);


sgdMemStatus->Cells[1][1] = Format("%d%%", ARRAYOFCONST(( memory.dwMemoryLoad 
)) );


I first had some such errors concerning floats vs doubles, so I had to
typecast into float.
But now these ambiguities pop up for IntToStr, which seems utterly
ridicilous....

It is not rediculous at all, when you pay attention to what your code is
actually doing.

Is there a global setting to get rid of this and have the compiler use
32 bit functions?

No.

After all I am compiling for Win32 and there is no other platform in the
project...

Irrelevant. This issue is not a platform-related issue.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02