Board index » delphi » Doubt on passing strings

Doubt on passing strings

Hi to all,

I think I finally have got the hang of references, however
I need help clarifying the following>

If I have the call>

Var
  Str : String;

  setLength(Str, 100);
  TestProc(PChar(Str));

and
Procedure TestProc(var StrPass : PChar)

I get the compile time error:
Constant object can not be passed as a var parameter reference.

Can anyone please explain why I get this.

Is it because String points to a fixed position in
memory and can never be changed unlike PChar variables.

Thanks

Steven Quail.

 

Re:Doubt on passing strings


Quote
Steven Quail <squai...@yahoo.com> wrote in message

news:3aabc57a.0108300850.4233bb09@posting.google.com...

Quote
> Hi to all,

> I think I finally have got the hang of references, however
> I need help clarifying the following>

> If I have the call>

> Var
>   Str : String;

>   setLength(Str, 100);
>   TestProc(PChar(Str));

> and
> Procedure TestProc(var StrPass : PChar)

> I get the compile time error:
> Constant object can not be passed as a var parameter reference.

> Can anyone please explain why I get this.

> Is it because String points to a fixed position in
> memory and can never be changed unlike PChar variables.

> Thanks

Not quite sure of your intention here, but when passing parameters  by var
the types must match exactly. How about something like....
 Var
   Str : String;

  SetLength(Str, 100);
  TestProc(PChar(Str));
  SetLength(Str, StrLen(PChar(Str)));

Procedure TestProc(Ptr : PChar);
begin
    // write some chars at Ptr and null terminate them
end;

Note that it is necessary to explicitly set the length of Str to match the
length of the null terminated string written back by TestProc(). Note also
the danger of writing back more than 100 characters.

Dave

Re:Doubt on passing strings


Here you are passing a 'conversion' of your string - this is
effectively unmodifyable.

  TestProc(PChar(Str));

and here you are expecting the address of a PChar that you *can*
modify.

Procedure TestProc(var StrPass : PChar)

using @Str[1] will give you a PChar type pointer.

IMO - and this will probably be disagreed with - PChars are pretty
pointless things now that we have ANSII Strings.  

The whole concept of an ASCIIZ string is .. well not very sound.

On 30 Aug 2001 09:50:37 -0700, squai...@yahoo.com (Steven Quail)
wrote:

Quote
>Hi to all,

>I think I finally have got the hang of references, however
>I need help clarifying the following>

>If I have the call>

>Var
>  Str : String;

>  setLength(Str, 100);
>  TestProc(PChar(Str));

>and
>Procedure TestProc(var StrPass : PChar)

>I get the compile time error:
>Constant object can not be passed as a var parameter reference.

>Can anyone please explain why I get this.

>Is it because String points to a fixed position in
>memory and can never be changed unlike PChar variables.

>Thanks

>Steven Quail.

Re:Doubt on passing strings


On 30 Aug 2001 09:50:37 -0700, squai...@yahoo.com (Steven Quail)
wrote:

Quote
>Hi to all,

>I think I finally have got the hang of references, however
>I need help clarifying the following>

>If I have the call>

>Var
>  Str : String;

>  setLength(Str, 100);
>  TestProc(PChar(Str));

>and
>Procedure TestProc(var StrPass : PChar)

>I get the compile time error:
>Constant object can not be passed as a var parameter reference.

>Can anyone please explain why I get this.

If you declare a parameter as "var" then you need
to pass a _variable_ to the routine. You're passing
PChar(Str), which is not a variable.

Two solutions: (i) It's very unlikely that you
actually need to use PChar's here - if you just
pass a "var string" things will probably work
more the way you expect (ii) It's almost certain
that IF you're going to use PChar's then you
do NOT need the "var". Because you're almost
certainly not modifying the value of a pointer,
surely you're just modifying the text that the
pointer points to.

Two examples - they both work:

procedure TestStringProc(var s: string);
begin
 s[1]:= 'H';
end;

procedure TestPCharProc(P: PChar);
begin
  P[0]:= 'h';
end;

//note those are both BUGGY routines, included
//for demonstration only. (What's the problem?)

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
  s:= 'hello';
  TestStringProc(s);
  showmessage(s);
  TestPCharProc(PChar(s));
  showmessage(s);
end;

Quote
>Is it because String points to a fixed position in
>memory and can never be changed unlike PChar variables.

>Thanks

>Steven Quail.

David C. Ullrich

Re:Doubt on passing strings


Im Artikel <3aabc57a.0108300850.4233b...@posting.google.com>,
squai...@yahoo.com (Steven Quail) schreibt:

Quote
>Is it because String points to a fixed position in
>memory and can never be changed unlike PChar variables.

Yes, that's the reason. Simple solution:

Quote
>Var
>  Str : String;

    tempstr: PChar; // <----------------

Quote
>  setLength(Str, 100);

    tempstr := PChar(Str);

Quote
>  TestProc(tempstr); //(PChar(Str));

BTW, why do you insist in a "var" parameter? Omit "var" from the PChar
parameter, and all works fine. You need "var" only, when the modified pointer
is of importance in the calling subroutine. If this really is your intention,
then you must pass an alterable pointer to the subroutine, like "tempstr"
above.

IOW, you need "var" only, when a data object must be moved in memory, and the
caller expects to receive the new starting position. If you want to prevent
changes to the data, as well as to the pointer, you must mark the pointer as
"const".

DoDi

Re:Doubt on passing strings


On 31 Aug 2001 22:18:23 GMT, vb...@aol.com (VBDis) wrote:

Quote
>Im Artikel <3aabc57a.0108300850.4233b...@posting.google.com>,
>squai...@yahoo.com (Steven Quail) schreibt:

>>Is it because String points to a fixed position in
>>memory and can never be changed unlike PChar variables.

>Yes, that's the reason. Simple solution:

>>Var
>>  Str : String;
>    tempstr: PChar; // <----------------

>>  setLength(Str, 100);
>    tempstr := PChar(Str);
>>  TestProc(tempstr); //(PChar(Str));

>BTW, why do you insist in a "var" parameter? Omit "var" from the PChar
>parameter, and all works fine.

That was my reaction as well. But we didn't see what TestProc did -
if TestProc is as in his later posts then he really does need a var
parameter, he really is modifying the value of a PChar (incrementing
it by some amount.)

Not that that's necessarily the best way to be doing whatever he's
doing, but _if_ he's doing that then it really does need to be a
var parameter.

Quote
> You need "var" only, when the modified pointer
>is of importance in the calling subroutine. If this really is your intention,
>then you must pass an alterable pointer to the subroutine, like "tempstr"
>above.

>IOW, you need "var" only, when a data object must be moved in memory, and the
>caller expects to receive the new starting position. If you want to prevent
>changes to the data, as well as to the pointer, you must mark the pointer as
>"const".

>DoDi

David C. Ullrich

Other Threads