Sign in Join

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

Mailing lists / fpc-devel / 2010-09

Packages, Generics

34 messages · 9 people · –

Reply by email Subscribe to this list Your subscription

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

Willibald Krenn

Hi!

Today I was thinking about fpc packages (whenever I am using this word, I mean Delphi-style-DLL-packages) and what difficulties might arise when implementing them. In my opinion, doing packages for D6-like Pascal should not be conceptually hard. It'll be more of a technical challenge to fiddle with the compiler internals.

However, since FPC supports more then the "simple" D6 language, I had a look at generics in particular. First, let me say that I am really glad to see this feature in FPC. However, I have to say that generics are NOT equivalent to C++ templates and should not be. (I strongly dislike the specialize keyword, btw., even though it makes the process of 'instantiating' the 'template' more apparent.) So, generics are _not_ pre-processor style macros - generic types are proper types. Let me explain.

Normally, a generic type can be statically checked by the compiler on it's own. You do not need to specialize it. The reason is simple: for most of the time, you could think of a generic type parameter as a variable with the type 'class of X' (which Pascal already supports). With the content of this variable you can do everything that is described in the public interface of its type. Nothing more, nothing less. For generic classes, this means that the compiler is able to check the correctness of the use of a value with a generic type without the need for specialization. Here is a catch: Pascal has quite a lot of types that are not classes. And this makes things a bit uncomfortable.

I would say that it is (almost) impossible to do packages in a sane way if we allow all sorts of operations on 'generically typed' values: If someone defines such a generic class, the compiler will need to pre-generate all possible type specializations of that class for the package file. Thereby 'all possible instantiations' means one for each non-oo type and at least one for all the object types (and possible combinations). Still worse, this would even break the 'one-implementation for all classes thing', because different classes could provide a method with the same name... (which would end up at different places in memory).

I don't know how Delphi solves these issues (w. regards to packages) but I think the one way to deal with this is to restrict the operations that can be done with values of generic types so that these operations match the type-information of the generic type parameters (e.g., generic A = class <T1 :Ordinal...> ...).

As said, all the class/interface types are no problem - they probably just need one specialization. Primitive types are basically grouped in Ordinals, Reals, Characters, Structures, Pointers, Functions. Each group comes with a set of operations that is valid and quite a lot of them end up being passed around as pointers. Refcounting aside, a common operation allowed on all types would be the assignment. This is enough for simple generic containers. Hence, if no other operation is needed, one common specialization could do. (Refcounting issue would still need to be solved, though.) If the developer needs more advanced operations, he/she has to narrow down the type that is allowed for specialization: Oridnal, or Real, or some TMyClass... . You get the basic idea. The more one restricts the generic parameter, the more one is allowed to do with values of that type. Which is the big difference to C++ templates, and the way generics should work.

So I am of the opinion that 'real' generics would make packages possible: Yes, generated code might be less efficient (int64 implementation for all signed ordinals), or there might be code duplication (for each ordinal type one implementation), but things would work. With the current implementation of generics packages are a no-go, I am afraid.

Cheers,
Willi

Reply by email

Michael Van Canneyt
to Willibald Krenn
Willibald Krenn wrote 9 lines
Hi! Today I was thinking about fpc packages (whenever I am using this word, I mean Delphi-style-DLL-packages) and what difficulties might arise when implementing them. In my opinion, doing packages for D6-like Pascal should not be conceptually hard. It'll be more of a technical challenge to fiddle with the compiler internals.

[snip]

Show quoted text 6 lines
So I am of the opinion that 'real' generics would make packages possible: Yes, generated code might be less efficient (int64 implementation for all signed ordinals), or there might be code duplication (for each ordinal type one implementation), but things would work. With the current implementation of generics packages are a no-go, I am afraid.

Packages have nothing to do with the language feature. The difficult thing is run-time resolving of all symbols. What the nature is of these symbols is really not relevant.

Michael.

Reply by email

Marco van de Voort
to Willibald Krenn: Hi! Today I was thinking about fpc packages (whenever I am using this word, I mean…

In our previous episode, Willibald Krenn said:

Show quoted text 9 lines
the correctness of the use of a value with a generic type without the need for specialization. Here is a catch: Pascal has quite a lot of types that are not classes. And this makes things a bit uncomfortable. I would say that it is (almost) impossible to do packages in a sane way if we allow all sorts of operations on 'generically typed' values: If someone defines such a generic class, the compiler will need to pre-generate all possible type specializations of that class for the package file

No it won't. Not all of the implementation of a package needs to be in the .BPL equivalent. Neither is the case in Delphi.

Seek for $weakpackage and read the packages wiki again

So in short, everything in the units that doesn't go into the DLL goes into the .DCP which is more or less a dcu archive if I understood it correctly

So only the specializations used inside the code contained in the BPL (and maybe one or two that you could force to save duplication) are in the BPL.

So in short, the problem is one that you create yourself by self-inflicting that every piece of code _must_ be in the BPL. That isn't the case.

Reply by email

Willibald Krenn
to Michael Van Canneyt: [snip] Packages have nothing to do with the language feature. The difficult thing is…
Packages have nothing to do with the language feature. The difficult thing is run-time resolving of all symbols. What the nature is of these symbols is really not relevant.

Pardon my ignorance, but why is runtime resolving so difficult? There is a fine Delphi ABI that maps classes, simple types, rtti, variables, methods, constructors, functions etc. to names the linker will then resolve... Since each symbol is only once included in the whole set of files that makes an application, I don't quite see the difficulty. Why is it that much different from a normal dll/so you link against?

If you wanted to get RTTI for a particular type from a package, you could just manually call getProcAddress(<mangled name>) and use that pointer.

Willi

Reply by email

Willibald Krenn
to Marco van de Voort: In our previous episode, Willibald Krenn said: No it won't. Not all of the implementation…
No it won't. Not all of the implementation of a package needs to be in the .BPL equivalent. Neither is the case in Delphi. Seek for $weakpackage and read the packages wiki again

In words of Borland/Embac - "Unit files containing the {$WEAKPACKAGEUNIT ON} directive must not have global variables, initialization sections, or finalization sections." Which makes sense. So not putting something into the bpl comes at a cost.

Also, I don't see the benefit of trying to introduce packages to have each type defined only once within the project, except that all generic types (and descendants thereof) would be spread all-over again.

Show quoted text 8 lines
So in short, everything in the units that doesn't go into the DLL goes into the .DCP which is more or less a dcu archive if I understood it correctly So only the specializations used inside the code contained in the BPL (and maybe one or two that you could force to save duplication) are in the BPL. So in short, the problem is one that you create yourself by self-inflicting that every piece of code _must_ be in the BPL. That isn't the case.

Ok, so lets say one of my generic classes uses class variables (static fields). Duplicating the type in each package defeats the purpose of the package-concept to have one common type across all modules of a running application.

Say I have a generic TMyList<T> type with some class variable. Then, I use the specialization TMyList<TMyOtherClass> in two different packages that depend on the package where TMyList<T> was defined. As soon as TMyList<T> is put into the .dcp, it will be statically compiled into the two other packages - hence you end up with 2 "instances" of the same type, which leads to having 2 different versions of the class variable (and N in the general case). In my opinion this is not what packages are about. Packages are a means to transparently break your application in to modules. BTW: It would be intersting to know whether Delphi allows some sort of "type TMyNewList<T> = type TMyList<T>" definition which would create a new type with a different set of class variables.

Finally, I have to confess that I am absolutely clueless about the semantics of class variables in FPC's generics. Most probably FPC only shares class variables between all instances of the same "type mySpec = specialization TMyList<...>" type, which would give somewhat room for the .dcp implementation. But this is not the usual semantics of generics. It also is not the Delphi semantics of generics, I suppose. This is (C++) templates without header files.

Cheers,
Willi

Reply by email

Marco van de Voort
to Willibald Krenn

In our previous episode, Willibald Krenn said:

Show quoted text 9 lines
> No it won't. Not all of the implementation of a package needs to be in the > .BPL equivalent. Neither is the case in Delphi. > > Seek for $weakpackage and read the packages wiki again In words of Borland/Embac - "Unit files containing the {$WEAKPACKAGEUNIT ON} directive must not have global variables, initialization sections, or finalization sections." Which makes sense. So not putting something into the bpl comes at a cost.

No, it comes with limitations.

Also, I don't see the benefit of trying to introduce packages to have each type defined only once within the project, except that all generic types (and descendants thereof) would be spread all-over again.

That's where generics are special. The code is generated on the spot where they are specialized, not on the spot where they are defined.

If you want to avoid that for space reasons, specialize a few common cases in the BPL, or, if it is a system BPL, in a secondary BPL.

Show quoted text 13 lines
> So in short, everything in the units that doesn't go into the DLL goes into > the .DCP which is more or less a dcu archive if I understood it correctly > > So only the specializations used inside the code contained in the BPL (and > maybe one or two that you could force to save duplication) are in the BPL. > > So in short, the problem is one that you create yourself by self-inflicting > that every piece of code _must_ be in the BPL. That isn't the case. Ok, so lets say one of my generic classes uses class variables (static fields). Duplicating the type in each package defeats the purpose of the package-concept to have one common type across all modules of a running application.

No, since any specialization creates the actual types, and they all will have their respective static fields anyway? (since the static field can be of the variable type)

There are some languages/runtimes that have some damage control here (most notably C# which uses constraints to limit the definition to classes implementing a certain interface, and it is said to typically share specializations for such classes)

Show quoted text 7 lines
Say I have a generic TMyList<T> type with some class variable. Then, I use the specialization TMyList<TMyOtherClass> in two different packages that depend on the package where TMyList<T> was defined. As soon as TMyList<T> is put into the .dcp, it will be statically compiled into the two other packages - hence you end up with 2 "instances" of the same type, which leads to having 2 different versions of the class variable (and N in the general case).

Fully correct.

In my opinion this is not what packages are about.

Well, what can I say about that?

Packages are a means to transparently break your application in to modules.

True, the specialization is what generates the code AND THAT IS NOT IN THE UNITS IN THE PACKAGE! So the logic still holds.

BTW: It would be intersting to know whether Delphi allows some sort of "type TMyNewList<T> = type TMyList<T>" definition which would create a new type with a different set of class variables.

You can try, but I doubt it. The = type <x> functionality is mostly sleeping, in both FPC and Delphi.

Finally, I have to confess that I am absolutely clueless about the semantics of class variables in FPC's generics. Most probably FPC only shares class variables between all instances of the same "type mySpec = specialization TMyList<...>" type,

That's what I expect yes.

which would give somewhat room for the .dcp implementation. But this is not the usual semantics of generics. It also is not the Delphi semantics of generics, I suppose. This is (C++) templates without header files.

As far as I know, it is this way for any compiled language.

The only exception I know is C#'s constraints, but that is possibly nothing but a bit of damage control in a totally different environment. Still it might be possible for FPC too, but that is a totally different subject.

When I read up about the C# stuff I didn't know that much about generics yet, so if interested, I encourage you to do your own research. But don't get your hopes up too much.

Reply by email

Willibald Krenn
to Marco van de Voort
Show quoted text 8 lines
No, since any specialization creates the actual types, and they all will have their respective static fields anyway? (since the static field can be of the variable type) There are some languages/runtimes that have some damage control here (most notably C# which uses constraints to limit the definition to classes implementing a certain interface, and it is said to typically share specializations for such classes)

Played around with Delphi today, and it seems that class vars are somewhat broken on generic types. They work as expected (share common class value amongst all sameclass<sametype> instances) only in a unit scope, it seems. Which is a pitty.

However, Delphi won't allow you to do something like

TMyGenericBaseClass<T> = class
   public
       public function AddOp(a: T; b: T) : T;
end;
implementation
function TMyGenericBaseClass<T>.AddOp;
begin
   result := a + b;
end;

since the '+' operator is not defined on T. Delphi lets you constrain your type parameters. That said, I don't really understand why constraints like :integer, :TObject are not allowed. (:record, :TMyClass are perfectly fine.) So Delphi's generics are more on the C#/.NET side than on the C++ template side.

Show quoted text 5 lines
> Packages are a means to transparently break your application in > to modules. True, the specialization is what generates the code AND THAT IS NOT IN THE UNITS IN THE PACKAGE! So the logic still holds.

Uh, no need to shout. I understand what you are saying, however, I'd still prefer to have working class variables, rtti checks etc. even with generic classes and packages.

Show quoted text 6 lines
> BTW: It would be intersting to know whether Delphi allows > some sort of "type TMyNewList<T> = type TMyList<T>" definition which > would create a new type with a different set of class variables. You can try, but I doubt it. The = type <x> functionality is mostly sleeping, in both FPC and Delphi.

Tried it: not allowed.

The only exception I know is C#'s constraints, but that is possibly nothing but a bit of damage control in a totally different environment. Still it might be possible for FPC too, but that is a totally different subject.

Well, IIRC Eiffel, Java/Pizza, .NET, Delphi all support constraints on type parameters. .NET actually has quite good support for generics (Java is limited in that respect).

When I read up about the C# stuff I didn't know that much about generics yet, so if interested, I encourage you to do your own research. But don't get your hopes up too much.

Ok for the start I'll be looking at co/contravariance, and lambda functions ;-). Joke aside, I'll think about the .dcp idea and how this might work out with packages.

Cheers,
Willi

Reply by email

Marco van de Voort
to Willibald Krenn

In our previous episode, Willibald Krenn said:

Show quoted text 9 lines
> There are some languages/runtimes that have some damage control here (most > notably C# which uses constraints to limit the definition to classes > implementing a certain interface, and it is said to typically share > specializations for such classes) Played around with Delphi today, and it seems that class vars are somewhat broken on generic types. They work as expected (share common class value amongst all sameclass<sametype> instances) only in a unit scope, it seems. Which is a pitty.

To be honest, that is already more than I expected.

since the '+' operator is not defined on T.

Generic versions of Delphi have operator overloading? Or did I miss something here?

Delphi lets you constrain your type parameters. That said, I don't really understand why constraints like :integer, :TObject are not allowed.

Does C# actually allow that? I thought it only supported interfaces?

(:record, :TMyClass are perfectly fine.) So Delphi's generics are more on the C#/.NET side than on the C++ template side.

Well, when they were developed, Delphi.NET was just being canceled, so that is no suprise.

Uh, no need to shout. I understand what you are saying, however, I'd still prefer to have working class variables,

Personally I only am interested in the constraint for object types. Many generic container types operating on objects only improve typing, and thus are runtime empty.

Mapping them onto eachother makes .exe's and memory footprint smaller, and more importantly, might have an effect on caches.

The opposite constraint (that excludes inheritable types) could maybe be useful for optimizations.

rtti checks etc. even with generic classes and packages.

You'll have to explain that in more detail. I fail to see the connection.

Moreover, this is turning into a generics feature and wishlist discussion, while it was about packages.

> You can try, but I doubt it. The = type <x> functionality is mostly > sleeping, in both FPC and Delphi. Tried it: not allowed.

No surprise there.

Show quoted text 7 lines
> The only exception I know is C#'s constraints, but that is possibly nothing > but a bit of damage control in a totally different environment. Still it > might be possible for FPC too, but that is a totally different subject. Well, IIRC Eiffel, Java/Pizza, .NET, Delphi all support constraints on type parameters. .NET actually has quite good support for generics (Java is limited in that respect).

Java and .NET also is a JIT who can delay certain things till runtime, when all loaded parts form a single program over which the JIT has more or less a complete overview. IMHO interesting for ideas, but not for implementation.

Delphi has constraints, but they don't reach your goals. So maybe it is time to stop the comparison game, and describe how you think such features should work.

Ok for the start I'll be looking at co/contravariance, and lambda functions ;-). Joke aside, I'll think about the .dcp idea and how this might work out with packages.

Note that

.bpl : a DLL with some runtime stuff.

.dcp : everything else,
- the .ppu like information for everything in .BPL (since the .bpl/.exe split is arbitrary, the compiler has full control, so it must be in there)
- code that didn't go into the .bpl (weakpackaged, maybe even complete units, but also stuff to construct tables needed in the main program)
- everything not linkable, inline functions, generics etc.

Reply by email

Willibald Krenn
to Marco van de Voort
Show quoted text 6 lines
> Played around with Delphi today, and it seems that class vars are > somewhat broken on generic types. They work as expected (share common > class value amongst all sameclass<sametype> instances) only in a unit > scope, it seems. Which is a pitty. To be honest, that is already more than I expected.

Well, half working is still broken. :-\
Better not supported than half working, if you ask me.

BTW: I've read somewhere on the internet (don't know whether that's true) that C# supports static fields in a proper way: Even if there is only one code-path for all object-related types, static fields are different for each different instantiated type. Hence Stack<TObject> would have different static fields than any object based on Stack<derivedFromObject>.

Show quoted text 6 lines
> since the '+' operator is not defined on T. Generic versions of Delphi have operator overloading? Or did I miss something here?

Sorry, my bad. Compiler says not applicable.

> Delphi lets you constrain your type parameters. That said, I don't really > understand why constraints like :integer, :TObject are not allowed. Does C# actually allow that? I thought it only supported interfaces?

Well, you can use 'struct' (record in delphi), class, new (IIRC constructor in delphi), some base class, or some interface name, or some other generic parameter as constraint. Pretty much the same as in Delphi.

Show quoted text 6 lines
Personally I only am interested in the constraint for object types. Many generic container types operating on objects only improve typing, and thus are runtime empty. Mapping them onto eachother makes .exe's and memory footprint smaller, and more importantly, might have an effect on caches.

And would need only one implementation in a package. ;-) That said, there'd be still the need for different RTTI entries for different instantiations...

Show quoted text 6 lines
The opposite constraint (that excludes inheritable types) could maybe be useful for optimizations. > rtti checks etc. even with generic classes and packages. You'll have to explain that in more detail. I fail to see the connection.

I don't know whether it is still the case but there was a time the 'is' operator relied on RTTI. So as soon as you have two different RTTI entries for, e.g., TMyList<integer> (which could happen if you compile with packages) the operator needs some 'repair'. I don't know how Delphi handles this today and whether to repair it is a good idea.

This, btw, was one of the downsides that made MDI-Child-Form-plugins via dlls back in D5/6 days quite difficult: even if the object was, say, a form, the 'is' operator failed. I'd need to look into the FPC sources to see how FPC handles this situation.

Moreover, this is turning into a generics feature and wishlist discussion, while it was about packages.

Well, it's related. Since generics have to be supported by packages, it's necessary to discuss the approaches. What must not happen is that a program behaves differently when compiled with packages because of the way things are done.

Java and .NET also is a JIT who can delay certain things till runtime, when all loaded parts form a single program over which the JIT has more or less a complete overview. IMHO interesting for ideas, but not for implementation.

True, a JIT has additional runtime knowledge an will only construct the types that are really necessary.

Delphi has constraints, but they don't reach your goals. So maybe it is time to stop the comparison game, and describe how you think such features should work.

Well, actually Delphi generics come really close. AFAICT generics in Delphi work the way I described them in one of my first emails about the subject: Within the generic type you can only do operations on the generic value that you know (from the constraint) are allowed. So you can compile (syntax check) the generic type separately from the code that uses it. This would in turn be beneficial for packages, as, e.g., for object types you could use one common code path. When using primitive types, code needs to end up in the dcp, yes, but perhaps there is a way so that RTTI is shared? (And class vars are working.)

That said, if there is no sane way for class vars working on generic types, I'd rather give them up (for these types).

Cheers,
Willi

Reply by email

Florian Klaempfl
to Willibald Krenn
Show quoted text 5 lines
I don't know whether it is still the case but there was a time the 'is' operator relied on RTTI. So as soon as you have two different RTTI entries for, e.g., TMyList<integer> (which could happen if you compile with packages) the operator needs some 'repair'.
This is why FPC has specialize (to emphasis this): only class instances
having the same specialized generic type are considered being equal:
type
   TList1 = specialize TList<Longint>;
   TList2 = specialize TList<Longint>;
var
  l1a,l1b : TList1;
  l2 : TList2;

Only l1a and l1b are assignment compatible. This is like records or classes are handled in pascal: even records with exactly the same fields are not assignment compatible.

So generics in packages are a non issue for fpc: every package specializes the generics created by the units contained in the package as it is done currently by a program: the specialization and code generation for all generics specialized by a program and its units is done during compilation of the program. For packages, it is just done during package compilation.

Reply by email

Willibald Krenn
to Florian Klaempfl
Show quoted text 14 lines
This is why FPC has specialize (to emphasis this): only class instances having the same specialized generic type are considered being equal: type TList1 = specialize TList<Longint>; TList2 = specialize TList<Longint>; var l1a,l1b : TList1; l2 : TList2; Only l1a and l1b are assignment compatible. This is like records or classes are handled in pascal: even records with exactly the same fields are not assignment compatible

So, what you are saying is that FPC - with traditional Pascal syntax - only supports generics like this:

type
  TList1 = type TList<Longint>;

Hence, I really don't see any good reason for the new 'specialize' keyword as everyone familiar with Pascal/Delphi knows the semantics of the above declaration. OTOH 'specialize' is an additional (unfamiliar) keyword and has semantics totally unknown to the world. So why not take what's already in the language?

Show quoted text 6 lines
So generics in packages are a non issue for fpc: every package specializes the generics created by the units contained in the package as it is done currently by a program: the specialization and code generation for all generics specialized by a program and its units is done during compilation of the program. For packages, it is just done during package compilation.

Of course you can export TList1 from a package and consume the type in different other packages (which means we need a way of encoding). But you are right, since the type has been closed this would not pose a problem.

FPC's generics are, however, very different to all other implementations of generics that I know of. And I really(!) hope, that FPC does not do the C++ like duck-typing, which could give interesting error messages: think about using a package where you do not have the source, and getting an error message pointing to the unit in the .dcp. Hence, I cannot stress often enough that generics found in Delphi W32, .NET, Eiffel, Java... are NOT C++ templates. And you should emphasize this in http://www.freepascal.org/docs-html/ref/refse41.html#x93-1000008.1. The concept of generics found in all modern languages (except C++) does not come from C++ and - see C# 4.0/.NET - is quite advanced.

But enough about generics, back to packages: I'll start doing an implementation for the non-generic part first. Let's see how this goes. Since I need to read into fpc source (and do this in my spare time), don't expect any spectacular results soon. In case there are more people interested in implementing this, some branch in the repo would be needed - if I am the only one, I will do this locally on my disk.

Cheers,
Willi

GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 Euro/mtl.!* http://portal.gmx.net/de/go/dsl

Reply by email

Florian Klaempfl
to Willibald Krenn
Willibald Krenn wrote 20 lines
> > This is why FPC has specialize (to emphasis this): only class > instances having the same specialized generic type are considered > being equal: type TList1 = specialize TList<Longint>; TList2 = > specialize TList<Longint>; > > var l1a,l1b : TList1; l2 : TList2; > > Only l1a and l1b are assignment compatible. This is like records > or classes are handled in pascal: even records with exactly the > same fields are not assignment compatible So, what you are saying is that FPC - with traditional Pascal syntax - only supports generics like this: type TList1 = type TList<Longint>; Hence, I really don't see any good reason for the new 'specialize' keyword as everyone familiar with Pascal/Delphi knows the semantics of the above declaration.

I doubt this :)

OTOH 'specialize' is an additional (unfamiliar) keyword and has semantics totally unknown to the world. So why not take what's already in the language?

As I said, to emphasis that a new type is created, generic specialization is something really new to the language. The meaning of type ... = type ...; is imo very unclear.

FPC's generics are, however, very different to all other implementations of generics that I know of. And I really(!) hope, that FPC does not do the C++ like duck-typing, which could give

FPC works in this regard as C++ which is not nice but much more flexible being not only some type cast wrapper generator as in C# etc.

Show quoted text 7 lines
But enough about generics, back to packages: I'll start doing an implementation for the non-generic part first. Let's see how this goes. Since I need to read into fpc source (and do this in my spare time), don't expect any spectacular results soon. In case there are more people interested in implementing this, some branch in the repo would be needed - if I am the only one, I will do this locally on my disk.

Let us know if you've something working and regarding the branch: just tell me if you need one.

Reply by email

Willibald Krenn
to Florian Klaempfl
Show quoted text 7 lines
> OTOH 'specialize' is an additional > (unfamiliar) keyword and has semantics totally unknown to the world. > So why not take what's already in the language? As I said, to emphasis that a new type is created, generic specialization is something really new to the language. The meaning of type ... = type ...; is imo very unclear.

Well, it's the Delphi way of creating a new type rather than an alias.

Show quoted text 6 lines
> FPC's generics are, however, very different to all other > implementations of generics that I know of. And I really(!) hope, > that FPC does not do the C++ like duck-typing, which could give FPC works in this regard as C++ which is not nice but much more flexible being not only some type cast wrapper generator as in C# etc.

Well, you know my opinion. This is type-unsafe, C-style, poor-man's generics. You are asking for trouble by following that route.

And one last time - C#/.NET generics are not only some 'type cast wrapper': think about working static fields, co-/contravariance ... . Java generics, however, could be described as type cast wrapper generators. And everybody on earth knows that Java generics are broken.

Let us know if you've something working and regarding the branch: just tell me if you need one.

Ok, thanks!

Willi

GMX DSL SOMMER-SPECIAL: Surf & Phone Flat 16.000 für nur 19,99 Euro/mtl.!* http://portal.gmx.net/de/go/dsl

Reply by email

Florian Klaempfl
to Willibald Krenn
Willibald Krenn wrote 10 lines
>> OTOH 'specialize' is an additional (unfamiliar) keyword and has >> semantics totally unknown to the world. So why not take what's >> already in the language? > > As I said, to emphasis that a new type is created, generic > specialization is something really new to the language. The meaning > of type ... = type ...; is imo very unclear. Well, it's the Delphi way of creating a new type rather than an alias.

Since they are still assignment compatible, I don't consider it as a really new type.

Show quoted text 11 lines
>> FPC's generics are, however, very different to all other >> implementations of generics that I know of. And I really(!) >> hope, that FPC does not do the C++ like duck-typing, which could >> give > > FPC works in this regard as C++ which is not nice but much more > flexible being not only some type cast wrapper generator as in C# > etc. Well, you know my opinion. This is type-unsafe,

It is perfectly type safe.

C-style, poor-man's

I consider C# style generics as poor man's generics :)

generics.

Well, I consider them more powerful than others because the C# programming style (having only one core implementation) can be done also with C++ style templates, see e.g. the fgl unit of fpc.

You are asking for trouble by following that route.

Nothing is trouble free ;)

And one last time - C#/.NET generics are not only some 'type cast wrapper': think about working static fields, co-/contravariance ... .

Yes. But the principle remains the same.

Show quoted text 10 lines
Java generics, however, could be described as type cast wrapper generators. And everybody on earth knows that Java generics are broken. > Let us know if you've something working and regarding the branch: > just tell me if you need one. Ok, thanks! Willi

Reply by email

Sven Barth
to Willibald Krenn: So, what you are saying is that FPC - with traditional Pascal syntax - only supports…
Willibald Krenn wrote
But enough about generics, back to packages: I'll start doing an implementation for the non-generic part first. Let's see how this goes. Since I need to read into fpc source (and do this in my spare time), don't expect any spectacular results soon. In case there are more people interested in implementing this, some branch in the repo would be needed - if I am the only one, I will do this locally on my disk.

You might want to start compiler/pmodules.pp. There is already some code to parse "package" projects and some code that allows all symbols to be exported (this code also appears in ppumove, but only for Linux and DOS).

I've stumpled upon this code last week and tested it on a Linux system. Compiling a simple package with a single unit works if I use Win32 as target. A .dll (wrong file extension) is generated which exports all functions/procedures that are in the interface of my unit or the RTL units, but no variables are exported although the Win32 target supports this (tested before the package). Using Linux as a target results in an internal error and I've not yet found the time to investigate this.

Also "requires" sections aren't parsed yet.

In theory(!) it should be "rather" simple to implement shared cross platform packages (those that are loaded on app startup by the OS and not dynamically during the run).

Regards,
Sven

Reply by email

Dimitri Smits
----- "Sven Barth" wrote 29 lines
Am 13.09.2010 11:44, schrieb Willibald Krenn: > But enough about generics, back to packages: I'll start doing an implementation for the non-generic part first. Let's see how this goes. Since I need to read into fpc source (and do this in my spare time), don't expect any spectacular results soon. In case there are more people interested in implementing this, some branch in the repo would be needed - if I am the only one, I will do this locally on my disk. You might want to start compiler/pmodules.pp. There is already some code to parse "package" projects and some code that allows all symbols to be exported (this code also appears in ppumove, but only for Linux and DOS). I've stumpled upon this code last week and tested it on a Linux system. Compiling a simple package with a single unit works if I use Win32 as target. A .dll (wrong file extension) is generated which exports all functions/procedures that are in the interface of my unit or the RTL units, but no variables are exported although the Win32 target supports this (tested before the package). Using Linux as a target results in an internal error and I've not yet found the time to investigate this. Also "requires" sections aren't parsed yet.

how about "contains" sections?

Show quoted text 5 lines
In theory(!) it should be "rather" simple to implement shared cross platform packages (those that are loaded on app startup by the OS and not dynamically during the run).

that would require a change in sysinit, sysutils & system units as well, all types of linked-target modules (executable, shared lib, package) should "register" their moduleinfo ('hinstance' of the module, list of contained units' table entries => init, finit pointers) in startupcode for the module. shutdown code for the module should deregister that moduleinfo.

for somewhat of a breakdown, look at TLibModule, LoadPackage, UnloadPackage and related functions for inspiration:

http://docwiki.embarcadero.com/VCL/en/System.TLibModule http://docwiki.embarcadero.com/VCL/en/System.LibModuleList http://docwiki.embarcadero.com/VCL/en/System.RegisterModule http://docwiki.embarcadero.com/VCL/en/System.UnregisterModule http://docwiki.embarcadero.com/VCL/en/SysUtils.LoadPackage http://docwiki.embarcadero.com/VCL/en/SysUtils.UnloadPackage

and related
http://docwiki.embarcadero.com/VCL/XE/en/System.TModuleUnloadProc http://docwiki.embarcadero.com/VCL/XE/en/System.AddModuleUnloadProc http://docwiki.embarcadero.com/VCL/en/System.RemoveModuleUnloadProc http://docwiki.embarcadero.com/VCL/en/System.EnumModules http://docwiki.embarcadero.com/VCL/en/System.EnumResourceModules http://docwiki.embarcadero.com/VCL/en/SysUtils.InitializePackage http://docwiki.embarcadero.com/VCL/en/System.PackageInfoTable http://docwiki.embarcadero.com/VCL/en/System.UnitEntryTable http://docwiki.embarcadero.com/VCL/en/System.PackageUnitEntry

sysinit, system, sysutils:
the initialization of an executable/package/library needs to be completed with filling in the libmodule structure (needs to be generated as well) with the moduleid (portably!) and the pointer needs to be given to registermodule. In delphi a check occurs somewhere on all the "included" units of a package/dll/exe to see if there is a duplicate unit loaded.

loadpackage does nothing more than dlopen() of a file, and then the resulting recently added libmodules that were added are then initialized by init-ing their unittable entries.

conversely, unloadpackage finit's all those units and dlclose().

finalization of an executable/package/library unhooks the libmodule

addmoduleunloadproc/removemoduleunloadproc are invoked either by unloadpackage or by unregistermodule.

---

as said before, inspiration can be had from how they do it, but that doesn't mean fpc should do it that way. Especially in a crossplatform context, and more so cross-architecture, it is not a one-size fits all per se.

kind regards,
Dimitri Smits

Reply by email

Florian Klaempfl
to Sven Barth: You might want to start compiler/pmodules.pp. There is already some code to parse…
Sven Barth wrote 19 lines
Am 13.09.2010 11:44, schrieb Willibald Krenn: > But enough about generics, back to packages: I'll start doing an > implementation for the non-generic part first. Let's see how this > goes. Since I need to read into fpc source (and do this in my spare > time), don't expect any spectacular results soon. In case there are > more people interested in implementing this, some branch in the repo > would be needed - if I am the only one, I will do this locally on my > disk. You might want to start compiler/pmodules.pp. There is already some code to parse "package" projects and some code that allows all symbols to be exported (this code also appears in ppumove, but only for Linux and DOS). I've stumpled upon this code last week and tested it on a Linux system. Compiling a simple package with a single unit works if I use Win32 as target. A .dll (wrong file extension) is generated which exports all functions/procedures that are in the interface of my unit or the RTL units, but no variables are exported although the Win32 target supports this (tested before the package).

IIRC this works not properly and is one of the first things needs to be fixed.

Reply by email

Willibald Krenn
to Florian Klaempfl: Since they are still assignment compatible, I don't consider it as a really new type. It…
Show quoted text 5 lines
> Well, it's the Delphi way of creating a new type rather than an > alias. Since they are still assignment compatible, I don't consider it as a really new type.

Are you sure they are assignment compatible? I thought the whole point of the type A = type B was to make a new type, not an alias.

> Well, you know my opinion. This is type-unsafe, It is perfectly type safe.

Well. FPC checks types when specializing the template and not when "compiling" it.

Well, I consider them more powerful than others because the C# programming style (having only one core implementation) can be done also with C++ style templates, see e.g. the fgl unit of fpc.

What do you mean by one core implementation? .NET generates one implementation for the class path, and different ones for value types.

But ok, we disagree on that matter.

> And one last time - C#/.NET generics are not only some 'type cast > wrapper': think about working static fields, co-/contravariance ... . Yes. But the principle remains the same.

The semantics are different. Maybe not by very much, but still quite different.

Cheers,
Willi

Achtung Sicherheitswarnung: GMX warnt vor Phishing-Attacken! http://portal.gmx.net/de/go/sicherheitspaket

Reply by email

Sven Barth
to Dimitri Smits: how about "contains" sections? that would require a change in sysinit, sysutils & system…
Dimitri Smits wrote 35 lines
----- "Sven Barth" schreef: > Am 13.09.2010 11:44, schrieb Willibald Krenn: >> But enough about generics, back to packages: I'll start doing an > implementation for the non-generic part first. Let's see how this > goes. Since I need to read into fpc source (and do this in my spare > time), don't expect any spectacular results soon. In case there are > more people interested in implementing this, some branch in the repo > would be needed - if I am the only one, I will do this locally on my > disk. > > You might want to start compiler/pmodules.pp. There is already some > code > to parse "package" projects and some code that allows all symbols to > be > exported (this code also appears in ppumove, but only for Linux and > DOS). > > I've stumpled upon this code last week and tested it on a Linux > system. > Compiling a simple package with a single unit works if I use Win32 as > > target. A .dll (wrong file extension) is generated which exports all > functions/procedures that are in the interface of my unit or the RTL > units, but no variables are exported although the Win32 target > supports > this (tested before the package). Using Linux as a target results in > an > internal error and I've not yet found the time to investigate this. > > Also "requires" sections aren't parsed yet. how about "contains" sections?

"contains" works, because that is the only section besides "requires" that a package might contain (no "uses" allowed there).

Show quoted text 40 lines
> In theory(!) it should be "rather" simple to implement shared cross > platform packages (those that are loaded on app startup by the OS and > > not dynamically during the run). > that would require a change in sysinit, sysutils& system units as well, all types of linked-target modules (executable, shared lib, package) should "register" their moduleinfo ('hinstance' of the module, list of contained units' table entries => init, finit pointers) in startupcode for the module. shutdown code for the module should deregister that moduleinfo. for somewhat of a breakdown, look at TLibModule, LoadPackage, UnloadPackage and related functions for inspiration: http://docwiki.embarcadero.com/VCL/en/System.TLibModule http://docwiki.embarcadero.com/VCL/en/System.LibModuleList http://docwiki.embarcadero.com/VCL/en/System.RegisterModule http://docwiki.embarcadero.com/VCL/en/System.UnregisterModule http://docwiki.embarcadero.com/VCL/en/SysUtils.LoadPackage http://docwiki.embarcadero.com/VCL/en/SysUtils.UnloadPackage and related http://docwiki.embarcadero.com/VCL/XE/en/System.TModuleUnloadProc http://docwiki.embarcadero.com/VCL/XE/en/System.AddModuleUnloadProc http://docwiki.embarcadero.com/VCL/en/System.RemoveModuleUnloadProc http://docwiki.embarcadero.com/VCL/en/System.EnumModules http://docwiki.embarcadero.com/VCL/en/System.EnumResourceModules http://docwiki.embarcadero.com/VCL/en/SysUtils.InitializePackage http://docwiki.embarcadero.com/VCL/en/System.PackageInfoTable http://docwiki.embarcadero.com/VCL/en/System.UnitEntryTable http://docwiki.embarcadero.com/VCL/en/System.PackageUnitEntry sysinit, system, sysutils: the initialization of an executable/package/library needs to be completed with filling in the libmodule structure (needs to be generated as well) with the moduleid (portably!) and the pointer needs to be given to registermodule. In delphi a check occurs somewhere on all the "included" units of a package/dll/exe to see if there is a duplicate unit loaded. loadpackage does nothing more than dlopen() of a file, and then the resulting recently added libmodules that were added are then initialized by init-ing their unittable entries. conversely, unloadpackage finit's all those units and dlclose(). finalization of an executable/package/library unhooks the libmodule addmoduleunloadproc/removemoduleunloadproc are invoked either by unloadpackage or by unregistermodule.

That's why I emphasized "in theory" and "rather" ^^

as said before, inspiration can be had from how they do it, but that doesn't mean fpc should do it that way. Especially in a crossplatform context, and more so cross-architecture, it is not a one-size fits all per se.

Basically the package system needs the following:

- The ability to import/export functions, procedures AND variables from binaries (although export from shared library only should be sufficient). This works on Windows, but on Linux I had problems.
- The ability to declare init and finit procedures for shared images. This works on Windows with the entry point and on Linux with special symbols. I don't know about the other platforms.
- The ability to add the init/finit entries (which call the unit initialization/finalization sections) uniquely to the shared RTL and execute them. This is of yet a todo as it means a bit of work in the RTL.

The first two points must be provided by the platform/OS while the third one is defined by us (at best as the same for all platforms).

What would you do different/better then the Delphi developers when implementing such a package system in a crossplatform way? I can't imagine currently what should be done additonally, but that might be because I don't use every feature that FPC provides. So please share your ideas. :)

Regards,
Sven

Reply by email

Florian Klaempfl
to Willibald Krenn: Are you sure they are assignment compatible? I thought the whole point of the type A =…
Willibald Krenn wrote 8 lines
>> Well, it's the Delphi way of creating a new type rather than an >> alias. > > Since they are still assignment compatible, I don't consider it as > a really new type. Are you sure they are assignment compatible?

I don't have a delphi here, but I'am pretty sure, yes.

I thought the whole point of the type A = type B was to make a new type, not an alias.

Well, the point is to be able to overload procedures/functions. They are no more equal but compatible.

Reply by email

Dimitri Smits
----- "Sven Barth" wrote 32 lines
Am 13.09.2010 14:46, schrieb Dimitri Smits: > as said before, inspiration can be had from how they do it, but that doesn't mean fpc should do it that way. Especially in a crossplatform context, and more so cross-architecture, it is not a one-size fits all per se. Basically the package system needs the following: - The ability to import/export functions, procedures AND variables from binaries (although export from shared library only should be sufficient). This works on Windows, but on Linux I had problems. - The ability to declare init and finit procedures for shared images. This works on Windows with the entry point and on Linux with special symbols. I don't know about the other platforms. - The ability to add the init/finit entries (which call the unit initialization/finalization sections) uniquely to the shared RTL and execute them. This is of yet a todo as it means a bit of work in the RTL. The first two points must be provided by the platform/OS while the third one is defined by us (at best as the same for all platforms). What would you do different/better then the Delphi developers when implementing such a package system in a crossplatform way? I can't imagine currently what should be done additonally, but that might be because I don't use every feature that FPC provides. So please share your ideas. :)

a few "cleanups" and "improvements" I'd sneak in are due to the fact that Delphi comes as a whole: VCL and compiler are distributed. Building for a version is building that version.

FPC and it's close companion Lazarus are not like that. Compiler is released a few times a year (?), IDE and visual componentset are separate. There is not really a maximum requirement for what compiler you use to build the IDE and components. There is sometimes a minimum version requirement.

DLL-hell is bigger, I know. However, take for instance LCL 1.0. (LCL-win32-1.0_fpc2.4.fpl ?) The requires could take just LCL-win32-1.0 as package name and "rtl".

Another thing I'd place inside the packageinfo is the compiler with which the package was build (for runtime checking). I do not believe that a version like 2.4.2 should contain other EABI/RTTI or even as worse: other interfaces. They are bugfixes (?).

So 2.4.0 can work with 2.4.2 packages.

Also, some packageinfo+unittableentry stuff is less than optimal in alignment with the shortstrings iso pchar? Something I've found bizarre with Delphi 7 RTTI in typeinfo as well.

Every unit has a local "tunitinfo" block generated:

tunitinfo=record
  ...
  unitname: shortstring;
end;
punitinfo=^tunitinfo;
tunittableentry=record
  init, finit: pointer;
  unitinfo: Punitinfo;
  typecount: cardinal;
  unittypes: pptypeinfo; // array[0..typecount-1] of ptypeinfo for all the types in interface & implementation
end;

Every package/exe(!)/library(!) has a packageinfo table with all the contained (implicitly/explicitly) units in order (like now) of dependencies containing a link like punittableentry. Yes, the executable is a package too!

Another thing is what to do with weak packages or what with "if you include this unit first in your project, then it will be initialized after system... for instance a memorymanager-swap"? Packages and the used/described register-init order implies that when you use a memory manager like that, a lot of memory can have been allocated during "init" of units using the default manager before a swap happens.

one can mediate that a bit if one can indicate the order of "build with runtimepackages" and if "rtl" contains no units that allocate memory (direct/indirect) in their init sections.

So, working further on the "register packages first, then initialize in order" doctrine, one can make the above records and especially the unittableentries and/or table as a doubly linked list. But that is just an idea.

I'm gonna stop here, because packages entail ofcourse a lot more than RTTI or dll generation/ini/fini. This is just the top of the iceberg.

kind regards
Dimitri Smits

Reply by email

Willibald Krenn
to Sven Barth: "contains" works, because that is the only section besides "requires" that a package…

[lots of useful information snipped]

- The ability to import/export functions, procedures AND variables from binaries (although export from shared library only should be sufficient). This works on Windows, but on Linux I had problems.

Packages also export/import RTTI, ClassVars, types, all the initialization/finalization code for each unit
(@ ..), compiler magic functions, and
some other stuff like
@
@Package1@@PackageUnload$qqrv
@Package1@@PackageLoad$qqrv
@Package1@@GetPackageInfoTable$qqrv
Finalize
Initialize
@GetPackageInfoTable

[...]

What would you do different/better then the Delphi developers when implementing such a package system in a crossplatform way?

Packages worked quite well under Delphi and Kylix. :)

Willi

Reply by email

Dimitri Smits
to Dimitri Smits: a few "cleanups" and "improvements" I'd sneak in are due to the fact that Delphi comes as…

appareantly this one didn't get through

----- "Sven Barth" wrote 32 lines
Am 13.09.2010 14:46, schrieb Dimitri Smits: > as said before, inspiration can be had from how they do it, but that doesn't mean fpc should do it that way. Especially in a crossplatform context, and more so cross-architecture, it is not a one-size fits all per se. Basically the package system needs the following: - The ability to import/export functions, procedures AND variables from binaries (although export from shared library only should be sufficient). This works on Windows, but on Linux I had problems. - The ability to declare init and finit procedures for shared images. This works on Windows with the entry point and on Linux with special symbols. I don't know about the other platforms. - The ability to add the init/finit entries (which call the unit initialization/finalization sections) uniquely to the shared RTL and execute them. This is of yet a todo as it means a bit of work in the RTL. The first two points must be provided by the platform/OS while the third one is defined by us (at best as the same for all platforms). What would you do different/better then the Delphi developers when implementing such a package system in a crossplatform way? I can't imagine currently what should be done additonally, but that might be because I don't use every feature that FPC provides. So please share your ideas. :)

a few "cleanups" and "improvements" I'd sneak in are due to the fact that Delphi comes as a whole: VCL and compiler are distributed. Building for a version is building that version.

FPC and it's close companion Lazarus are not like that. Compiler is released a few times a year (?), IDE and visual componentset are separate. There is not really a maximum requirement for what compiler you use to build the IDE and components. There is sometimes a minimum version requirement.

DLL-hell is bigger, I know. However, take for instance LCL 1.0. (LCL-win32-1.0_fpc2.4.fpl ?) The requires could take just LCL-win32-1.0 as package name and "rtl".

Another thing I'd place inside the packageinfo is the compiler with which the package was build (for runtime checking). I do not believe that a version like 2.4.2 should contain other EABI/RTTI or even as worse: other interfaces. They are bugfixes (?).

So 2.4.0 can work with 2.4.2 packages.

Also, some packageinfo+unittableentry stuff is less than optimal in alignment with the shortstrings iso pchar? Something I've found bizarre with Delphi 7 RTTI in typeinfo as well.

Every unit has a local "tunitinfo" block generated:

tunitinfo=record
  ...
  unitname: shortstring;
end;
punitinfo=^tunitinfo;
tunittableentry=record
  init, finit: pointer;
  unitinfo: Punitinfo;
  typecount: cardinal;
  unittypes: pptypeinfo; // array[0..typecount-1] of ptypeinfo for all the types in interface & implementation
end;

Every package/exe(!)/library(!) has a packageinfo table with all the contained (implicitly/explicitly) units in order (like now) of dependencies containing a link like punittableentry. Yes, the executable is a package too!

Another thing is what to do with weak packages or what with "if you include this unit first in your project, then it will be initialized after system... for instance a memorymanager-swap"? Packages and the used/described register-init order implies that when you use a memory manager like that, a lot of memory can have been allocated during "init" of units using the default manager before a swap happens.

one can mediate that a bit if one can indicate the order of "build with runtimepackages" and if "rtl" contains no units that allocate memory (direct/indirect) in their init sections.

So, working further on the "register packages first, then initialize in order" doctrine, one can make the above records and especially the unittableentries and/or table as a doubly linked list. But that is just an idea.

I'm gonna stop here, because packages entail ofcourse a lot more than RTTI or dll generation/ini/fini. This is just the top of the iceberg.

kind regards
Dimitri Smits

Reply by email

Florian Klaempfl
to Willibald Krenn: [lots of useful information snipped] Packages also export/import RTTI, ClassVars, types,…
Willibald Krenn wrote 17 lines
[lots of useful information snipped] > - The ability to import/export functions, procedures AND variables > from binaries (although export from shared library only should be > sufficient). This works on Windows, but on Linux I had problems. Packages also export/import RTTI, ClassVars, types, all the initialization/finalization code for each unit (@ ..), compiler magic functions, and some other stuff like @ @Package1@@PackageUnload$qqrv @Package1@@PackageLoad$qqrv @Package1@@GetPackageInfoTable$qqrv Finalize Initialize @GetPackageInfoTable

Since this is also exported by static libs, the main issue is to create proper exports in shared libs (including dlls).

Reply by email

Leonardo M. Ramé
to Florian Klaempfl

Sorry Florian, the error happened trying to compile some auto-generated code with wrong property assignments, with overloaded setters. It's fixed now.

Leonardo M. Ramé
http://leonardorame.blogspot.com

Florian Klaempfl wrote 17 lines
From: Florian Klaempfl Subject: Re: [fpc-devel] Fatal: Internal error 200111022 To: "FPC developers' list" Date: Tuesday, September 14, 2010, 12:04 PM Am 14.09.2010 01:13, schrieb Leonardo M. Ramé: > Hi, does anyone knows what the error "Fatal: Internal error 200111022" means?. > Something happened which should not happen ;) Looks like an error with overloading. Can you create a cut down example? _______________________________________________ fpc-devel maillist  -  http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Florian Klämpfl
to Leonardo M. Ramé
Leonardo M. Ramé wrote
Sorry Florian, the error happened trying to compile some auto-generated code with wrong property assignments, with overloaded setters. It's fixed now.

In FPC or your code?

Show quoted text 31 lines
Leonardo M. Ramé http://leonardorame.blogspot.com --- On Tue, 9/14/10, Florian Klaempfl wrote: > From: Florian Klaempfl > Subject: Re: [fpc-devel] Fatal: Internal error 200111022 > To: "FPC developers' list" > Date: Tuesday, September 14, 2010, 12:04 PM > Am 14.09.2010 01:13, schrieb Leonardo > M. Ramé: >> Hi, does anyone knows what the error "Fatal: Internal > error 200111022" means?. >> > > Something happened which should not happen ;) Looks like an > error with > overloading. Can you create a cut down example? > _______________________________________________ > 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

Leonardo M. Ramé
to Florian Klämpfl

My code, don't worry.

Leonardo M. Ramé
http://leonardorame.blogspot.com

Florian Klämpfl wrote 52 lines
From: Florian Klämpfl Subject: Re: [fpc-devel] Fatal: Internal error 200111022 To: "FPC developers' list" Date: Tuesday, September 14, 2010, 4:01 PM Am 14.09.2010 19:39, schrieb Leonardo M. Ramé: > Sorry Florian, the error happened trying to compile some auto-generated code with wrong property assignments, with overloaded setters. It's fixed now. In FPC or your code? > > Leonardo M. Ramé > http://leonardorame.blogspot.com > > > --- On Tue, 9/14/10, Florian Klaempfl wrote: > >> From: Florian Klaempfl >> Subject: Re: [fpc-devel] Fatal: Internal error 200111022 >> To: "FPC developers' list" >> Date: Tuesday, September 14, 2010, 12:04 PM >> Am 14.09.2010 01:13, schrieb Leonardo >> M. Ramé: >>> Hi, does anyone knows what the error "Fatal: Internal >> error 200111022" means?. >>> >> >> Something happened which should not happen ;) Looks like an >> error with >> overloading. Can you create a cut down example? >> _______________________________________________ >> fpc-devel maillist  -  >> http://lists.freepascal.org/mailman/listinfo/fpc-devel >> > > >        > _______________________________________________ > 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

Sven Barth
to Willibald Krenn: [lots of useful information snipped] Packages also export/import RTTI, ClassVars, types,…
Willibald Krenn wrote 17 lines
[lots of useful information snipped] > - The ability to import/export functions, procedures AND variables > from binaries (although export from shared library only should be > sufficient). This works on Windows, but on Linux I had problems. Packages also export/import RTTI, ClassVars, types, all the initialization/finalization code for each unit (@ ..), compiler magic functions, and some other stuff like @ @Package1@@PackageUnload$qqrv @Package1@@PackageLoad$qqrv @Package1@@GetPackageInfoTable$qqrv Finalize Initialize @GetPackageInfoTable

Bascially everything that a Package exports is either a function/procedure or a variable. But currently the package code of FPC only exports functions and procedures, but no variables, so you miss the important variables of the RTL which are needed to generate a working package version of the RTL.

Regards,
Sven

Reply by email

Leonardo M. Ramé
to Florian Klämpfl: Well, I worry because no code to compile should be able to trigger an internal error.

I understand. Sadly I can't reproduce the error anymore, my code was fixed yesterday, if I can get the broken code again I'll send it to you.

Leonardo M. Ramé
http://leonardorame.blogspot.com

Florian Klämpfl wrote 15 lines
From: Florian Klämpfl Subject: Re: [fpc-devel] Fatal: Internal error 200111022 To: "FPC developers' list" Date: Tuesday, September 14, 2010, 4:32 PM Am 14.09.2010 21:31, schrieb Leonardo M. Ramé: > My code, don't worry. Well, I worry because no code to compile should be able to trigger an internal error. _______________________________________________ fpc-devel maillist  -  http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Paulo Costa
to Florian Klaempfl: I don't have a delphi here, but I'am pretty sure, yes. Well, the point is to be able to…
Florian Klaempfl wrote 11 lines
Am 13.09.2010 14:51, schrieb Willibald Krenn: > >>> Well, it's the Delphi way of creating a new type rather than an >>> alias. >> >> Since they are still assignment compatible, I don't consider it as >> a really new type. > > Are you sure they are assignment compatible? I don't have a delphi here, but I'am pretty sure, yes.

It works that way.

The following snippet compiles and gives the expected result in D7

type TMyInteger = type Integer;
procedure TForm1.FormCreate(Sender: TObject);
var my: TMyInteger;
     notmy: integer;
begin
   my := 10;
   notmy := my;
   showmessage(inttostr(notmy));
   showmessage(inttostr(my));
end;

Paulo Costa

Reply by email