Another problem, also reported on the macpascal mailing list and reproduced by the following program:
[G5:gcc/p/test] adriaan% cat avo12.pas program avo12;
type Str255 = record sLength: Byte; sChars: packed array[1..255] of char; end;
function StringToStr255 ( const s: String ) = Result : Str255; begin Result.sLength := Min( Length( s ), 255 ); if Result.sLength > 0 then begin Result.sChars[1..Result.sLength] := s[1..Result.sLength]; end; end;
procedure DrawString1( const s: Str255); external name 'DrawString'; procedure DrawString2( protected var s: Str255); external name 'DrawString';
begin DrawString1( StringToStr255( 'Hello')); {OK} DrawString2( StringToStr255( 'Hello')) {Error: reference expected, value given} end.
[G5:gcc/p/test] adriaan% gpc avo12.pas avo12.pas: In main program: avo12.pas:19: error: reference expected, value given
In gpc-20030830, this was no problem, but now it is no longer allowed, which is quite inconvenient. In the GPC interfaces for Mac OS X, we use the external declaration form with a "protected var" because (according to the gc docs) the "const" declaration form doesn't guarantuee that the parameter is passed by reference, which is an ABI requirement.
Regards,
Adriaan van Os
On 28 Feb 2005 at 15:14, Adriaan van Os wrote:
Another problem, also reported on the macpascal mailing list and reproduced by the following program:
[G5:gcc/p/test] adriaan% cat avo12.pas program avo12;
type Str255 = record sLength: Byte; sChars: packed array[1..255] of char; end;
function StringToStr255 ( const s: String ) = Result : Str255; begin Result.sLength := Min( Length( s ), 255 ); if Result.sLength > 0 then begin Result.sChars[1..Result.sLength] := s[1..Result.sLength]; end; end;
procedure DrawString1( const s: Str255); external name 'DrawString'; procedure DrawString2( protected var s: Str255); external name 'DrawString';
begin DrawString1( StringToStr255( 'Hello')); {OK} DrawString2( StringToStr255( 'Hello')) {Error: reference expected, value given} end.
[...]
Don't know much about EP - but I would have thought that the compiler is correct to reject the call to DrawString2. "Hello" is not a variable (protected or not).
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Adriaan van Os wrote:
Another problem, also reported on the macpascal mailing list and reproduced by the following program:
[G5:gcc/p/test] adriaan% cat avo12.pas program avo12;
type Str255 = record sLength: Byte; sChars: packed array[1..255] of char; end;
function StringToStr255 ( const s: String ) = Result : Str255; begin Result.sLength := Min( Length( s ), 255 ); if Result.sLength > 0 then begin Result.sChars[1..Result.sLength] := s[1..Result.sLength]; end; end;
procedure DrawString1( const s: Str255); external name 'DrawString'; procedure DrawString2( protected var s: Str255); external name 'DrawString';
begin DrawString1( StringToStr255( 'Hello')); {OK} DrawString2( StringToStr255( 'Hello')) {Error: reference expected, value given} end.
[G5:gcc/p/test] adriaan% gpc avo12.pas avo12.pas: In main program: avo12.pas:19: error: reference expected, value given
In gpc-20030830, this was no problem,
Then it was a bug in 20030830. `protected var' clearly requires a reference.
but now it is no longer allowed, which is quite inconvenient. In the GPC interfaces for Mac OS X, we use the external declaration form with a "protected var" because (according to the gc docs) the "const" declaration form doesn't guarantuee that the parameter is passed by reference, which is an ABI requirement.
In general it doesn't. This particular type is currently passed by reference (as `const'), so for a temporary work-around (until GPC has short strings) it may be acceptable.
But actually I think you have a problem here. If you need a reference in the call, and only have a string value, you usually need a variable to assign it to. I know this might be quite uncomfortable to do in each call, but anything else seems rather fragile. You might want to consider writing wrapper routines (that accept string values and pass references).
Frank
Frank Heckenbach wrote:
In general it doesn't. This particular type is currently passed by reference (as `const'), so for a temporary work-around (until GPC has short strings) it may be acceptable.
How do I know which types are or are not currently passed by reference ?
But actually I think you have a problem here. If you need a reference in the call, and only have a string value, you usually need a variable to assign it to. I know this might be quite uncomfortable to do in each call, but anything else seems rather fragile.
Whether it is "fragile" or not, is not the issue, Peter, Gale and I have to change the interfaces with each version of GPC anyway. The question each time is - can it be done at all ?
You might want to consider writing wrapper routines (that accept string values and pass references).
When I look out of the window, I see a long row of programmers, all volunteering to write wrappers for 268 units with 245991 lines of declarations.
Regards,
Adriaan van Os
On 28 Feb 2005 at 18:55, Adriaan van Os wrote:
[...]
You might want to consider writing wrapper routines (that accept string values and pass references).
When I look out of the window, I see a long row of programmers, all volunteering to write wrappers for 268 units with 245991 lines of declarations.
I think that this kind of sarcasm is wholly misplaced. If what you want to say is that the suggested solution is not practical for you, then that can be said in a nicer way. It is not as if anyone is paying Frank or Waldek for the work they do on the compiler.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Adriaan van Os wrote:
Whether it is "fragile" or not, is not the issue, Peter, Gale and I have to change the interfaces with each version of GPC anyway. The question each time is - can it be done at all ?
You might want to consider writing wrapper routines (that accept string values and pass references).
When I look out of the window, I see a long row of programmers, all volunteering to write wrappers for 268 units with 245991 lines of declarations.
I am somewhat suprised that you do that by hand. I have met similar problems several times and the anwser was always the same: write a program which will generate the code you need. Sure, I had much smaller problems (tens to thoused routnes), but IMHO larger scale only increases advantage of automatic method.
You need machine readable _logical_ description of your interface and a set of rules that map logical description to Pascal code. AFAICS the complexity is basicaly in how many different rules you need and what condition you use to trigger rules.
By the way: I belive that also for other interfaces (W32 API, Open GL, etc) we should have a "database" and a generator program.
I wrote:
Adriaan van Os wrote:
Whether it is "fragile" or not, is not the issue, Peter, Gale and I have to change the interfaces with each version of GPC anyway. The question each time is - can it be done at all ?
You might want to consider writing wrapper routines (that accept string values and pass references).
When I look out of the window, I see a long row of programmers, all volunteering to write wrappers for 268 units with 245991 lines of declarations.
I am somewhat suprised that you do that by hand. I have met similar problems several times and the anwser was always the same: write a program which will generate the code you need. Sure, I had much smaller problems (tens to thoused routnes), but IMHO larger scale only increases advantage of automatic method.
You need machine readable _logical_ description of your interface and a set of rules that map logical description to Pascal code. AFAICS the complexity is basicaly in how many different rules you need and what condition you use to trigger rules.
By the way: I belive that also for other interfaces (W32 API, Open GL, etc) we should have a "database" and a generator program.
I have looked at Apple interfeces and I see that you use a conversion script. It looks that the conversion is regex-driven. I think that with some extra effort you can actually parse function and procedure declarations. IMHO generating wrappers is of order 300 lines od code, so why bragging about 245991 lines. By the way, most seem to be comments, my count shows about 11000 routines.
On 28 Feb 2005 at 21:53, Waldek Hebisch wrote:
[...]
You need machine readable _logical_ description of your interface and a set of rules that map logical description to Pascal code. AFAICS the complexity is basicaly in how many different rules you need and what condition you use to trigger rules.
By the way: I belive that also for other interfaces (W32 API, Open GL, etc) we should have a "database" and a generator program.
The FPC guys have a program called "h2pas" which does that. Perhaps it can be adapted?
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Adriaan van Os wrote:
Frank Heckenbach wrote:
In general it doesn't. This particular type is currently passed by reference (as `const'), so for a temporary work-around (until GPC has short strings) it may be acceptable.
How do I know which types are or are not currently passed by reference ?
But actually I think you have a problem here. If you need a reference in the call, and only have a string value, you usually need a variable to assign it to. I know this might be quite uncomfortable to do in each call, but anything else seems rather fragile.
Whether it is "fragile" or not, is not the issue, Peter, Gale and I have to change the interfaces with each version of GPC anyway. The question each time is - can it be done at all ?
Well, then, relying on a larger array `const' parameter being passed by reference seems a bit more stable than relying on EP violations.
You might want to consider writing wrapper routines (that accept string values and pass references).
When I look out of the window, I see a long row of programmers, all volunteering to write wrappers for 268 units with 245991 lines of declarations.
These numbers are quite pointless, as I suppose not each line contains such a problematic declaration. (And we didn't write the Mac ABI, BTW.)
Frank
You might want to consider writing wrapper routines (that accept string values and pass references).
When I look out of the window, I see a long row of programmers, all volunteering to write wrappers for 268 units with 245991 lines of declarations.
Ignoring Adriaan's misplaced sarcasm, it is not practical to write wrappers for interface functions like this. Interface functions are by definition interfaces on to existing routines, and have no code associated with them (even the initialization code required by GPC causes us problems). Not upgrading GPC would be a preferable solution to writing wrappers around all these routines with all the code changes and implementation code issues that would require.
At 10:10 PM +0100 28/2/05, Frank Heckenbach wrote:
These numbers are quite pointless, as I suppose not each line contains such a problematic declaration. (And we didn't write the Mac ABI, BTW.)
You're quite right, and this discussion is pointless for that reason. Despite the claims in GPC to the contrary, "const" array parameters must be passed by reference according to the ABI anyway, and there is no way for the compiler to optimize it out since in these cases it can never have any access to the code behind the declaration since it is in the system.
So the net result of this change is that we can stop using the "protected var" parameters and go back to using the "const" parameters like (which is what Metrowerks uses anyway) and we can all be happy as long as no one reads the documentation line that says the "const" might not be passed by reference.
Adriaan/Gale - I'll sort out converting the "protected var" parameters back to "const" parameters when I get a chance (remind me if I haven't done it in a couple weeks or you need it sooner).
Enjoy, Peter.
Peter N Lewis wroteL
You might want to consider writing wrapper routines (that accept string values and pass references).
Ignoring Adriaan's misplaced sarcasm, it is not practical to write wrappers for interface functions like this. Interface functions are by definition interfaces on to existing routines, and have no code associated with them (even the initialization code required by GPC causes us problems). Not upgrading GPC would be a preferable solution to writing wrappers around all these routines with all the code changes and implementation code issues that would require.
Could you elaborate what problems wrappers cause? I can see that generating wrappers takes some effort and they cause some space and time overhead at runtime. So I would avoid needless wrappers. But I would say: if you need them, them use them.
Despite the claims in GPC to the contrary, "const" array parameters must be passed by reference according to the ABI anyway, and there is no way for the compiler to optimize it out since in these cases it can never have any access to the code behind the declaration since it is in the system.
I would be not so religious about ABI. Apple ABI seem to expose many low-level details without real need. My impression is that this is already causing them serious compatibilty problems. Wrappers allow to isolate Pascal programs at least from some low level details.
Waldek Hebisch wrote:
Peter N Lewis wroteL
You might want to consider writing wrapper routines (that accept string values and pass references).
Ignoring Adriaan's misplaced sarcasm, it is not practical to write wrappers for interface functions like this. Interface functions are by definition interfaces on to existing routines, and have no code associated with them (even the initialization code required by GPC causes us problems). Not upgrading GPC would be a preferable solution to writing wrappers around all these routines with all the code changes and implementation code issues that would require.
Could you elaborate what problems wrappers cause? I can see that generating wrappers takes some effort and they cause some space and time overhead at runtime. So I would avoid needless wrappers. But I would say: if you need them, them use them.
Despite the claims in GPC to the contrary, "const" array parameters must be passed by reference according to the ABI anyway, and there is no way for the compiler to optimize it out since in these cases it can never have any access to the code behind the declaration since it is in the system.
I would be not so religious about ABI. Apple ABI seem to expose many low-level details without real need. My impression is that this is already causing them serious compatibilty problems. Wrappers allow to isolate Pascal programs at least from some low level details.
I agree completely to both points.
Both things can help make using the interfaces (i.e., Pascal programming) more comfortable, and unless the call overhead is of superior importance, I'd prefer the comfort. (I can imagine that there are a few cases where efficiency matters. In these cases, you'd still need hand-written conversions in place, but for the same reason, you usually want to avoid anything implicit and write everything explicit to have full control. In a few places, this might be acceptable ...)
Frank
On 28 Feb 2005 at 17:38, Frank Heckenbach wrote:
In the GPC interfaces for Mac OS X, we use the external declaration form with a "protected var" because (according to the gc docs) the "const" declaration form doesn't guarantuee that the parameter is passed by reference, which is an ABI requirement.
In general it doesn't. This particular type is currently passed by reference (as `const'), so for a temporary work-around (until GPC has short strings) it may be acceptable.
Is it possible to add a compiler directive or something like that to force the passing of "const" parameters by reference? Another possible option is a new keyword "ByRef" - e.g., procedure foo (ByRef {const} bar : BarType); Now that I've typed it, it looks very silly indeed. But Visual Basic (!) has "ByRef". I doubt that we need a new keyword in GPC. So I would probably still plumb for adding a new compiler directive: - e.g., "{$reference-const-parameters}" or "--reference-const-parameters" at the command line.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Prof A Olowofoyeku (The African Chief) wrote:
On 28 Feb 2005 at 17:38, Frank Heckenbach wrote:
In the GPC interfaces for Mac OS X, we use the external declaration form with a "protected var" because (according to the gc docs) the "const" declaration form doesn't guarantuee that the parameter is passed by reference, which is an ABI requirement.
In general it doesn't. This particular type is currently passed by reference (as `const'), so for a temporary work-around (until GPC has short strings) it may be acceptable.
Is it possible to add a compiler directive or something like that to force the passing of "const" parameters by reference? Another possible option is a new keyword "ByRef" - e.g., procedure foo (ByRef {const} bar : BarType); Now that I've typed it, it looks very silly indeed. But Visual Basic (!) has "ByRef". I doubt that we need a new keyword in GPC. So I would probably still plumb for adding a new compiler directive: - e.g., "{$reference-const-parameters}" or "--reference-const-parameters" at the command line.
I think a compiler directive is too broad here because you usually don't want it for all types (in particular simple types).
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
Frank
I think a compiler directive is too broad here because you usually don't want it for all types (in particular simple types).
Why would you have "const" on a simple type which would be passed by value to get the same result...?
As far as I can see, the only purpose in the "const" keyword in this case is to get it passed by reference, but not allowed to be modified so you can pass things like strings and records without the cost of copying or the fear of changing your source. For simple types you would just pass by value.
But even then, I'm happy for the compiler to say: "const" with simple values does nothing, "const" with not-simple values is undefined unless the compiler directive XYZ is set, in which case it always passes by reference.
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
That's fine by me, except if that would allow passing constant strings and such, then how is it different to "protected var" allowing passing constant strings? The latter seems the easiest solution (not to mention keeping the current status and not requiring me to go and change all the interfaces again ;).
Enjoy, Peter.
Peter N Lewis wrote:
As far as I can see, the only purpose in the "const" keyword in this case is to get it passed by reference, but not allowed to be modified so you can pass things like strings and records without the cost of copying or the fear of changing your source. For simple types you would just pass by value.
I have not checked the rules gpc uses. But speaking about purpose, consider:
type alpha : array[1..8] of char;
On 64-bit machine passing `alpha' by value (in a register) is likely to more efficient then passing reference. On 32-bit machine reference is probably more efficient. On machines with vector registers it may pay off to pass larger arrays in registers. So one meaning is "the value will not change, use most efficient method to pass parameters".
Also, `var' (even protected) parameter has special semantics: the value _can_ change due to direct assignments to global variables (or due to routine calls). In many cases the compiler has to read values directly from memory, even if previously read value is still available in registers. Indirect modifications of `const' may be considered as an error, since the programmer can not rely on parameters being modified (or not modified). So, in principle `const' parameters allow better optimization. Of course, once we document that certain `const' parameters are always passed by reference programmers may try dirty tricks...
Concerning `Str255': it would take rather strange machine (high bandwidth, high latency distributed machine ???) for such type to be passed by value. For such machine sticking to Apple ABI seem pointless...
Peter N Lewis wrote:
I think a compiler directive is too broad here because you usually don't want it for all types (in particular simple types).
Why would you have "const" on a simple type which would be passed by value to get the same result...?
To state that it's read-only. (Yes, `protected' does the same, but those preferring BP style, or trying to write BP compatible code, use `const' ...)
As far as I can see, the only purpose in the "const" keyword in this case is to get it passed by reference, but not allowed to be modified so you can pass things like strings and records without the cost of copying or the fear of changing your source. For simple types you would just pass by value.
Perhaps you really weren't aware of it (I'm almost getting the impression when I read this), but both `const' and `protected' forbid modification of the parameter within the routine, even if it's passed by value. This can be a tool to avoid some bugs (especially for value parameters -- one might accidentally assign to the parameter, thinking it was a reference parameter; a plain value parameter would accept the assignment and discard the value when leaving the routine; a `protected' or `const' parameter will signal an error).
But even then, I'm happy for the compiler to say: "const" with simple values does nothing, "const" with not-simple values is undefined unless the compiler directive XYZ is set, in which case it always passes by reference.
That's basically what GPC does without the directive ATM already. The question is what simple values are.
As I said, an array of 255 chars is most likely not simple; the critical values are quite different ones. But if you want to declare it explicitly (and be 100% sure that it will always be passed by reference), the best so far to me still seems a new syntax.
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
That's fine by me, except if that would allow passing constant strings and such, then how is it different to "protected var" allowing passing constant strings? The latter seems the easiest solution (not to mention keeping the current status and not requiring me to go and change all the interfaces again ;).
It violates EP, quite simply. (So we'd need a dialect version check and all the blah blah, and then I'll rather have a different syntax to make the difference explicit.)
I think that `const var' looks a bit strange. But given that `const' in parameter lists means `read-only, accept values' and `var' here means `pass by reference', it may be understandable ...
Waldek Hebisch wrote:
Peter N Lewis wrote:
As far as I can see, the only purpose in the "const" keyword in this case is to get it passed by reference, but not allowed to be modified so you can pass things like strings and records without the cost of copying or the fear of changing your source. For simple types you would just pass by value.
I have not checked the rules gpc uses. But speaking about purpose, consider:
type alpha : array[1..8] of char;
On 64-bit machine passing `alpha' by value (in a register) is likely to more efficient then passing reference. On 32-bit machine reference is probably more efficient. On machines with vector registers it may pay off to pass larger arrays in registers. So one meaning is "the value will not change, use most efficient method to pass parameters".
Exactly, that's how we defined it. (Well, we don't strictly find the most efficient method currently, just some heuristics, but that's the idea.)
Also, `var' (even protected) parameter has special semantics: the value _can_ change due to direct assignments to global variables (or due to routine calls). In many cases the compiler has to read values directly from memory, even if previously read value is still available in registers. Indirect modifications of `const' may be considered as an error, since the programmer can not rely on parameters being modified (or not modified). So, in principle `const' parameters allow better optimization.
Yes. I don't know if the backend supports it (yet), but in principle we could avoid aliasing problems.
Of course, once we document that certain `const' parameters are always passed by reference programmers may try dirty tricks...
That's why we don't. :-) In particular, since it may vary between platforms, providing for very nice kinds of bugs ...
Concerning `Str255': it would take rather strange machine (high bandwidth, high latency distributed machine ???) for such type to be passed by value. For such machine sticking to Apple ABI seem pointless...
Perhaps, one day, 2048 bit registers ... ;-)
Peter N Lewis wrote:
Despite the claims in GPC to the contrary, "const" array parameters must be passed by reference according to the ABI anyway, and there is no way for the compiler to optimize it out since in these cases it can never have any access to the code behind the declaration since it is in the system.
BTW, are there array values in MP at all, or are the only arrays where it really matters in fact strings?
Frank
On 28 Feb 2005 at 23:32, Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
On 28 Feb 2005 at 17:38, Frank Heckenbach wrote:
In the GPC interfaces for Mac OS X, we use the external declaration form with a "protected var" because (according to the gc docs) the "const" declaration form doesn't guarantuee that the parameter is passed by reference, which is an ABI requirement.
In general it doesn't. This particular type is currently passed by reference (as `const'), so for a temporary work-around (until GPC has short strings) it may be acceptable.
Is it possible to add a compiler directive or something like that to force the passing of "const" parameters by reference? Another possible option is a new keyword "ByRef" - e.g., procedure foo (ByRef {const} bar : BarType); Now that I've typed it, it looks very silly indeed. But Visual Basic (!) has "ByRef". I doubt that we need a new keyword in GPC. So I would probably still plumb for adding a new compiler directive: - e.g., "{$reference-const-parameters}" or "--reference-const-parameters" at the command line.
I think a compiler directive is too broad here because you usually don't want it for all types (in particular simple types).
Local directives?
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
Yes, that should be fine as well. That way, Peter can simply do a search&replace to change "Protected Var" to "Const Var".
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Prof A Olowofoyeku (The African Chief) wrote:
On 28 Feb 2005 at 23:32, Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
On 28 Feb 2005 at 17:38, Frank Heckenbach wrote:
In the GPC interfaces for Mac OS X, we use the external declaration form with a "protected var" because (according to the gc docs) the "const" declaration form doesn't guarantuee that the parameter is passed by reference, which is an ABI requirement.
In general it doesn't. This particular type is currently passed by reference (as `const'), so for a temporary work-around (until GPC has short strings) it may be acceptable.
Is it possible to add a compiler directive or something like that to force the passing of "const" parameters by reference? Another possible option is a new keyword "ByRef" - e.g., procedure foo (ByRef {const} bar : BarType); Now that I've typed it, it looks very silly indeed. But Visual Basic (!) has "ByRef". I doubt that we need a new keyword in GPC. So I would probably still plumb for adding a new compiler directive: - e.g., "{$reference-const-parameters}" or "--reference-const-parameters" at the command line.
I think a compiler directive is too broad here because you usually don't want it for all types (in particular simple types).
Local directives?
Well, having to turn on/off the directive for each such parameter in those big interfaces ...
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
Yes, that should be fine as well. That way, Peter can simply do a search&replace to change "Protected Var" to "Const Var".
Probably.
Frank
Prof A Olowofoyeku (The African Chief) wrote:
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
Yes, that should be fine as well. That way, Peter can simply do a search&replace to change "Protected Var" to "Const Var".
I've implemented `const var' now. After the next release, please check (Adriaan, Peter, Gale, whoever likes to ;-) if it satisfies the needs. I did only trivial tests now, as I don't have a real test situation handy. (Or send me test programs if you prefer -- though it might not be easy to write them in a general way, and checking for internals ...)
Frank
Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
Yes, that should be fine as well. That way, Peter can simply do a search&replace to change "Protected Var" to "Const Var".
I've implemented `const var' now. After the next release, please check (Adriaan, Peter, Gale, whoever likes to ;-) if it satisfies the needs. I did only trivial tests now, as I don't have a real test situation handy. (Or send me test programs if you prefer -- though it might not be easy to write them in a general way, and checking for internals ...)
Thanks for implementing `const var'. I will be pleased to test them after the next release.
Regards,
Adriaan van Os
Frank Heckenbach wrote:
(Or send me test programs if you prefer -- though it might not be easy to write them in a general way, and checking for internals ...)
Maybe the following trick works (it does on Mac OS X). Pass a global variable to a routine and then check if @globalvar=@parameter. Repeat this for several types.
Regards,
Adriaan van Os
Adriaan van Os wrote:
Frank Heckenbach wrote:
(Or send me test programs if you prefer -- though it might not be easy to write them in a general way, and checking for internals ...)
Maybe the following trick works (it does on Mac OS X). Pass a global variable to a routine and then check if @globalvar=@parameter. Repeat this for several types.
Good idea. I've added this test now (passes). Any more types I should check?
{$setlimit 10000}
program fjf1089d (Output);
type th = String (1); ti= String (100); tj = set of 1 .. 4; tk = set of -1000 .. 5000; tl = record a: Byte end; tm = record i: Integer; j: array [1 .. 1000] of Real end; tn = array [1 .. 2] of Char; tp = array [-400 .. 10000] of Real; tq = packed array [0 .. 255] of Char; tr = packed array [1 .. 5] of Boolean; ts = object a: Boolean end; tt = object s: String (10000) end; tu = (aa, bb, cc, dd, ee); tv = ^Integer;
var a: Char; b: Boolean; c: Byte; d: Integer; e: LongestCard; f: Real; g: LongestReal; h: th; i: ti; j: tj; k: tk; l: tl; m: tm; n: tn; p: tp; q: tq; r: tr; s: ts; t: tt; u: tu; v: tv;
procedure o (const var pa: Char; const var pb: Boolean; const var pc: Byte; const var pd: Integer; const var pe: LongestCard; const var pf: Real; const var pg: LongestReal; const var ph: th; const var pi: ti; const var pj: tj; const var pk: tk; const var pl: tl; const var pm: tm; const var pn: tn; const var pp: tp; const var pq: tq; const var pr: tr; const var ps: ts; const var pt: tt; const var pu: tu; const var pv: tv); begin if (@pa = @a) and (@pb = @b) and (@pc = @c) and (@pd = @d) and (@pe = @e) and (@pf = @f) and (@pg = @g) and (@ph = @h) and (@pi = @i) and (@pj = @j) and (@pk = @k) and (@pl = @l) and (@pm = @m) and (@pn = @n) and (@pp = @p) and (@pq = @q) and (@pr = @r) and (@ps = @s) and (@pt = @t) and (@pu = @u) and (@pv = @v) then WriteLn ('OK') else WriteLn ('failed') end;
begin o (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u, v) end.
Frank
Frank Heckenbach wrote:
Adriaan van Os wrote:
Frank Heckenbach wrote:
(Or send me test programs if you prefer -- though it might not be easy to write them in a general way, and checking for internals ...)
Maybe the following trick works (it does on Mac OS X). Pass a global variable to a routine and then check if @globalvar=@parameter. Repeat this for several types.
Good idea.
The idea was borrowed from Peter N. Lewis.
Regards,
Adriaan van Os