Sign in Join

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

Mailing lists / fpc-devel / 2011-06

New language idea: Unified types (assignment size-compatible types).

21 messages · 10 people · –

Reply by email Subscribe to this list Your subscription

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

Skybuck Flying

Hello,

Here is a new language idea which would make Delphi a bit more friendly:

First the problem:

pointers and longwords are not assignment compatible.

This is pretty much bullshit because they are the same size.

Now the solution, create a new type which has the same size and make it "size compatible" with all other types of the same size so for example:

type
    TUnifiedType = unify longword;

This would make the TUnifiedType assigment compatible with all other types of the same size.

If this is to broad then the syntax can also be made less broad by having to specify all types which are to be considered assignment compatible.

Example of less-broad-syntax:

type
  TUnifiedType = unify longword pointer integer Pinteger Plongword;

The following code would then be possible:

procedure API( ParaUnifiedType : TUnifiedType );
var
    p : pointer;
    t : integer;
    w : longword;
    k : Pinteger;
    z : Plongword;
    e : TunifiedType;
begin
    API( p );
    API( T );
    API( w ):
    API( k );
    API( z );
    e := p;
    p := e;
    // etc
end;

This would also solve some other problems:

var
    I : integer;
    b : byte;
begin
    i := integer(b); // unsafe typecast ! variable overflow ! undetected by
Delphi XE !
end;

Typecasts for unified types no longer necessary, however unified types have automatic size checking so these errors would be caught.

Furthermore writing the api as follows would also not be necessary

API( var data );

^ very unsafe... this would allow more data to be passed in then might be expected, leading to parameter overflow !

Therefore conclusion can only be:

Unified types would make programming safer and a whole lot easier without all those damned typecasts ! ;) :)

Less remark this could probably come in handy for cuda as well, which has slightly different types for example:

host pointer (pointer) vs cuda pointer (longword)

For the unified addressing future of cuda/api the new unified type for Delphi would be very welcome ! ;) :)

Bye,
Skybuck.

Reply by email

Paul Dunn
to Skybuck Flying
Skybuck Flying wrote
Here is a new language idea which would make Delphi a bit more friendly:

Do the Embarcadero developers read this list?

Show quoted text 5 lines
First the problem: pointers and longwords are not assignment compatible. This is pretty much bullshit because they are the same size.

Unfortunately pointers are not the same size as longwords on some architectures - on x64, they're twice the size.

D.

Reply by email

Paul Dunn
to Skybuck Flying
Skybuck Flying wrote
Not a problem, that's what the unified type is for. It detects "pointer" and "longword" is of different size on 64 bit so then it's not allowed ;)

Wouldn't that break your code between platforms quite considerably? I can't see how this would be remotely useful!

D.

Reply by email

Lloyd Park
to Paul Dunn

Not to mention that it breaks the strong typing that is central to Pascal's design.

Paul Dunn wrote 14 lines
On Mon, Jun 20, 2011 at 6:12 AM, Skybuck Flying wrote: > Not a problem, that's what the unified type is for. > > It detects "pointer" and "longword" is of different size on 64 bit so then > it's not allowed ;) Wouldn't that break your code between platforms quite considerably? I can't see how this would be remotely useful! D. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Skybuck Flying
to Paul Dunn: Wouldn't that break your code between platforms quite considerably? I can't see how this…

Not really, because if the platform changes from 32 bit to 64 bit then other types would change too.

For example type declared as being longword would change to uint64.

So the only thing which needs to happen is a changed to TUnifiedAddress for example.

was:

TUnifiedAddress = unify longword pointer;

becomes:

TUnifiedAddress = unify uint64 pointer;

additional example for longword:

was:

TExternalPointer = longword;

becomes:

TExternalPointer = uint64;

Bye,
Skybuck.

Reply by email

Skybuck Flying
to Lloyd Park: Not to mention that it breaks the strong typing that is central to Pascal's design.

From: Lloyd Park
Sent: Monday, June 20, 2011 4:30 PM
To: FPC developers' list
Subject: Re: [fpc-devel] New language idea: Unified types(assignmentsize-compatible types).

“
Not to mention that it breaks the strong typing that is central to Pascal's design. “
Nope, the strong type checking is still in place for all other types, except for the unified type. The programmer uses it to indicate he knows what he is doing. It actually makes type checking stronger, typecasts can go wrong when types change and remain undetected, the unified type would immediately detect it. In this sense the unified type can be thought of as doing automatic typecasts but even better the compiler checks the sizes to make sure they are of the same size, something that is not done for typecasts.
Bye,
Skybuck.

Reply by email

Hans-Peter Diettrich
to Skybuck Flying: Not really, because if the platform changes from 32 bit to 64 bit then other types would…
Not really, because if the platform changes from 32 bit to 64 bit then other types would change too. For example type declared as being longword would change to uint64.

Please understand generic types first.

A LongWord will always have 32 bits, because it's a concrete type. Instead Integer, Cardinal, Char, String or Real can vary with every compiler version or target platform, because these are *generic* types.

BTW I don't know of *any* language that changed "long" integers to 64 bits on 64 bit platforms.

Since C has absolutely *no* idea of fixed-size integers, all concrete types are subject to conditional definitions in the header files:

#if (sizeof(int)==4)

   typedef int32 int;

#elif (sizeof(int)==2)

   typedef int16 int;

#else
#error clueless
#endif

#if (sizeof(int*)==4)

   typedef ptr_int int32;

#elif (sizeof(int*)==8)

   typedef ptr_int int64; //hope that an int64 type has been found out

#else
#error clueless
#endif

DoDi

Reply by email

Hans-Peter Diettrich
to Sven Barth
Show quoted text 6 lines
On 21.06.2011 13:09, Hans-Peter Diettrich wrote: > BTW I don't know of *any* language that changed "long" integers to 64 > bits on 64 bit platforms. Aehm... C did that basically everywhere except on Windows: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

Hmmm, looks as if my memory failed :-(

Most probably I confused int and long, where some people argued that *int* should have the native register size, i.e. 64 bits on 64 bit systems.

Thanks for the correction :-)

DoDi

Reply by email

Sven Barth
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 14 lines
Sven Barth schrieb: > On 21.06.2011 13:09, Hans-Peter Diettrich wrote: >> BTW I don't know of *any* language that changed "long" integers to 64 >> bits on 64 bit platforms. > > Aehm... C did that basically everywhere except on Windows: > http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models Hmmm, looks as if my memory failed :-( Most probably I confused int and long, where some people argued that *int* should have the native register size, i.e. 64 bits on 64 bit systems. Thanks for the correction :-)

You are welcome. :)

Regards,
Sven

Reply by email

Mark Morgan Lloyd
to Paul Dunn: Do the Embarcadero developers read this list? Unfortunately pointers are not the same…
Paul Dunn wrote 14 lines
On Sun, Jun 19, 2011 at 1:15 AM, Skybuck Flying wrote: > Here is a new language idea which would make Delphi a bit more friendly: Do the Embarcadero developers read this list? > First the problem: > > pointers and longwords are not assignment compatible. > > This is pretty much bullshit because they are the same size. Unfortunately pointers are not the same size as longwords on some architectures - on x64, they're twice the size.

The size is irrelevant. Pointers and numeric types have different sets of applicable operators, in the same way as bitsets and numeric types have different operators. You can add two numbers and get a meaningful result, you can't add two pointers or bitsets.

There's a fairly old book on linkers and loaders which uses the analogy that pointers are like vectors and integer types like scalars, and then explores the various combinations of operators etc.

Whether it would be desirable to have some construct that allowed assignment without a warning is, of course, a different matter. But at that point, in the general case, one has to consider that different architectures assume different pointer behavior, such as the normalised pointers assumed by Turbo Pascal- with which FPC still has some interest in being compatible.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Graeme Geldenhuys
to Hans-Peter Diettrich: Please understand generic types first. A LongWord will always have 32 bits, because it's…
Hans-Peter Diettrich wrote
A LongWord will always have 32 bits, because it's a concrete type. Instead Integer, Cardinal, Char, String or Real can vary with every compiler version or target platform, because these are *generic* types.

Um, I think you are mistaken. Integer is *always* 32-bits on either 32-bit or 64-bit target platforms. NativeInt is different sizes on different target platforms. I think LongWord also varies in size based on target platform, though not 100% sure on this one.

Regards,   - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

Sven Barth
to Graeme Geldenhuys
Graeme Geldenhuys wrote 13 lines
On 21 June 2011 13:09, Hans-Peter Diettrich wrote: > > A LongWord will always have 32 bits, because it's a concrete type. Instead > Integer, Cardinal, Char, String or Real can vary with every compiler version > or target platform, because these are *generic* types. Um, I think you are mistaken. Integer is *always* 32-bits on either 32-bit or 64-bit target platforms. NativeInt is different sizes on different target platforms. I think LongWord also varies in size based on target platform, though not 100% sure on this one.

No, LongWord does not vary. It's always 32-Bit.
But Hans-Peter is right so far that Integer was originally considered a generic type. You can still see this if you do a "SizeOf(Integer)" once in mode FPC (2 bytes) and in mode ObjFPC (4 bytes). I didn't test "SizeOf(Cardinal)" in mode FPC yet though...

Regards,
Sven

Reply by email

Graeme Geldenhuys
to Hans-Peter Diettrich: No. It *happens* to have 32 bit there. On 16 bit platforms (TP, Delphi 1) it was 16 bit.…
Hans-Peter Diettrich wrote 6 lines
> Integer is *always* 32-bits on either > 32-bit or 64-bit target platforms. It *happens* to have 32 bit there. On 16 bit platforms (TP, Delphi 1) it was 16 bit. I'm not sure when Delphi changed that to 32 bit, perhaps not before D3.

The point I was trying to make is that it is NOT going to become a 64-bit type in Delphi 64-bit (one day when it actually arrives). And neither is it a 64-bit type under current 64-bit FPC as far as I remember.

It might have been a "generic" type in the 16/32 bit days, but it isn't any more in the 32/64 bit FPC/Delphi compilers.

Anyway, this is what I remember from a discussion a few months back with Michael van Canneyt. He even pointed me to the newly updated docs for the FPC types mentioning the same thing - I still had older FPC documentation printed out which was wrong at the time (hence my confusion).

Regards,   - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

Marco van de Voort
to Graeme Geldenhuys: Um, I think you are mistaken. Integer is *always* 32-bits on either 32-bit or 64-bit…

In our previous episode, Graeme Geldenhuys said:

Um, I think you are mistaken. Integer is *always* 32-bits on either 32-bit or 64-bit target platforms

That's because FPC currently only supports LP64 and LLP64 systems.

There are some systems (IIRC some AIX editions) that are ILP64 (iow in C "int" is 64-bit).

What FPC will do there is probably still undecided, since it will be a dilemma between compatibility with the OS it is running on vs compatibility with other FPC targets.

Reply by email

Jonas Maebe
to Marco van de Voort
Marco van de Voort wrote
What FPC will do there is probably still undecided, since it will be a dilemma between compatibility with the OS it is running on vs compatibility with other FPC targets.

I'm fairly sure we'd keep the definition the same as on other platforms. For OS interoperability we have the ctypes unit.

Jonas

Reply by email

Marco van de Voort
to Jonas Maebe

In our previous episode, Jonas Maebe said:

Show quoted text 5 lines
> What FPC will do there is probably still undecided, since it will be a > dilemma between compatibility with the OS it is running on vs compatibility > with other FPC targets. I'm fairly sure we'd keep the definition the same as on other platforms.

As long as a majority platform doesn't change, probably indeed. (if only that it would require a significant hardening of the RTL and core packages)

Anyway, for me it is hard to predict what will work and what will break. Do
we know how gcc deals with such targets?
For OS interoperability we have the ctypes unit.

Hmm. I just looked around a bit, and noticed that the ctypes unit doesn't alias the C types (unix/ctypes.inc) the *nix rtl exports. (via e.g. unixtype and aliasctp.inc).

In such case where RTL and external interpretations vary this might have to be fixed. (I'm wondering if it originally were aliases)

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: Um, I think you are mistaken. Integer is *always* 32-bits on either 32-bit or 64-bit…
Show quoted text 7 lines
On 21 June 2011 13:09, Hans-Peter Diettrich wrote: > A LongWord will always have 32 bits, because it's a concrete type. Instead > Integer, Cardinal, Char, String or Real can vary with every compiler version > or target platform, because these are *generic* types. Um, I think you are mistaken.

No.

Integer is *always* 32-bits on either 32-bit or 64-bit target platforms.

It *happens* to have 32 bit there. On 16 bit platforms (TP, Delphi 1) it was 16 bit. I'm not sure when Delphi changed that to 32 bit, perhaps not before D3.

NativeInt is different sizes on different target platforms. I think LongWord also varies in size based on target platform, though not 100% sure on this one.

In Delphi (XE) NativeInt has the CPU register size, assuming that data and address registers have the same size (i.e. unsegmented pointers). LongWord still is documented as a fundamental (non-generic) 32 bit type.

DoDi

Reply by email

Paulo Costa
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote
It *happens* to have 32 bit there. On 16 bit platforms (TP, Delphi 1) it was 16 bit. I'm not sure when Delphi changed that to 32 bit, perhaps not before D3.

The change was in D2.
Delphi 2 was the first "32 bits" Delphi.

Paulo Costa

Reply by email

Skybuck Flying
to Hans-Peter Diettrich: No. It *happens* to have 32 bit there. On 16 bit platforms (TP, Delphi 1) it was 16 bit.…

Here is a little idea for an automated check or so, to warn if something odd is happening or so ;) :):

Assert( SizeOf(byte) = 1, 'SizeOf(byte)(' + IntToStr(SizeOf(byte)) + ') =
1' );
Assert( SizeOf(word) = 2, 'SizeOf(word)(' + IntToStr(SizeOf(word)) + ') =
2' );
Assert( SizeOf(longword) = 4, 'SizeOf(longword)(' +
IntToStr(SizeOf(longword)) + ') = 4' );
Assert( SizeOf(uint64) = 8, 'SizeOf(uint64)(' + IntToStr(SizeOf(uint64)) +
') = 8' );
Assert( SizeOf(shortint) = 1, 'SizeOf(shortint)(' +
IntToStr(SizeOf(shortint)) + ') = 1' );
Assert( SizeOf(smallint) = 2, 'SizeOf(smallint)(' +
IntToStr(SizeOf(smallint)) + ') = 2' );
Assert( SizeOf(integer) = 4, 'SizeOf(integer)(' + IntToStr(SizeOf(integer))
+ ') = 4' );
Assert( SizeOf(int64) = 8, 'SizeOf(int64)(' + IntToStr(SizeOf(int64)) + ') =
8' );

Code is untested but should work ! ;)

Bye,
Skybuck.

Reply by email