Prof A Olowofoyeku wrote:
On 9 Mar 2005 at 2:01, Waldek Hebisch wrote:
BTW, when I write:
bar := tfunc (foo());
then my copy of FPC (1.9.4 on Debian) still gives wrong result.
What it gives is the value of "foo", which, inside "foo", you assign the address of "baz" (i.e., foo returns the address of baz as an integer). That seems correct to me.
I do not know what your FPC is doing, but AFAICS my copy of FPC treats:
bar := tfunc (foo);
and
bar := tfunc (foo());
the same. Now, the first form is ambiguous, and what FPC is doing with this form is usefull and reasonable. IMHO the second form has only one possible meaning: empty parentheses mean that `foo' should be called and the _return value_ of `foo' should be converted and assigned to `bar'.
In conclusion, I think this is what GPC should do:
- "bar := tfunc (foo)" = assign to bar the address of foo, but don't
call foo
- "bar := tfunc (foo ())" = call foo (and also assign to bar the
address of foo?) so that "writeln (integer (bar))" should result in a second call to foo - otherwise, what value does bar hold?
I see two clear cases:
bar := tfunc (@foo) { assign to bar the address of foo }
and
bar := tfunc (foo ()) { call foo and assign the return value to bar }
Plain `foo' should either mean `@foo' or `foo ()' or return variable of function `foo' (but here I am interested in values, so the third case is excluded) depending on context. I am slightly oversimpifing here -- IIRC we sometimes reject `@foo' where `foo' is acceptable, but to point is that we have to decide if we want address of foo or we want the return value. We have a bunch of syntactic contexts: left hand side of an assignment, initializers, casts, function parameters (three sorts of function parameters: value parameters, variable parameters and functional parameters).
Note that beside plain functions ("function constants") we have also function variables, pointers and results of casts so we can form rather large collection of function valued expressions.
IMHO we should use the same rule for assignment, initializers and value parameters. I am tempted to say that we should use the same rule also for variable parameters and functional parameters, but variable parameters have special restrictions and ATM functional parameters do less strict type checking then assignment.
Casts are really nasty case, since in BP casts frequently give different result then assignment (when both are legal). Also, it seems that BP casts are supposed to handle values (except for casts as lvalues). So for example is:
i := integer(foo); bar := tfunc(pointer(i));
or
bar := tfunc(pointer(integer(foo)));
the same as:
bar := tfunc(foo);
(In FPC one should use `longint' instead of `integer'.)
What happens when the return type of `foo' is `pointer'? What if return type of `foo' is pointer to `tfunc'?