> 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)
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.
> 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)
"Mike Williams [TeamB]" <mlwil...@gmail.com> wrote in message
news:Xns956D7021C2...@207.105.83.66...
> 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.
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
@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
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
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
Sorry for creating confusion by not stating that I thought of S as a
shortstring!
regards Sven
With the exception that one method works while the other crashes: yes,
identically (if you really want to call it that way).
JensG
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
> 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!
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
> 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.