[fpc-devel] blockwrite
Jonas Maebe
jonas.maebe at elis.ugent.be
Thu Mar 16 10:01:24 CET 2006
(moving back to the list)
On 15 mrt 2006, at 23:55, XXXX XXXXXXXXXXX X mail.ru wrote:
> JM> Your variable "a:^pbyte;" is not an array, it's a pointer. In
> Pascal,
> JM> So if you write blockwrite(a,..), you are passing the address
> of "a"
> JM> Jonas
>
> Not to spam maillists: how could I know that?
Because "a" is a pointer. And because blockwrite is declared as
Procedure BlockWrite(Var f:File;Const Buf;Count:Int64;var
Result:Int64);[IOCheck];
The "Const Buf" is a formal const parameter, and formal const and var
parameters always receive the address to the argument you pass to them.
> Is there any
> documentation with explicit conventions on pointer arithmetics in
> FreePascal?
You have found the documentation yourself apparently, given the
paragraph below. It's at http://www.freepascal.org/docs-html/ref/
refse14.html
Pointer arithmetics work exactly the same as in C. I think your
confusion rather stemmed from the fact that C does not know the
concept of "var parameters" nor of "formal const/var parameters".
Another thing is that the documentation does not clearly state that
in case of "formal const" parameters, the address to the parameter is
always passed (and in case the parameter does not have an address,
such as in case you would pass "5", then the compiler allocates
temporary room on the stack, stores the value there and then passes
the address of this temporary stack location).
> (In docs the corresponding argument of blockwrite is declared as
> "const buf", in blockread example it was array, in pointer
> documentation bracketed pointers behave exactly like array
> identifiers.
> Isn't documentation vague, or do I miss something?)
It says "The difference is that the former declaration allocates
memory for the pointer only (not for the array), and the second
declaration allocates memory for the entire array."
When a procedure is declared as having a parameter of which the
address must be passed, then the compiler always does this. So "a:
^byte;" only allocates memory for the pointer "a", and passing "a" to
a formal const/var parameter will pass the address of the pointer
"a". "b: array[1..10] of byte;" allocates memory for the array "b"
and passing "b" to a formal const/var parameter will pass the address
of the array b.
If you set "a := @b", then a[0] and b[1] become equivalent, so @a[0]
and @b[1] are also equivalent. In addition, @b = @b[0], but @a <> @a
[1]. The abusing of pointers as arrays is so confusing because it
includes an implicit dereferencing of the pointer. Normally, you
should have to declare "a" as
type
tarr = array[1..10] of byte;
var
a: ^tarr;
b: tarr;
And use it like
a := @b;
a^[1] := 5;
if (a^[1] <> b[1]) then
writeln('error');
This is much clearer concerning what is actually going on. But the
fact that the compiler also accepts C-style pointer/array equivalence
means that it will also accept "a[1]" in the above program (though
the result of that expression is not a byte, but a "tarr") and this
can lead to very confusing type checking error messages if you are
not used to working with pointers that can behave like arrays.
> I am obviously not ready to write some docs on this topic and offer
> them, so all I can do is to ask and try not to spam.
Asking questions on a mailing list to get help is not spamming.
> PPS. Was my question appropriate for that maillist?
Yes, although fpc-pascal would probably be even more appropriate (fpc-
devel in generally about developing the compiler itself, fpc-pascal
is about getting help with using the compiler and general Pascal
programming)
Jonas
More information about the fpc-devel
mailing list