[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