Sign in Join

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

Mailing lists / fpc-pascal / 2010-02

Pointers

12 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

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

Rainer Stratmann

What is the difference between A* and B*?
regards, Rainer

type
 tchararr = array[ 0..999 ] of char;
 pchararr = ^tchararr;
 http_obj = object
  pdata            : pchararr;
  header_anz        : longint;
  content_anz       : longint;
 end;
var
 http : http_obj;
 ppp : pointer;
 // This works for me A*
 ppp := http.pdata;
 ppp := ppp + http.header_anz;
 // This is not working B*
 ppp := http.pdata + http.header_anz;
 write( 'IP-Adress = ' + parse_ip( ppp , http.content_anz ) );
Frank Peelo
to Rainer Stratmann

So you're allowed add an integer to an untyped pointer?!

Wow!

Usually if you add 1 to a pointer of type t, then sizeof(t) gets added to the value of the pointer. So if p points at an array of byte, p+1 would point at the next element of the array, 1 byte after p. But if p points at an array of LongInt, then the next element is 4 bytes on from p, so adding 1 to p increases p by 4. So what would sizeof(pointer^) be?

To me, adding an integer to an untyped pointer feels undefined (i.e. I haven't studied the spec for it but I wouldn't have expected the compiler to do anything sensible with it) because what pointer points to is undefined and sizeof(something undefined) is not defined. So I haven't tried that myself.

From your code, I'm guessing that adding 1 to an untyped pointer adds 1 to the address. So ppp + http.header_anz would be http.header_anz bytes after ppp.

But http.pdata + http.header_anz means to add http.header_anz to a variable of type pointer to tchararr. That means, imagine http.pdata is pointing to an array[0..lots] of tcharrarr, find the address of element http.header_anz of that array. Now, tcharrarr is 1000 bytes long, so I would expect http.pdata + http.header_anz to be 1000*http.header_anz bytes after http.pdata.

Is that what you are seeing?

FP

Rainer Stratmann wrote 32 lines
What is the difference between A* and B*? regards, Rainer type tchararr = array[ 0..999 ] of char; pchararr = ^tchararr; http_obj = object pdata : pchararr; header_anz : longint; content_anz : longint; end; var http : http_obj; ppp : pointer; // This works for me A* ppp := http.pdata; ppp := ppp + http.header_anz; // This is not working B* ppp := http.pdata + http.header_anz; write( 'IP-Adress = ' + parse_ip( ppp , http.content_anz ) ); _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Rainer Stratmann
to Frank Peelo

I thought that adding something to a pointer always adds 1 sizeof(byte) to it. So if something is added to a pointer the compiler looks the sizeof the (typed) pointer points to?
Ok, that makes some sense, but I did not know it before. In the past with the turbopascal compiler and other always sizeof byte was added.
Thank you and regards, Rainer

Frank Peelo wrote 28 lines
So you're allowed add an integer to an untyped pointer?! Wow! Usually if you add 1 to a pointer of type t, then sizeof(t) gets added to the value of the pointer. So if p points at an array of byte, p+1 would point at the next element of the array, 1 byte after p. But if p points at an array of LongInt, then the next element is 4 bytes on from p, so adding 1 to p increases p by 4. So what would sizeof(pointer^) be? To me, adding an integer to an untyped pointer feels undefined (i.e. I haven't studied the spec for it but I wouldn't have expected the compiler to do anything sensible with it) because what pointer points to is undefined and sizeof(something undefined) is not defined. So I haven't tried that myself. From your code, I'm guessing that adding 1 to an untyped pointer adds 1 to the address. So ppp + http.header_anz would be http.header_anz bytes after ppp. But http.pdata + http.header_anz means to add http.header_anz to a variable of type pointer to tchararr. That means, imagine http.pdata is pointing to an array[0..lots] of tcharrarr, find the address of element http.header_anz of that array. Now, tcharrarr is 1000 bytes long, so I would expect http.pdata + http.header_anz to be 1000*http.header_anz bytes after http.pdata. Is that what you are seeing?

I did not test it, but I think you are right.

Show quoted text 37 lines
FP On 11/02/2010 15:38, Rainer Stratmann wrote: > What is the difference between A* and B*? > regards, Rainer > > > type > tchararr = array[ 0..999 ] of char; > pchararr = ^tchararr; > > http_obj = object > pdata : pchararr; > header_anz : longint; > content_anz : longint; > end; > > var > http : http_obj; > ppp : pointer; > > > // This works for me A* > ppp := http.pdata; > ppp := ppp + http.header_anz; > // This is not working B* > ppp := http.pdata + http.header_anz; > > > write( 'IP-Adress = ' + parse_ip( ppp , http.content_anz ) ); > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Micha Nelissen
to Rainer Stratmann
Rainer Stratmann wrote
Ok, that makes some sense, but I did not know it before. In the past with the turbopascal compiler and other always sizeof byte was added.

The behavior is dependent on the {$T+} (typed pointers) mode.

Micha

Jonas Maebe
to Rainer Stratmann: I thought that adding something to a pointer always adds 1 sizeof(byte) to it. So if…
Rainer Stratmann wrote
In the past with the turbopascal compiler and other always sizeof byte was added.

That is not true. This program prints "2" when compiled under Turbo Pascal:

{$t-}
type
   pw = ^word;
var
   w: pw;
begin
   w:=nil;
   inc(w);
   writeln(longint(w));
end.

(and the result does not depend on {$t+} or {$t-}; that only influences whether e.g. @wordvar has the type "^word" or plain "pointer").

Furthermore, Turbo Pascal did not support performing pointer arithmetic using anything else but inc() and dec() (so things like "ppp := ppp + http.header_anz" or "w:=w+1" would not compile under TP), except for pchar variables (in which case the base value is sizeof(char), since that's what a pchar points to).

Jonas

Rainer Stratmann
to Jonas Maebe
Jonas Maebe wrote 7 lines
On 11 Feb 2010, at 18:17, Rainer Stratmann wrote: > In the past with the turbopascal compiler and other always sizeof > byte was > added. That is not true. This program prints "2" when compiled under Turbo Pascal:

Ok, sorry I don't remember exactly, but it feels like that tp did this.

Is there a site how to deal with pointers?

Show quoted text 27 lines
{$t-} type pw = ^word; var w: pw; begin w:=nil; inc(w); writeln(longint(w)); end. (and the result does not depend on {$t+} or {$t-}; that only influences whether e.g. @wordvar has the type "^word" or plain "pointer"). Furthermore, Turbo Pascal did not support performing pointer arithmetic using anything else but inc() and dec() (so things like "ppp := ppp + http.header_anz" or "w:=w+1" would not compile under TP), except for pchar variables (in which case the base value is sizeof(char), since that's what a pchar points to). Jonas _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Ralf A. Quint
to Jonas Maebe: That is not true. This program prints "2" when compiled under Turbo Pascal: {$t-} type pw…
Jonas Maebe wrote 8 lines
On 11 Feb 2010, at 18:17, Rainer Stratmann wrote: >In the past with the turbopascal compiler and other always sizeof >byte was >added. That is not true. This program prints "2" when compiled under Turbo Pascal:

I am fairly certain that he confuses this with the special case of applying sizeof() to a string type, where you always get one byte more (the preceding length byte) than the string type has been defined, for example SizeOf (String [80]) will return 81, 80 bytes reserved for the contents plus the length byte...

Ralf

Rainer Stratmann
to Ralf A. Quint
Ralf A. Quint wrote 16 lines
At 12:07 PM 2/11/2010, Jonas Maebe wrote: >On 11 Feb 2010, at 18:17, Rainer Stratmann wrote: >>In the past with the turbopascal compiler and other always sizeof >>byte was >>added. > >That is not true. This program prints "2" when compiled under Turbo >Pascal: I am fairly certain that he confuses this with the special case of applying sizeof() to a string type, where you always get one byte more (the preceding length byte) than the string type has been defined, for example SizeOf (String [80]) will return 81, 80 bytes reserved for the contents plus the length byte... Ralf

How can I have access to position 4 of a pointer?

var
 p : pbyte;
 c : char;
 s : ansistring;
 x : longint;

...

 s := 'Hello';
 p := @s;
 x := 4;  // 4th position
 c :=  [p+x]^ ??? how to get access to the 'o'
Ralf A. Quint
to Rainer Stratmann
Rainer Stratmann wrote 9 lines
> I am fairly certain that he confuses this with the special case of > applying sizeof() to a string type, where you always get one byte > more (the preceding length byte) than the string type has been > defined, for example SizeOf (String [80]) will return 81, 80 bytes > reserved for the contents plus the length byte... > > Ralf How can I have access to position 4 of a pointer?

By using Pascal and not C! <LOL>

var
  p : Pointer;
  c : char;
  s : ansistring;
  x : longint;
begin
  s := 'Hello';
  p := @s;
  x := 5;  // 5th position!!!!
  c :=  Char (ANSIString (p^)[x]);
  WriteLn ('Character No.',x,' is ',c);
end.

Ralf

David Emerson
to Rainer Stratmann: How can I have access to position 4 of a pointer? var p : pbyte; c : char; s : ansistring;
Rainer Stratmann wrote 12 lines
How can I have access to position 4 of a pointer? var p : pbyte; c : char; s : ansistring; x : longint; s := 'Hello'; p := @s; x := 4; // 4th position c := [p+x]^ ??? how to get access to the 'o'
c := (p+x)^;  // why would someone use square brackets for that?

Of course, if you are actually working with a string, there is no need to use pointers.
c := s[5]; // remember strings are 1-indexed

You can also increment...
inc (p, 4);
c := p^;

I might make a second pointer, q, and increment that, so p can stay in place.

~David.

Mattias Gaertner
to Rainer Stratmann: How can I have access to position 4 of a pointer? var p : pbyte; c : char; s : ansistring;
Show quoted text 30 lines
Am Thursday 11 February 2010 21:24:03 schrieb Ralf A. Quint: > At 12:07 PM 2/11/2010, Jonas Maebe wrote: > >On 11 Feb 2010, at 18:17, Rainer Stratmann wrote: > >>In the past with the turbopascal compiler and other always sizeof > >>byte was > >>added. > > > >That is not true. This program prints "2" when compiled under Turbo > >Pascal: > > I am fairly certain that he confuses this with the special case of > applying sizeof() to a string type, where you always get one byte > more (the preceding length byte) than the string type has been > defined, for example SizeOf (String [80]) will return 81, 80 bytes > reserved for the contents plus the length byte... > > Ralf How can I have access to position 4 of a pointer? var p : pbyte; c : char; s : ansistring; x : longint; ... s := 'Hello'; p := @s;

Now p is an PAnsiString.
Maybe you meant:
p:=PByte(s);

x := 4; // 4th position c := [p+x]^ ??? how to get access to the 'o'
c:=chr(p[x]);

But normally you use PChar:

var p: PChar;
...
p:=s;
c:=p[x];

Mattias

Frank Peelo
to Jonas Maebe: That is not true. This program prints "2" when compiled under Turbo Pascal: {$t-} type pw…
Jonas Maebe wrote 20 lines
On 11 Feb 2010, at 18:17, Rainer Stratmann wrote: > In the past with the turbopascal compiler and other always sizeof byte > was > added. That is not true. This program prints "2" when compiled under Turbo Pascal: {$t-} type pw = ^word; var w: pw; begin w:=nil; inc(w); writeln(longint(w)); end.

i.e. incrementing a pointer to word changes the address by sizeof(word) = 2 bytes.

Incrementing always by sizeof(byte) just would not make sense. If you have a type that takes more than one byte, such as word, or double, then incrementing by sizeof(byte) would take you *inside* the variable, to an address where you don't know what you should find! It would depend on the endianness of the CPU, and what was in memory after the end of the variable, and stuff like that. The only sensible way to increment a pointer to SomeType is to increment by sizeof(SomeType). If you really want to pick apart a variable byte by byte, use ^Byte.

Frank