Waldek Hebisch wrote:
Prof A Olowofoyeku wrote:
It is with the "move" call that I actually don't need the compiler complaining about dereferencing untyped pointers.
I guess in general you mean dereferencing untyped pointers to pass then via var parameters. We could in principle allow such use while disallowing all other uses, trough it is somewhat tricky to do in the compiler (at first glance it looks almost impossible,
Indeed.
but I have found rather simple way to do this).
Which way is this (as I'd judge the klumsiness of a feature also by the amount of work it takes to implement)? Would you add a new tree code for pointer dereferencing, or have you found an easier way?
Still, such use should be not very frequent.
Surely.
One option was to have "{$borland-pascal}" and such before the call, and then have "{$gnu-pascal}" afterwards to turn off the BP mode. However, this now breaks other things: e.g.,
function foo (const p; size : cardinal) : Integer; begin [...] inc (count); {$delphi} move (p, values^[count]^, size); { will now compile } {$gnu-pascal} result := count; end;
The assignment to "result" will no longer compile, whatever you pass at the command line, because under GPC 20050331, "{$gnu-pascal}" means that "result" is no longer predefined :-(
In the example above, "result" will be accepted if you pass "--implicit- result" to the compiler. It will however, only be accepted inside that function. It will be rejected in any other function that comes thereafter - e.g.,
function bar : integer; begin result := 0; (* not accepted because of the {$gnu-pascal} above *) end;
It compiles with my GPC 20050331, but I consider this as a bug.
What exactly? The following does not compile with 20050331.
{$W-}
program Blah;
function foo (const p; size : cardinal) : Integer; begin {inc (count);} {$delphi} {move (p, values^[count]^, size);} { will now compile } {$gnu-pascal} {result := count;} foo := size end;
function bar : Integer; begin result := 0; (* not accepted because of the {$gnu-pascal} above *) end;
begin end.
The preferred method is:
{$local delphi} move (p, values^[count]^, size); { will now compile } {$endlocal}
the `{$endlocal}' directive should restore the exact setting in force before `{$local'.
BTW, unrelated to the original topic, I had wondered about this. What about directives between `{$local}' and `{$endlocal}', should they also be restored? It might seem more consistent, and is probably easier to implement, if so. It would, of course, mean that `{$local foo}{$bar}' and `{$local foo,bar}' would be equivalent, but well, why not?
It still does not work with my GPC 20050331, but I consider this as a bug (which I hope will be quickly fixed).
Indeed. It will be easier to fix after integrating the preprocessor, but I hope I'll get to that soon now (say, after the next alpha which should mainly fix current bugs and finish some of the issues we're currently working on).
I do not know why you consider here compiler directives better then
move (p, pchar(values^[count])^, size); { will now compile }
I'd also suggest that. Compiler directives are IMHO "dirtier" than a single non-standard construct such as type-casting. (If the alternative would be several such constructs, it may be debatable.)
BTW if you want to use `move' multiple times, did you consider defining a new routine with second parameter beeing a pointer (so there is no need to dereference):
procedure movevp(const s; tp: pointer, size : cardinal); begin move (p, pchar(tp)^, size); end;
and later:
movevp (p, values^[count], size);
If there's really serious need for it, we could probably supply such a routine with GPC (with no extra calling overhead, unlike with a wrapper routine). Then, I suppose both the first and second arguments should be pointers. But I'm not yet convinced it's really needed.
Let's just say that this new feature has made life more difficult for me, since before the 20050331 snapshot, {"$gnu-pascal}" meant "allow everything that GPC supports". Now, it seems to mean something different. I am not sure whether this is an unintended side effect, but it does look like it to me!
`{$gnu-pascal}' means "allow everything that GPC supports and does not conflict with default settings". It was explained that `implicit-result' is _not_ an extension, it is an incompatible change. Key here is that an extension assigns meaning to otherwise illegal construct (so all old programs continue to work). `implicit-result' changes meanig of non-Delphi programs. If Wirth says that a program should print 1 and Delphi prints -1 than we can not support both ways as a default (and we like Wirth more than Delphi:)
Indeed. AFAIK, you (Chief) followed that discussion. Perhaps the incompatibility caused by `Result' is not important to you, and it may well not affect any of your code, but it exists, and a compiler has to deal with it.
To sum up the previous discussions:
- `Result' is really incompatible because it doesn't have global scope. Unless other extensions which can be shadowed by user constructs, `Result' in turn can shadow user constructs, and therefore, as Waldek described, alter the meaning of a previously valid standard Pascal (and even Turbo Pascal) program. That's the big problem. Even if most actual uses of `Result' are harmless, turning it on by default could affect programs entirely unaware of `Result' and using it as a regular identifier.
- Since 20050331, GPC treats implicit `Result' exactly like an explicit result variable if enabled (so scopes work as expected). Therefore, the setting of the option at the start of the function (after its heading, before possible local declarations), where the variable would be declared, matters, and option changes within the function don't matter. They can, of course, influence following functions. This may be surprising (being able to use `Result' after "turning it off" within a function where it was originally enabled), but it seems the only sane way to handle it (without retroactively inserting/deleting the result variable declaration from the current function).
The Chief wrote:
So, why not just write "foo := count" ?
Because there are too many source files and too many functions to change in this way.
I see. However, due to the dangers of `Result', I'd suggest to get rid of it in the long run.
An easier alternative might by to add an explicit result variable called `Result'. This way there can be no confusion about the meaning of `Result', so GPC will allow it by default. This would amount to adding `= Result' in all relevant function headings which might be easier to do, and still allow the result variable on the RHS of an assignment without causing a recursive call (which is the main use of implicit `Result' AFAIK).
Frank