Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2008-09

Bug in FPC and declaring distinct types

28 messages · 7 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

I was following a discussion in the delphi.non-technical newsgroup. They raised an issue about distinct types. I tried the following example under FPC and unexpectedly, FPC doesn't raise any errors!

If you declare a distinct type as follows:
  type TMyInteger = type Integer;

The type TMyInteger Integer so you are not supposed to be allowed to assign one to the other. Yet you can. See the following program.

----------------------[  test1.pas ]--------------------------
program test1;
{$mode objfpc}{$H+}
uses
  Classes, SysUtils;
type
  Angle = type Double;
  Length = type Double;
function AngleToLength(var a: Angle):Length;  { Note the var parameter }
begin
  result := a;
end;
function AngleToLength2(a: Angle):Length;  { Here is NO var parameter }
begin
  result := a;
end;
procedure Test;
var
  a: Angle;
  l: Length;
  d: Double;
begin
  d := Now;
  a := d;
  l := a;  // Should this have failed ????
  { FPC raises no errors, but at least Delphi raises an error wit the
     var parameter type. }
  a := AngleToLength(l);  // This should definitely have failed!!
  a := AngleToLength2(l);  // Should this fail too?
end;
begin
  Test;
end.
--------------------------[ end ]-----------------------------

The program was compiled with FPC 2.2.3:
fpc test1.pas
./test1

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 11 lines
Hi, I was following a discussion in the delphi.non-technical newsgroup. They raised an issue about distinct types. I tried the following example under FPC and unexpectedly, FPC doesn't raise any errors! If you declare a distinct type as follows: type TMyInteger = type Integer; The type TMyInteger Integer so you are not supposed to be allowed to assign one to the other. Yet you can. See the following program.

But obviously delphi also allows it ? It compiles everything, just not as a var parameter.

The whole 'Type' thing is a bit ridiculous: the only reason they did it is so they can have different type pointers in the RTTI for something which is the same 'type' anyway. For the rest it is extremely badly designed, and not really consistent. It serves no purpose. FPC introduced it to be able to compile Delphi code, no other reason.

Michael.

Show quoted text 60 lines
----------------------[ test1.pas ]-------------------------- program test1; {$mode objfpc}{$H+} uses Classes, SysUtils; type Angle = type Double; Length = type Double; function AngleToLength(var a: Angle):Length; { Note the var parameter } begin result := a; end; function AngleToLength2(a: Angle):Length; { Here is NO var parameter } begin result := a; end; procedure Test; var a: Angle; l: Length; d: Double; begin d := Now; a := d; l := a; // Should this have failed ???? { FPC raises no errors, but at least Delphi raises an error wit the var parameter type. } a := AngleToLength(l); // This should definitely have failed!! a := AngleToLength2(l); // Should this fail too? end; begin Test; end. --------------------------[ end ]----------------------------- The program was compiled with FPC 2.2.3: fpc test1.pas ./test1 Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/ _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt
Michael Van Canneyt wrote 6 lines
> > The type TMyInteger Integer so you are not supposed to be allowed > to assign one to the other. Yet you can. See the following program. But obviously delphi also allows it ? It compiles everything, just not as a var parameter.

Which still doesn't discount it as a bug in both FPC and Delphi! At least in Delphi it fails on the var parameter, so it's 50% there - it should really fail on both counts. You are not allowed to do that (assign different types) with any other types, so why allow it with custom made types??

Show quoted text 5 lines
The whole 'Type' thing is a bit ridiculous: the only reason they did it is so they can have different type pointers in the RTTI for something which is the same 'type' anyway. For the rest it is extremely badly designed, and not really consistent. It serves no purpose. FPC introduced it to be able to compile Delphi code, no other reason.

I'm not going to get into the whole argument about the usefulness of distinct types - for that you can read the thread posted in delphi.non-technical titled: "Generics. How can I?" dated 2008-09-15

All I can say, is that distinct types (custom made types) are used all over the place, in Delphi, Lazarus, fpGUI and I'm pretty sure FPC as well. It's a handy language feature and should allow type safety like all other types.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 30 lines
On Thu, Sep 18, 2008 at 9:42 AM, Michael Van Canneyt wrote: >> >> The type TMyInteger Integer so you are not supposed to be allowed >> to assign one to the other. Yet you can. See the following program. > > But obviously delphi also allows it ? It compiles everything, > just not as a var parameter. Which still doesn't discount it as a bug in both FPC and Delphi! At least in Delphi it fails on the var parameter, so it's 50% there - it should really fail on both counts. You are not allowed to do that (assign different types) with any other types, so why allow it with custom made types?? > The whole 'Type' thing is a bit ridiculous: the only reason they did it > is so they can have different type pointers in the RTTI for something which > is the same 'type' anyway. For the rest it is extremely badly designed, > and not really consistent. It serves no purpose. FPC introduced it to > be able to compile Delphi code, no other reason. I'm not going to get into the whole argument about the usefulness of distinct types - for that you can read the thread posted in delphi.non-technical titled: "Generics. How can I?" dated 2008-09-15 All I can say, is that distinct types (custom made types) are used all over the place, in Delphi, Lazarus, fpGUI and I'm pretty sure FPC as well. It's a handy language feature and should allow type safety like all other types.

And it is also very annoying because

Type
  MyString = type string;
Const
  AString = 'something';
Var
  M : MyString;
begin
  M:=AString;
end.

Will no longer compile if you are too strict. They should at least remain assignment compatible. Delphi does the best it can, FPC should maybe be a bit more strict - it should not allow the var parameter.

Michael.

Reply by email

Marco van de Voort
to Michael Van Canneyt

In our previous episode, Michael Van Canneyt said:

Show quoted text 18 lines
And it is also very annoying because Type MyString = type string; Const AString = 'something'; Var M : MyString; begin M:=AString; end. Will no longer compile if you are too strict. They should at least remain assignment compatible. Delphi does the best it can, FPC should maybe be a bit more strict - it should not allow the var parameter.

Well, IMHO that is the idea! So that you can e.g. declare a UTF8string that way (in pre Tiburon land), and get compiler errors on the spot where you need to call conversion routines.

But I agree it works poorly. In both.

Reply by email

Florian Klaempfl
to Michael Van Canneyt: But obviously delphi also allows it ? It compiles everything, just not as a var parameter.
Show quoted text 23 lines
On Thu, 18 Sep 2008, Graeme Geldenhuys wrote: > Hi, > > I was following a discussion in the delphi.non-technical newsgroup. > They raised an issue about distinct types. I tried the following > example under FPC and unexpectedly, FPC doesn't raise any errors! > > If you declare a distinct type as follows: > type TMyInteger = type Integer; > > The type TMyInteger Integer so you are not supposed to be allowed > to assign one to the other. Yet you can. See the following program. But obviously delphi also allows it ? It compiles everything, just not as a var parameter. The whole 'Type' thing is a bit ridiculous: the only reason they did it is so they can have different type pointers in the RTTI for something which is the same 'type' anyway. For the rest it is extremely badly designed, and not really consistent. It serves no purpose. FPC introduced it to be able to compile Delphi code, no other reason.

This is not true. The main purpose is to be able to overload functions/operators:

type
   TUTF8String = type ansistring;

enables you to overload all procedure already defined for ansistrings with UTF8String functions but reusing ansistring support functionality and this is supported for years. Because nobody used this yet to make an utf-8 unit, I never took the unicode string support serious :)

Reply by email

Michael Van Canneyt
to Florian Klaempfl
Florian Klaempfl wrote 30 lines
Michael Van Canneyt schrieb: > > On Thu, 18 Sep 2008, Graeme Geldenhuys wrote: > > > Hi, > > > > I was following a discussion in the delphi.non-technical newsgroup. > > They raised an issue about distinct types. I tried the following > > example under FPC and unexpectedly, FPC doesn't raise any errors! > > > > If you declare a distinct type as follows: > > type TMyInteger = type Integer; > > > > The type TMyInteger Integer so you are not supposed to be allowed > > to assign one to the other. Yet you can. See the following program. > > But obviously delphi also allows it ? It compiles everything, > just not as a var parameter. > > The whole 'Type' thing is a bit ridiculous: the only reason they did it > is so they can have different type pointers in the RTTI for something which > is the same 'type' anyway. For the rest it is extremely badly designed, and > not really consistent. It serves no purpose. FPC introduced it to be able to > compile Delphi code, no other reason. This is not true. The main purpose is to be able to overload functions/operators: type TUTF8String = type ansistring;

Well, that was not so for delphi. The delphi help explicitly says:

"if your purpose in defining a new type is to utilize runtime type information--for example, to associate a property editor with properties of a particular type--the distinction between "different name" and "different type" becomes important. In this case, use the syntax"

I've lived with this knowledge for years :-)

Show quoted text 5 lines
enables you to overload all procedure already defined for ansistrings with UTF8String functions but reusing ansistring support functionality and this is supported for years. Because nobody used this yet to make an utf-8 unit, I never took the unicode string support serious :)

Aha, in that case, you should have told me this so I could document it !

I cannot see inside your head, you know :-)

Maybe make a backup of your brain and send it to me ? A 1Tb. external disk is no longer so expensive :-)

Michael.

Reply by email

Yury Sidorov
to Florian Klaempfl: This is not true. The main purpose is to be able to overload functions/operators: type…

From: "Florian Klaempfl"

Show quoted text 41 lines
Michael Van Canneyt schrieb: > > On Thu, 18 Sep 2008, Graeme Geldenhuys wrote: > >> Hi, >> >> I was following a discussion in the delphi.non-technical >> newsgroup. >> They raised an issue about distinct types. I tried the following >> example under FPC and unexpectedly, FPC doesn't raise any errors! >> >> If you declare a distinct type as follows: >> type TMyInteger = type Integer; >> >> The type TMyInteger Integer so you are not supposed to be >> allowed >> to assign one to the other. Yet you can. See the following >> program. > > But obviously delphi also allows it ? It compiles everything, > just not as a var parameter. > > The whole 'Type' thing is a bit ridiculous: the only reason they > did it > is so they can have different type pointers in the RTTI for > something which > is the same 'type' anyway. For the rest it is extremely badly > designed, and not really consistent. It serves no purpose. FPC > introduced it to be able to compile Delphi code, no other reason. This is not true. The main purpose is to be able to overload functions/operators: type TUTF8String = type ansistring; enables you to overload all procedure already defined for ansistrings with UTF8String functions but reusing ansistring support functionality and this is supported for years. Because nobody used this yet to make an utf-8 unit, I never took the unicode string support serious :)

Yes. But it works only partially. For example the following code is not compilable:

//------
type
  TUTF8String = type ansistring;
procedure DoTest(const s: ansistring); overload;
begin
end;
procedure DoTest(const s: TUTF8String); overload;
begin
end;
begin
  DoTest('1234');
end.
//------

Yury Sidorov.

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt: And it is also very annoying because Type MyString = type string; Const AString =…
Michael Van Canneyt wrote 18 lines
And it is also very annoying because Type MyString = type string; Const AString = 'something'; Var M : MyString; begin M:=AString; end. Will no longer compile if you are too strict. They should at least remain assignment compatible.

That's the whole point - it shouldn't be assignment compatible. You are creating a new MyString type, irrespective of what base-type it was based on. Only MyString types should be assigned to MyString types, otherwise you could simply have used String type.

I thought the example given in the delphi.non-technical discussion was quite a good. Using mathematics and defining a Angle and Elevation type. Both used the base-type Double. But in a math function you need to know which one you are working with and what functions allow what types (speaking of radians and degrees).

"Believe me, if you work with angles, one can easily confuse radians and degrees (IOW, one can easily forget to convert between them), especially if the user is used to using degrees, while the library (sine, cosine, etc.) requires radians." -- Rudy Velthuis

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Florian Klaempfl
to Graeme Geldenhuys
Show quoted text 27 lines
On Thu, Sep 18, 2008 at 10:11 AM, Michael Van Canneyt wrote: > And it is also very annoying because > > Type > MyString = type string; > > Const > AString = 'something'; > > Var > M : MyString; > > begin > M:=AString; > end. > > Will no longer compile if you are too strict. They should at least remain > assignment compatible. That's the whole point - it shouldn't be assignment compatible. You are creating a new MyString type, irrespective of what base-type it was based on. Only MyString types should be assigned to MyString types, otherwise you could simply have used String type. I thought the example given in the delphi.non-technical discussion was quite a good.

It's as useless as any talk in this newsgroup. If you don't like two types being assignment compatible, use classes, records whatever.

Show quoted text 9 lines
Using mathematics and defining a Angle and Elevation type. Both used the base-type Double. But in a math function you need to know which one you are working with and what functions allow what types (speaking of radians and degrees). "Believe me, if you work with angles, one can easily confuse radians and degrees (IOW, one can easily forget to convert between them), especially if the user is used to using degrees, while the library (sine, cosine, etc.) requires radians." -- Rudy Velthuis

See above.

Reply by email

Florian Klaempfl
to Yury Sidorov: From: "Florian Klaempfl" Yes. But it works only partially. For example the following code…
Show quoted text 40 lines
From: "Florian Klaempfl" > Michael Van Canneyt schrieb: >> >> On Thu, 18 Sep 2008, Graeme Geldenhuys wrote: >> >>> Hi, >>> >>> I was following a discussion in the delphi.non-technical newsgroup. >>> They raised an issue about distinct types. I tried the following >>> example under FPC and unexpectedly, FPC doesn't raise any errors! >>> >>> If you declare a distinct type as follows: >>> type TMyInteger = type Integer; >>> >>> The type TMyInteger Integer so you are not supposed to be allowed >>> to assign one to the other. Yet you can. See the following program. >> >> But obviously delphi also allows it ? It compiles everything, >> just not as a var parameter. >> >> The whole 'Type' thing is a bit ridiculous: the only reason they did it >> is so they can have different type pointers in the RTTI for something >> which >> is the same 'type' anyway. For the rest it is extremely badly >> designed, and not really consistent. It serves no purpose. FPC >> introduced it to be able to compile Delphi code, no other reason. > > This is not true. The main purpose is to be able to overload > functions/operators: > > type > TUTF8String = type ansistring; > > enables you to overload all procedure already defined for ansistrings > with UTF8String functions but reusing ansistring support functionality > and this is supported for years. Because nobody used this yet to make > an utf-8 unit, I never took the unicode string support serious :) Yes. But it works only partially. For example the following code is not compilable:

Well, I wouldn't know either what you expect :)

Show quoted text 23 lines
//------ type TUTF8String = type ansistring; procedure DoTest(const s: ansistring); overload; begin end; procedure DoTest(const s: TUTF8String); overload; begin end; begin DoTest('1234'); end. //------ Yury Sidorov. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Ivo Steinmann
to Graeme Geldenhuys: I was following a discussion in the delphi.non-technical newsgroup. They raised an issue…
Show quoted text 65 lines
Hi, I was following a discussion in the delphi.non-technical newsgroup. They raised an issue about distinct types. I tried the following example under FPC and unexpectedly, FPC doesn't raise any errors! If you declare a distinct type as follows: type TMyInteger = type Integer; The type TMyInteger Integer so you are not supposed to be allowed to assign one to the other. Yet you can. See the following program. ----------------------[ test1.pas ]-------------------------- program test1; {$mode objfpc}{$H+} uses Classes, SysUtils; type Angle = type Double; Length = type Double; function AngleToLength(var a: Angle):Length; { Note the var parameter } begin result := a; end; function AngleToLength2(a: Angle):Length; { Here is NO var parameter } begin result := a; end; procedure Test; var a: Angle; l: Length; d: Double; begin d := Now; a := d; l := a; // Should this have failed ???? { FPC raises no errors, but at least Delphi raises an error wit the var parameter type. } a := AngleToLength(l); // This should definitely have failed!! a := AngleToLength2(l); // Should this fail too? end; begin Test; end. --------------------------[ end ]----------------------------- The program was compiled with FPC 2.2.3: fpc test1.pas ./test1 Regards, - Graeme -

This one is working also ;) No idea if it should or not....

program test;
{$mode objfpc}
{$H+}
type
  TTypeA = type Integer;
  TTypeB = type Integer;
  IIntf = interface
    function GetSomething: TTypeA;
  end;
  TMyObject = class(TInterfacedObject, IIntf)
    function GetSomething: TTypeB; virtual;
  end;
  TMyObject2 = class(TMyObject)
    function GetSomething: TTypeA; override;
  end;
function TMyObject.GetSomething: TTypeB;
begin
end;
function TMyObject2.GetSomething: TTypeA;
begin
end;
begin
end.

Reply by email

Graeme Geldenhuys
to Florian Klaempfl: It's as useless as any talk in this newsgroup. If you don't like two types being…
Florian Klaempfl wrote 11 lines
> > That's the whole point - it shouldn't be assignment compatible. You > are creating a new MyString type, irrespective of what base-type it > was based on. Only MyString types should be assigned to MyString > types, otherwise you could simply have used String type. > > I thought the example given in the delphi.non-technical discussion was > quite a good. It's as useless as any talk in this newsgroup. If you don't like two types being assignment compatible, use classes, records whatever.
If the developer wants assignment compatibility surely he could then
use the alias types??

eg: #1

type
   MyType = Double;
   MyOtherType = Double;

With the above types you should have assignment compatibility between MyType, MyOtherType and Double.
When creating distinct types as show below, type safety should come into play and assignment compatibility should be broken.

eg: #2

type
   MyType = type Double;
   MyOtherType = type Double;

Otherwise, what's the different between a "alias" type (eg #1) and a "distinct" type (eg #2)??

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Florian Klaempfl
to Graeme Geldenhuys
Show quoted text 9 lines
eg: #2 type MyType = type Double; MyOtherType = type Double; Otherwise, what's the different between a "alias" type (eg #1) and a "distinct" type (eg #2)??

As I said: overloading. It means: compatible but not equal. If you want distinct: use as said, classes, records etc.

Reply by email

Yury Sidorov
to Florian Klaempfl: Well, I wouldn't know either what you expect :)

From: "Florian Klaempfl"

Show quoted text 49 lines
Yury Sidorov schrieb: > From: "Florian Klaempfl" >> Michael Van Canneyt schrieb: >>> >>> On Thu, 18 Sep 2008, Graeme Geldenhuys wrote: >>> >>>> Hi, >>>> >>>> I was following a discussion in the delphi.non-technical >>>> newsgroup. >>>> They raised an issue about distinct types. I tried the following >>>> example under FPC and unexpectedly, FPC doesn't raise any >>>> errors! >>>> >>>> If you declare a distinct type as follows: >>>> type TMyInteger = type Integer; >>>> >>>> The type TMyInteger Integer so you are not supposed to be >>>> allowed >>>> to assign one to the other. Yet you can. See the following >>>> program. >>> >>> But obviously delphi also allows it ? It compiles everything, >>> just not as a var parameter. >>> >>> The whole 'Type' thing is a bit ridiculous: the only reason they >>> did it >>> is so they can have different type pointers in the RTTI for >>> something which >>> is the same 'type' anyway. For the rest it is extremely badly >>> designed, and not really consistent. It serves no purpose. FPC >>> introduced it to be able to compile Delphi code, no other reason. >> >> This is not true. The main purpose is to be able to overload >> functions/operators: >> >> type >> TUTF8String = type ansistring; >> >> enables you to overload all procedure already defined for >> ansistrings with UTF8String functions but reusing ansistring >> support functionality and this is supported for years. Because >> nobody used this yet to make an utf-8 unit, I never took the >> unicode string support serious :) > > Yes. But it works only partially. For example the following code is > not compilable: Well, I wouldn't know either what you expect :)

I expect that compiler will choose DoTest with ansistring parameter in that case.

Show quoted text 17 lines
> //------ > type > TUTF8String = type ansistring; > > procedure DoTest(const s: ansistring); overload; > begin > end; > > procedure DoTest(const s: TUTF8String); overload; > begin > end; > > begin > DoTest('1234'); > end. > > //------

Reply by email

Florian Klaempfl
to Yury Sidorov
Show quoted text 7 lines
>> Yes. But it works only partially. For example the following code is >> not compilable: > > Well, I wouldn't know either what you expect :) I expect that compiler will choose DoTest with ansistring parameter in that case.

What rule do you apply to say this?

Show quoted text 22 lines
>> //------ >> type >> TUTF8String = type ansistring; >> >> procedure DoTest(const s: ansistring); overload; >> begin >> end; >> >> procedure DoTest(const s: TUTF8String); overload; >> begin >> end; >> >> begin >> DoTest('1234'); >> end. >> >> //------ _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Yury Sidorov
to Florian Klaempfl

From: "Florian Klaempfl"
To: "FPC developers' list"
Sent: Thursday, September 18, 2008 4:14 PM
Subject: Re: [fpc-devel] Bug in FPC and declaring distinct types

Show quoted text 10 lines
Yury Sidorov schrieb: >>> Yes. But it works only partially. For example the following code >>> is not compilable: >> >> Well, I wouldn't know either what you expect :) > > I expect that compiler will choose DoTest with ansistring parameter > in that case. What rule do you apply to say this?

Compiler treats '1234' as ansistring constant. Therefore ansistring overload must be choosen here.

Like in this case:

const
  sss: ansistring = '1234';
...
DoTest(sss);
Show quoted text 17 lines
>>> //------ >>> type >>> TUTF8String = type ansistring; >>> >>> procedure DoTest(const s: ansistring); overload; >>> begin >>> end; >>> >>> procedure DoTest(const s: TUTF8String); overload; >>> begin >>> end; >>> >>> begin >>> DoTest('1234'); >>> end. >>> >>> //------

Reply by email

Florian Klaempfl
to Yury Sidorov
Show quoted text 19 lines
From: "Florian Klaempfl" To: "FPC developers' list" Sent: Thursday, September 18, 2008 4:14 PM Subject: Re: [fpc-devel] Bug in FPC and declaring distinct types > Yury Sidorov schrieb: >>>> Yes. But it works only partially. For example the following code is >>>> not compilable: >>> >>> Well, I wouldn't know either what you expect :) >> >> I expect that compiler will choose DoTest with ansistring parameter >> in that case. > > What rule do you apply to say this? Compiler treats '1234' as ansistring constant. Therefore ansistring overload must be choosen here.

No, '1234' is taken as generic string constant.

Show quoted text 30 lines
Like in this case: const sss: ansistring = '1234'; ... DoTest(sss); >>>> //------ >>>> type >>>> TUTF8String = type ansistring; >>>> >>>> procedure DoTest(const s: ansistring); overload; >>>> begin >>>> end; >>>> >>>> procedure DoTest(const s: TUTF8String); overload; >>>> begin >>>> end; >>>> >>>> begin >>>> DoTest('1234'); >>>> end. >>>> >>>> //------ _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Graeme Geldenhuys
to Florian Klaempfl
Florian Klaempfl wrote 6 lines
>> What rule do you apply to say this? > > Compiler treats '1234' as ansistring constant. Therefore ansistring > overload must be choosen here. No, '1234' is taken as generic string constant.

And which type is a generic string? When compiled with {$mode objfpc}{$H+} I would have thought ansistring? Well, at least that is how I understood the $H directive.

Either way, I still think FPC and Delphi is broken (FPC more so than Delphi) with regards to distinct type declarations.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Yury Sidorov
to Florian Klaempfl: No, '1234' is taken as generic string constant.

From: "Florian Klaempfl"

Show quoted text 22 lines
Yury Sidorov schrieb: > From: "Florian Klaempfl" > To: "FPC developers' list" > Sent: Thursday, September 18, 2008 4:14 PM > Subject: Re: [fpc-devel] Bug in FPC and declaring distinct types > > >> Yury Sidorov schrieb: >>>>> Yes. But it works only partially. For example the following >>>>> code is not compilable: >>>> >>>> Well, I wouldn't know either what you expect :) >>> >>> I expect that compiler will choose DoTest with ansistring >>> parameter in that case. >> >> What rule do you apply to say this? > > Compiler treats '1234' as ansistring constant. Therefore ansistring > overload must be choosen here. No, '1234' is taken as generic string constant.

Yes, I just tried to explain possible logic :)

Also the following code is not possible currently:

//------
operator := (const s: ansistring) r: TUTF8String;
begin
end;
operator := (const s: TUTF8String) r: ansistring;
begin
end;
//------

It makes implementation of utf8string impossible using this approach...

Show quoted text 25 lines
>>>>> //------ >>>>> type >>>>> TUTF8String = type ansistring; >>>>> >>>>> procedure DoTest(const s: ansistring); overload; >>>>> begin >>>>> end; >>>>> >>>>> procedure DoTest(const s: TUTF8String); overload; >>>>> begin >>>>> end; >>>>> >>>>> begin >>>>> DoTest('1234'); >>>>> end. >>>>> >>>>> //------ > _______________________________________________ > fpc-devel maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-devel > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Martin Friebe
to Florian Klaempfl: No, '1234' is taken as generic string constant.
Florian Klaempfl wrote 11 lines
Yury Sidorov schrieb: >> Yury Sidorov schrieb: >>>>> Yes. But it works only partially. For example the following code >>>>> is not compilable: >>>> Well, I wouldn't know either what you expect :) >>> I expect that compiler will choose DoTest with ansistring parameter >>> in that case. >> What rule do you apply to say this? > Compiler treats '1234' as ansistring constant. Therefore ansistring > overload must be choosen here. No, '1234' is taken as generic string constant.

I was able (with "Free Pascal Compiler version 2.2.2rc1 [2008/06/27] for i386") to compile the below.
(I know it's an old fpc version, but I am not at my home PC)

As shown with the non-overloaded procedures p1a, p1w, p1s: the string 'xx' can be given to any of them.
On the other hand the compiler allowed me to overload p1 for short, ansi and wide-sring

I do not know which rule it followes if p1('xx') is called?

type
  sstr = String[3];
  procedure p1s (s : sstr);
  procedure p1a (s : ansistring);
  procedure p1w (s : widestring);
  procedure p1 (s : sstr); overload;
  procedure p1 (s : ansistring); overload;
  procedure p1 (s : widestring); overload;
implementation
procedure main;
begin
 p1('xx');
 p1s('xx');
 p1a('xx');
 p1w('xx');
end;

Warning: Use of ppc386.cfg is deprecated, please use fpc.cfg instead Hint: Start of reading config file
c:\lazarus\fpc\2.2.2\bin\i386-win32\fpc.cfg
Hint: End of reading config file c:\lazarus\fpc\2.2.2\bin\i386-win32\fpc.cfg Warning: You are using the obsolete switch -OG
Free Pascal Compiler version 2.2.2rc1 [2008/06/27] for i386 Copyright (c) 1993-2008 by Florian Klaempfl
Target OS: Win32 for i386
Compiling C:\DOCUME~1\Martin\LOCALS~1\Temp\project1.lpr Compiling unit1.pas
unit1.pas(23,18) Hint: Parameter "s" not used
unit1.pas(24,18) Hint: Parameter "s" not used
unit1.pas(25,18) Hint: Parameter "s" not used
unit1.pas(27,17) Hint: Parameter "s" not used
unit1.pas(28,17) Hint: Parameter "s" not used
unit1.pas(29,17) Hint: Parameter "s" not used
Linking C:\DOCUME~1\Martin\LOCALS~1\Temp\project1.exe 101 lines compiled, 1.3 sec , 1056816 bytes code, 280748 bytes data 2 warning(s) issued
8 hint(s) issued
Project "project1" successfully built. :)

Show quoted text 34 lines
> > Like in this case: > > const > sss: ansistring = '1234'; > ... > DoTest(sss); > >>>>> //------ >>>>> type >>>>> TUTF8String = type ansistring; >>>>> >>>>> procedure DoTest(const s: ansistring); overload; >>>>> begin >>>>> end; >>>>> >>>>> procedure DoTest(const s: TUTF8String); overload; >>>>> begin >>>>> end; >>>>> >>>>> begin >>>>> DoTest('1234'); >>>>> end. >>>>> >>>>> //------ > _______________________________________________ > fpc-devel maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-devel > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Florian Klaempfl
to Graeme Geldenhuys: On Thu, Sep 18, 2008 at 3:40 PM, Florian Klaempfl And which type is a generic string? …
Show quoted text 8 lines
On Thu, Sep 18, 2008 at 3:40 PM, Florian Klaempfl wrote: >>> What rule do you apply to say this? >> Compiler treats '1234' as ansistring constant. Therefore ansistring >> overload must be choosen here. > No, '1234' is taken as generic string constant. And which type is a generic string?

It has no particular type, guess why FPC internally has this:

        tconststringtype = (
          cst_conststring,
          cst_shortstring,
          cst_longstring,
          cst_ansistring,
          cst_widestring,
          cst_unicodestring
        );

Without any further code, the type 'asdf' is not defined, $H means only ansistring might be prefered.

Show quoted text 6 lines
When compiled with {$mode objfpc}{$H+} I would have thought ansistring? Well, at least that is how I understood the $H directive. Either way, I still think FPC and Delphi is broken (FPC more so than Delphi) with regards to distinct type declarations.

I can't help you if you don't get what "= type ..." actually means :)

Reply by email

Florian Klaempfl
to Yury Sidorov: From: "Florian Klaempfl" Yes, I just tried to explain possible logic :) Also the…
Show quoted text 40 lines
From: "Florian Klaempfl" > Yury Sidorov schrieb: >> From: "Florian Klaempfl" >> To: "FPC developers' list" >> Sent: Thursday, September 18, 2008 4:14 PM >> Subject: Re: [fpc-devel] Bug in FPC and declaring distinct types >> >> >>> Yury Sidorov schrieb: >>>>>> Yes. But it works only partially. For example the following code >>>>>> is not compilable: >>>>> >>>>> Well, I wouldn't know either what you expect :) >>>> >>>> I expect that compiler will choose DoTest with ansistring parameter >>>> in that case. >>> >>> What rule do you apply to say this? >> >> Compiler treats '1234' as ansistring constant. Therefore ansistring >> overload must be choosen here. > > No, '1234' is taken as generic string constant. Yes, I just tried to explain possible logic :) Also the following code is not possible currently: //------ operator := (const s: ansistring) r: TUTF8String; begin end; operator := (const s: TUTF8String) r: ansistring; begin end; //------ It makes implementation of utf8string impossible using this approach...

We discussed this once and concluded, that something like this hurts more than it helps because an overloaded assignment operator allows the compiler always to mess really around :)

Reply by email

Graeme Geldenhuys
to Yury Sidorov: From: "Florian Klaempfl" Yes, I just tried to explain possible logic :) Also the…
Yury Sidorov wrote
It makes implementation of utf8string impossible using this approach...

I agree. I created a distinct string type (TfpgString) in fpGUI. That way I could ensure TfpgString is a UTF-8 string and String is a AnsiString string. I replaced all String parameters with TfpgString where UTF-8 strings are expected and hoped that the compiled would complain and tell me where I tried to assign String to a TfpgString. I got no complaints... and assumed all was okay. :-(

So that means my whole assumption of type safety has gone for a ball of s**t! (well used S.African expression) ;-)

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Yury Sidorov
to Florian Klaempfl: We discussed this once and concluded, that something like this hurts more than it helps…

From: "Florian Klaempfl"

Show quoted text 46 lines
Yury Sidorov schrieb: > From: "Florian Klaempfl" >> Yury Sidorov schrieb: >>> From: "Florian Klaempfl" >>> To: "FPC developers' list" >>> Sent: Thursday, September 18, 2008 4:14 PM >>> Subject: Re: [fpc-devel] Bug in FPC and declaring distinct types >>> >>> >>>> Yury Sidorov schrieb: >>>>>>> Yes. But it works only partially. For example the following >>>>>>> code is not compilable: >>>>>> >>>>>> Well, I wouldn't know either what you expect :) >>>>> >>>>> I expect that compiler will choose DoTest with ansistring >>>>> parameter in that case. >>>> >>>> What rule do you apply to say this? >>> >>> Compiler treats '1234' as ansistring constant. Therefore >>> ansistring overload must be choosen here. >> >> No, '1234' is taken as generic string constant. > > Yes, I just tried to explain possible logic :) > > Also the following code is not possible currently: > > //------ > operator := (const s: ansistring) r: TUTF8String; > begin > end; > > operator := (const s: TUTF8String) r: ansistring; > begin > end; > //------ > > It makes implementation of utf8string impossible using this > approach... > We discussed this once and concluded, that something like this hurts more than it helps because an overloaded assignment operator allows the compiler always to mess really around :)

Maybe.
But you stated that it is possible to create fully functional utf8string type from ansistring. :)
Unfortunately it is not true :(

Yury.

Reply by email

Graeme Geldenhuys
to Florian Klaempfl: It has no particular type, guess why FPC internally has this: tconststringtype = (…
Florian Klaempfl wrote
Without any further code, the type 'asdf' is not defined, $H means only ansistring might be prefered.

So does that mean if you have {$H+} enabled, then in the example below, the p1(ansistring) version will be called?

 procedure p1 (s : shortstring); overload;
 procedure p1 (s : ansistring); overload;
 procedure p1 (s : widestring); overload;
implementation
procedure main;
begin
  p1('xx');
end;
I can't help you if you don't get what "= type ..." actually means :)

I'm trying too Florian. And clearly my initial idea of this was wrong. :-(

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Florian Klaempfl
to Yury Sidorov: From: "Florian Klaempfl" Maybe. But you stated that it is possible to create fully…
Show quoted text 9 lines
> > We discussed this once and concluded, that something like this hurts > more than it helps because an overloaded assignment operator allows > the compiler always to mess really around :) Maybe. But you stated that it is possible to create fully functional utf8string type from ansistring. :) Unfortunately it is not true :(

Indeed, you can only to a certain limit, but imo you can get very far. Things like rtti, writeln etc. aren't fixable indeed.

Reply by email

Graeme Geldenhuys
to Florian Klaempfl: This is not true. The main purpose is to be able to overload functions/operators: type…
Florian Klaempfl wrote 11 lines
This is not true. The main purpose is to be able to overload functions/operators: type TUTF8String = type ansistring; enables you to overload all procedure already defined for ansistrings with UTF8String functions but reusing ansistring support functionality and this is supported for years. Because nobody used this yet to make an utf-8 unit, I never took the unicode string support serious :)

OK, bare with me here... :-) Lets see if I understand it now. "... = type ...;" simply held or 'hints' to the compiler what overloaded function to use - nothing more - no type safety!

type
 TUTF8String = type ansistring;
procedure DoTest(const s: ansistring); overload;
begin
end;
procedure DoTest(const s: TUTF8String); overload;
begin
end;
var
  a: String; // ansistring because I have {$H+} enabled
  u: TUTF8String;
begin
  a := '1234';
  u := a;      // allowed yes because utf8string is a ansistring
  u := 'aaaaa';
  a := u;      // allowed yes because ansistring is a utf8string
  { Due to type of u, compiler will know to call DoTest(utf8string) }
 DoTest(u);
  { Due to type of a, compiler will know to call DoTest(ansistring) }
 DoTest(a);
end.

Have I got this write so far?

So going with what you said about UTF8String type.... The idea was to have overloaded copies of string functions for AnsiString, WideString and UTF8String, all having different implementations. Based on the string type passed into a function, the compiler could make a better choice as to which implementation of a function (eg: Copy(...) ) to call.

If I got this right, then clearly the Delphi/Kylix help could have explained distinct types MUCH better than they did. I (and many others) understood it as having type safety as well - assignment incompatible.

[...sorry, it's been a loooooong week for me...]

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email