(moving back to the list)
XXXX XXXXXXXXXXX X mail.ru wrote 7 lines
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).
Show quoted text 5 lines
(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