Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Is Pchar equivalent to @

21 views
Skip to first unread message

Mike Williams [TeamB]

unread,
Sep 23, 2004, 10:38:19 AM9/23/04
to
On 23 Sep 2004, "Yehia Ahmed" <yeh...@hotmail.com> wrote:

> is this true, i mean are those lines identical:
>
> ShellExecute(self.Handle , 'Open', pchar(repath), nil, nil, 0);
>
> ShellExecute(self.Handle , 'Open', @repath, nil, nil, 0);

No, they're different. The second example should be @repath[1] which takes
the address of the first character of the string.

--
-Mike (TeamB)

Avatar Zondertau

unread,
Sep 23, 2004, 10:46:45 AM9/23/04
to
> > is this true, i mean are those lines identical:
> >
> > ShellExecute(self.Handle , 'Open', pchar(repath), nil, nil, 0);
> >
> > ShellExecute(self.Handle , 'Open', @repath, nil, nil, 0);
>
> No, they're different. The second example should be @repath[1] which
> takes the address of the first character of the string.

This is still wrong (at least theoretically) since you may be referring
to an empty string. In this case you're dereferencing it. This may not
cause access violations, since the only thing that is used of the
dereferenced nil is a pointer to it (a nil again), but still it's not a
nice thing to do.

The PChar cast is recommended in the Delphi help and therefore
preferable.

Mike Williams [TeamB]

unread,
Sep 23, 2004, 11:01:22 AM9/23/04
to
On 23 Sep 2004, "Avatar Zondertau" <avatarz...@hotmail.com> wrote:

> The PChar cast is recommended in the Delphi help and therefore
> preferable.

Absolutely. The @st[1] trick is dangerous but @st is even worse as that
refers to a portion of the string header data.

--
-Mike (TeamB)

Yehia Ahmed

unread,
Sep 23, 2004, 11:10:59 AM9/23/04
to
don't really understand, the @ gives the pointer to the string and so does
pchar, so what's the problem?

"Mike Williams [TeamB]" <mlwil...@gmail.com> wrote in message
news:Xns956D7021C2...@207.105.83.66...

Jens Geyer

unread,
Sep 23, 2004, 11:27:13 AM9/23/04
to
Hello Yehia Ahmed,

> don't really understand, the @ gives the pointer to the string and so
> does pchar, so what's the problem?

The difference comes into view when you try this on an empty string. See the
code below.
JensG

program Project1;
{$APPTYPE CONSOLE}
{$D+,L+,O-}
uses sysutils;
var s1, s2 : string;
pc1,pc2 : PChar;
begin
s1 := 'not empty';
s2 := ''; // empty

// both of these will return the same result
pc1 := PChar(s1);
pc2 := @s1[1];

// the second line will crash because s1 is empty = NIL
pc1 := PChar(s2); // pc1 then points to ''
pc2 := @s2[1]; // will crash
end.

Avatar Zondertau

unread,
Sep 23, 2004, 11:29:39 AM9/23/04
to
> don't really understand, the @ gives the pointer to the string and so
> does pchar, so what's the problem?

The PChar cast implicitly calls _LStrToPChar, which prevents passing
nil as a null terminated string. This is safer than possibly
dereferencing a nil pointer. Also the Delphi help specifies that the
PChar cast is safe. This meanss that it is guaranteed to remain safe in
future compiler versions, even if the internal storage for the string
type would change. This is not the case for the other approach, which
is more of a hack.

For more info on using PChar read Rudy Velthuis' (one of the TeamB
members) article on the subject:
http://rvelthuis.bei.t-online.de/articles/articles-pchars.htm

Peter Below (TeamB)

unread,
Sep 23, 2004, 3:02:36 PM9/23/04
to
In article <4152...@newsgroups.borland.com>, Yehia Ahmed wrote:
> don't really understand, the @ gives the pointer to the string and so does
> pchar, so what's the problem?

@st gives you the address of the string *variable*, which is completely
different from the address of the first character in the string if we are
talking about Ansistrings here.


--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


Sven Pran

unread,
Sep 23, 2004, 5:51:03 PM9/23/04
to

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote in message
news:VA.0000b34...@nomail.please...

> In article <4152...@newsgroups.borland.com>, Yehia Ahmed wrote:
>> don't really understand, the @ gives the pointer to the string and so
>> does
>> pchar, so what's the problem?
>
> @st gives you the address of the string *variable*, which is completely
> different from the address of the first character in the string if we are
> talking about Ansistrings here.

But am I right that @S[1] and PChar(S) will be the same except that he
must also make certain S is terminated with a "null" character?

(And of course I believe that PChar(S) creates dynamically a separate
null-terminated string rather than pointing to the original S)

regards Sven


Rob Kennedy

unread,
Sep 23, 2004, 7:28:02 PM9/23/04
to
Sven Pran wrote:
> But am I right that @S[1] and PChar(S) will be the same except that he
> must also make certain S is terminated with a "null" character?

Delphi strings are always null terminated, except when they're empty.
When they are empty, it is illegal to ask for the first character via
S[1] since that character doesn't exist, and thus you cannot get a
pointer to it, either.

> (And of course I believe that PChar(S) creates dynamically a separate
> null-terminated string rather than pointing to the original S)

False. The LStrToPChar function (which is what gets triggered when you
cast a string variable to PChar) will either return the same pointer
value already held in S or return a pointer to a null character. In
neither case does any memory get allocated. The body of LStrToPChar
contains a zero byte inline, and the funciton returns a pointer to that
byte.

--
Rob

Sven Pran

unread,
Sep 24, 2004, 2:26:27 AM9/24/04
to

"Rob Kennedy" <.> wrote in message news:41535bf6$1...@newsgroups.borland.com...

Sorry for creating confusion by not stating that I thought of S as a
shortstring!

regards Sven


Jens Geyer

unread,
Sep 24, 2004, 3:46:41 AM9/24/04
to
> But am I right that @S[1] and PChar(S) will be the same except that he
> must also make certain S is terminated with a "null" character?

With the exception that one method works while the other crashes: yes,
identically (if you really want to call it that way).

JensG


Peter Below (TeamB)

unread,
Sep 24, 2004, 7:32:55 AM9/24/04
to
In article <4153...@newsgroups.borland.com>, Sven Pran wrote:
> But am I right that @S[1] and PChar(S) will be the same except that he
> must also make certain S is terminated with a "null" character?

Yes.

> (And of course I believe that PChar(S) creates dynamically a separate
> null-terminated string rather than pointing to the original S)

Well, what it does is call UniqueString on S, which may or may not cause a
copy to be made to get a string with a reference count of 1. The @ operator
applied to a character in the string will also cause UniqueString to be
called in newer versions of Delphi, so @S[1] acts the same as a PChar cast.

Sven Pran

unread,
Sep 24, 2004, 7:59:40 AM9/24/04
to

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote in message
news:VA.0000b35...@nomail.please...

> In article <4153...@newsgroups.borland.com>, Sven Pran wrote:
>> But am I right that @S[1] and PChar(S) will be the same except that he
>> must also make certain S is terminated with a "null" character?
>
> Yes.
>
>> (And of course I believe that PChar(S) creates dynamically a separate
>> null-terminated string rather than pointing to the original S)
>
> Well, what it does is call UniqueString on S, which may or may not cause a
> copy to be made to get a string with a reference count of 1. The @
> operator
> applied to a character in the string will also cause UniqueString to be
> called in newer versions of Delphi, so @S[1] acts the same as a PChar
> cast.

How will that be when S is a shortstring or a character array and I use
@S[1] as a parameter when calling a subroutine having the formal parameter
list: (var XS: PChar; const XL: word); (XL is of course the buffer
length)?

Now it is important that the @ operator does not create a copy of S isn't
it?

regards Sven


Iain Macmillan

unread,
Sep 24, 2004, 12:24:50 PM9/24/04
to

In article <41535bf6$1...@newsgroups.borland.com>, Rob Kennedy <.> wrote:

> Sven Pran wrote:
>> But am I right that @S[1] and PChar(S) will be the same except that he
>> must also make certain S is terminated with a "null" character?
>
> Delphi strings are always null terminated, except when they're empty.

Well, I wasn't sure about this, nor it seems was Sven, so when he speaks of
making certain I think of doing something like
S:=S+#0;


> When they are empty, it is illegal to ask for the first character via
> S[1] since that character doesn't exist, and thus you cannot get a
> pointer to it, either.

and if 'making certain' means this, the string can't ever be empty. It
always consists of one char at least even if just the null char..


> Delphi strings are always null terminated

How would you verify this anyway..
if s[length(s)+1] <> #0 then
.. looks illegal to me!

Sven Pran

unread,
Sep 24, 2004, 7:24:16 PM9/24/04
to

"Iain Macmillan" <he...@ariesps.co.uk> wrote in message
news:4154...@newsgroups.borland.com...

If S is a longstring then it will always be null terminated.
I was thinking of S as a shortstring in which case it is perfectly OK
to code S := 'some text' + #0 when you "load" S

After all the only situation I know of where such contruction is
needed is when calling a subprogram which takes a PChar as
a var parameter (and modifies this parameter). Then the calling
program must provide a buffer to hold this parameter and pass
this buffer as PChar.

Sven


Peter Below (TeamB)

unread,
Sep 25, 2004, 6:53:03 AM9/25/04
to
In article <41540c2d$1...@newsgroups.borland.com>, Sven Pran wrote:

> How will that be when S is a shortstring or a character array and I use
> @S[1] as a parameter when calling a subroutine having the formal parameter
> list: (var XS: PChar; const XL: word); (XL is of course the buffer
> length)?
>
> Now it is important that the @ operator does not create a copy of S isn't
> it?

It will not create a copy in those cases, only if applied to an Ansistring.

0 new messages