Markus Gerwinski wrote:
Frank Heckenbach wrote:
I'd consider it perhaps a misfeature, but I think it will keep working, as long as you use explicit linker names (as you do), and take care of the parameter list ("Self" last, in contrast to BP where it's first, no difference in the example).
...?
Let me get this straight: If I defined a method like this:
tFoo = object Procedure bar ( baz: cinteger ); attribute ( name = 'foo_bar' ); end (* tFoo *);
and linked it from a C library, would the header then be
external void foo_bar ( int baz, void *self );
or
external void foo_bar ( void *self, int baz );?
I'm only asking because I've been using the latter one for years, and it worked fine.
Sorry, I mixed it up in the paragraph above. With GPC it's first, with BP it's last.
So if tFooFunc was a "method" type with a parameter list, what would be the correct declaration?
tFooFunc = Procedure ( aParam: integer; aSelf: pTestObj );
or
tFooFunc = Procedure ( aSelf: pTestObj; aParam: integer );?
Procedure tTestObj.Foo ( aParam: integer; bParam: Real );
=>
tFooFunc = Procedure ( var Self: tTestObj; aParam: integer; bParam: Real );
(i.e., Self first, then method parameters in order).
For a compiler-implemented solution, polymorphy would also be an issue, and AFAICS, the compiler would need to emit such a wrapper routine automatically then. That might not be too difficult per se (just some work to do ...), but the important question is, when and where to emit such wrappers (looks a bit like the C++ template problems). We could emit one on each usage, at the danger of emitting the same one several times (might even be in different units). Or emit one for each virtual method, at the danger of emitting some (often many) that aren't used at all. Of course, it's not a huge issue (just a few bytes per routine), but since a manual solution is available, I'd first wonder if the effort is justified for a feature that might not be used all that often ...
True. You've halfway convinced me to stick with the wrappers; I'm not sure if the flaws I'd catch by using method variables (syntax-approved or not) wouldn't more than outweigh their possible benefits. At least with the wrappers, I have a well-defined and most flexible way of handling "method" vars, and the overhead is, though sometimes annoying, acceptable altogether. I'll have to sleep over it.
OK. BTW, the wrapper way is type-safe, i.e. the compiler will find any parameter list mismatches, and you don't have to worry about the placement of Self etc. (In fact, in a manual wrapper, you can put Self anywhere you like.) So it would probably even work with BP and other compilers without changes, though I didn't test it. With the type-cast and linker-name versions, the compiler can't check matching parameter lists.
Frank