Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2006-03

blockwrite

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

���� ����������� � mail.ru

Hello for the first time, fpc-devel group!

I have posted something as bug report #4905, but didn't understand the answer (why it is not a bug). Could anyone be specific and correct source code supplied (it is especially crafted little program of 25 lines including program..., end., and empty lines). (Please, look at that source before answering, because it seems to me, that fixer didn't.)

Bug report is at http://www.freepascal.org/bugs/showrec.php3?ID=4905, source example at http://www.freepascal.org/bugs/showsource.php3?ID=4905.

(FP Version: 2.0.0, Win32)

Reply by email

Jonas Maebe
to ���� ����������� � mail.ru
ϸòð Êîñàðåâñêèé ñ mail.ru wrote 6 lines
I have posted something as bug report #4905, but didn't understand the answer (why it is not a bug). Could anyone be specific and correct source code supplied (it is especially crafted little program of 25 lines including program..., end., and empty lines). (Please, look at that source before answering, because it seems to me, that fixer didn't.)

Your variable "a:^pbyte;" is not an array, it's a pointer. In Pascal, arrays and pointers are not the same thing, unlike in C. The fact that FPC allows you to abuse array notation to "index" pointers (based on the fact that TP introduced this for pchars) does not change this.

So if you write blockwrite(a,..), you are passing the address of "a" to blockwrite, not the address whatever a points to. And because "b" comes right after "a" in memory, you are first seeing garbage (namely the pointer value of a) followed by the contents of "b".

Jonas

Reply by email

Jonas Maebe

(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

Reply by email