Peter Gerwinski wrote:
What about extending (*$executable-file-name="foo"*) to accept a directory? Or else (*$executable-path-name="/foo"*) and (*$object-path-name="/bar"*)?
I don't agree. The *name* of the executable can be considered part of the program. The *path* where it will be stored will be system dependent, so the path, IMHO, does not belong into the source, but on the commandline (or into a (system or user or project specific) config file, of course).
A directive (*$Foo="Bar"*) is always equivalent to a command-line option `--foo="Bar"'. I was just thinking about reasonable names for these options.
Ok, "executable-path-name" and "object-path-name" seem ok to me. I just doubt whether it's wise to allow putting them into the source (doing so would probably lead to "unexpected results" when moving the files to another system). Or are all command line options automatically allowed in the source now?
- Passing the actual size for untyped (resp. void) parameters, so it can be access with sizeof.
var x:void -> like C var/const x -> like BP
BP does *not* pass the size of untyped parameters to the procedure.
Sorry, I meant to say "like BP with extensions"... ;-)
Changing GPC would break compatibility to both C and BP; the latter being unimportant because nobody will consider it a feature *not* to have the size of a variable.
I wouldn't even say it breaks compatibility. It just adds a feature ("backward compatible"). Programs written for BP cannot fail with gpc because of the additional parameter.
OTOH, many C libraries rely on a `void*' parameter *not* being followed by a `size' parameter.
Ok, then "void" works for these cases (passing an untyped pointer by value works, too).
Instead of changing the meaning of `Var foo', we are IMHO better off when introducing a *safe* mechanism to pass variables of varying type (and number). Procedure overloading will be "half the rent". ;-)
But what about the other half? Overloading will only handle those cases where only a certain number of types are admitted. Other cases (like BlockRead/ -Write, Move, FillChar, to speak in BP terms) allow any type, so overloading doesn't help there. And since BP compatibilty is not really broken, I'd still vote for this.
For procedural variables, BP uses "@ProcVar" to cast them into a pointer(!!!). gpc does not understand this, but the (more logical, IMHO) "Pointer(ProcVar)". Unfortunately, BP doesn't accept the latter, so AFAICS there's yet no way that works on both. :-( Since we can't change BP, we should make gpc recognize "@ProcVar", perhaps also only in "--borland-pascal".
Okay; I have put it on my list.
Plan: Recognize it, but warn. With `--borland-pascal' (same as (*$borland-pascal*) :-), don't warn.
Oh, oh... things seems to be much more difficult than I thought... :-(
I saw that there could be problems with function type variables, resulting from the possible confusion between their addresses and the function results -- especially difficult if the function result type is a pointer type. Additionally, there can be manual type casts, and finally there's BP even more strange syntax "@@", meaning the address of the procedure/function type *variable*.
So I did some tests, and now I'm completely confused! Since I don't know what the standard requires, I don't even know what are bugs, and what are features...
That's why I'm posting the results without any comments. The first program:
program x; {$x+} {$f+}
{Write a pointer (with BP: only the offset, but this doesn't matter here)} procedure wp(p:pointer); begin writeln(integer(p)) end;
{Test function} function y:pointer; begin y:=nil end;
type t=function:pointer;
var va:integer; v:t absolute va;
begin v:=y; {Let v point to y}
wp(@va); {Should give the address of the variable v for reference purposes} wp(@y); {Should give the address of the function y for reference purposes}
{6 different ways of accessing some addresses...}
{$ifndef __GPC__} wp(v); {$endif} wp(@v); {$ifndef __GPC__} wp(@@v); {$endif} wp(pointer(v)); wp(pointer(@v)); {$ifndef __GPC__} wp(pointer(@@v)); {$endif} end.
The results with BP are (where "v" means the actual address of v, "y" that of y, and "0" means nil):
v,y,0,y,v,0,y,v
gpc gives (where "-" means, doesn't compile, and "?" is a seemingly arbitrary value):
v,0,-,v,-,?,v,-
With the SP syntax "^function:pointer", the "?" becomes 0.
With the next program, gpc says "invalid lvalue in address expression" in line 4:
program x; var a:procedure; b:integer absolute a; begin end.
With this one, it says "void value not ignored as it ought to be" and "initial value is of wrong type" in line 5:
program x;
procedure y; begin end;
var a:procedure value y;
begin end.
All I can see that the results are "a little bit" different from BP. :-( The last two programs seem to show that gpc tries to "evaluate"(?) a procedure when it shouldn't...!?
Since I don't really understand what's going on, I have no ideas how to "fix" it. At least, we have a different syntax in BP and SP, so we could use different semantics if necessary (see above ;-)...