Pointers

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Pointers

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 ) );
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Frank Peelo
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


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  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
>


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Rainer Stratmann
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


Am Thursday 11 February 2010 17:36:04 schrieb Frank Peelo:

> 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.

> 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  -  [hidden email]
> > http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Micha Nelissen
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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Jonas Maebe-2
In reply to this post by Rainer Stratmann

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.

(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  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Rainer Stratmann
Am Thursday 11 February 2010 21:07:17 schrieb Jonas Maebe:
> 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?

> {$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  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Ralf A. Quint
In reply to this post by Jonas Maebe-2
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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Rainer Stratmann
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;

 x := 4;  // 4th position

 c :=  [p+x]^ ??? how to get access to the 'o'
 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Ralf A. Quint
At 12:53 PM 2/11/2010, Rainer Stratmann wrote:
> > 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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

David Emerson
In reply to this post by Rainer Stratmann
On Thu 11 Feb 2010, Rainer Stratmann wrote:

> 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.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Mattias Gaertner
In reply to this post by Rainer Stratmann
On Thu, 11 Feb 2010 21:53:59 +0100
Rainer Stratmann <[hidden email]> wrote:

> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Pointers

Frank Peelo
In reply to this post by Jonas Maebe-2
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:
>
> {$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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal