Oldham, Adam wrote:
TYPE AnyStr = STRING[40]; AnyStrPtr = ^AnyStr;
VAR TestVar1 : AnyStrPtr; TestVar2 : AnyStrPtr; TestVar3 : AnyStr; TestVar4 : AnyStr;
BEGIN TestVar3 := 'TEST1'; TestVar1 := AnyStrPtr(@TestVar3); TestVar4 := 'TEST3'; TestVar2 := AnyStrPtr(@TestVar4); writeln(TestVar1^); writeln(TestVar2^); MOVELEFT (TestVar1^, TestVar2^, (LENGTH(TestVar1^) + 1)); writeln(""); writeln("After"); writeln(TestVar1^); writeln(TestVar2^); END. { unit pSos }
With GPC, the output is: TEST1 -> (TestVar1) TEST3 -> (TestVar2)
After TEST1 -> (TestVar1 after MoveLeft) TEST3 -> (TestVar2 after MoveLeft)
With my old compiler, the output is: TEST1 TEST3
After TEST1 TEST1
As it basically copies the length bytes of TestVar1 into TestVar2. Now, my question, does GPC work differently for this function, and if yes or no, is this a bug.
Your old compiler was probably a Borland type, i.e. AnyStr are one byte [0] containing the length and 40 bytes containing the chars. This is why you moved length()+1 chars, 1 being for the zeroth char. In gpc String is different. It is defined as:
type String (Capacity : Integer) = record Length : 0 .. Capacity; String : packed array [1 .. Capacity + 1] of Char end;
When you moves 6 chars, you move mainly the Capacity and (part of) the Length field, this is why it seems you move nothing. The result would be even stranger if the two strings had different Capacity and/or Length.
One solution if you want to move only the chars would be
MOVELEFT (TestVar1^[1], TestVar2^[1], (LENGTH(TestVar1^)));
i.e. addresses of the first chars and no more +1.
This non pascal, C style or assembly style, kind of programming can work only if you know exactly the internals of your system, down to binary level. Otherwise it opens a can of worms and any porting from one system to another is a very efficient bug generator, as you have checked. For example If you tried to move also the Capacity and Length fields to solve your problem, the result would depend on undefined things like alignment of these fields: try to write SizeOf(AnyStr). On my system it is 52, instead of 40 + 1 + 2*SizeOf(integer) = 49: alignment on a four bytes (integer) boundary. String assignment is probably the right way of doing !
So this is definitely not a bug of gpc, rather a bug entailed by Borland style programming.
Hope this helps
Maurice