Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Pchar typecast to temporary string, still in scope or not?


This question is answered.


Permlink Replies: 7 - Last Post: Jan 15, 2018 11:59 AM Last Post By: Mark Marks
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Pchar typecast to temporary string, still in scope or not?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 9, 2018 1:04 AM
Hello all,

many routines in the Windows API require char* parameters.

Consider the following situation:

- I have a string list
- I want to display the contents of the string list in a message box with as few hassles as possible.

Would the following be safe?

    if MyStringList.count > 0 then
        MessageBox(Handle,
        pchar(MyStringList.Text),
        'Information', MB_OK + MB_ICONINFORMATION + MB_TOPMOST);

My reason for asking:

tStringlist.text is a property "getter" function that returns a string. That temporary string is released by Delphi as soon as it goes out of scope. What I don't know is if the "pchar()" typecast keeps the temporary string in scope or not. Is the messagbox() routine called with a pchar that is still valid?

Kind regards,
Arthur

Edited by: Arthur Hoornweg on Jan 9, 2018 1:04 AM

Lajos Juhasz

Posts: 801
Registered: 3/14/14
Re: Pchar typecast to temporary string, still in scope or not? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 9, 2018 6:24 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:


My reason for asking:

tStringlist.text is a property "getter" function that returns a
string. That temporary string is released by Delphi as soon as it
goes out of scope. What I don't know is if the "pchar()" typecast
keeps the temporary string in scope or not. Is the messagbox()
routine called with a pchar that is still valid?

I'm a bit confused how could the string go out of the scope while a
modal dialog is displayed?

I've double checked:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx

The first sentence is:

MessageBox function
Displays a modal dialog box that contains a system icon, a set of
buttons, and a brief application-specific message, such as status or
error information.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Pchar typecast to temporary string, still in scope or not? [Edit]
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 9, 2018 7:02 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

many routines in the Windows API require char* parameters.

More accuately, they require TCHAR* parameters, where TCHAR is either
char or wchar_t depending on project configuration.

Consider the following situation:

- I have a string list
- I want to display the contents of the string list in a message box
with as few hassles as possible.

Would the following be safe?

Yes, that is safe (on a side note, you should be using 'or' instead of
'+' to combine flags). But, why not use a Delphi-style dialog box
instead, like ShowMessage() or MessageDlg()? They take String
parameters.

if MyStringList.count > 0 then
  ShowMessage(MyStringList.Text);


if MyStringList.count > 0 then
  MessageDlg(MyStringList.Text, mtInformation, [mbOK], 0);


My reason for asking:

tStringlist.text is a property "getter" function that returns a
string. That temporary string is released by Delphi as soon as it
goes out of scope.

Yes, but that temporary won't go out of scope until after the end of
the entire statement that uses it (after MessageBox() exits).

What I don't know is if the "pchar()" typecast keeps the temporary
string in scope or not.

The temporary string will be in scope, but it is not the type-cast that
does that.

Is the messagbox() routine called with a pchar that is still valid?

Yes.

--
Remy Lebeau (TeamB)
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Pchar typecast to temporary string, still in scope or not? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2018 2:10 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Arthur Hoornweg wrote:

Yes, that is safe (on a side note, you should be using 'or' instead of
'+' to combine flags).

This was a quick example generated by the Cnpack Messagebox wizard. It uses "+" instead of "or".

But, why not use a Delphi-style dialog box instead, like ShowMessage()
or MessageDlg()? They take String parameters.

That circumvents the whole issue, sure, but it doesn't help me to understand the scope behaviour of typecasted strings. At first glance, a typecast happens to "look" just like a function call. So my gut feeling was that it might also "behave" like a function call and introduce scope problems on managed types. Let me clarify what I mean, by rewriting the typecast as a function:

Function _pchar(const s:string):pchar;
begin
  if s='' then result:=NIL else result:=@s[1];
end;
 
Procedure Test;
begin
    MessageBoxW(Handle, _pchar(MyStringList.Text), 'Information', MB_OK);  
end;

...From my point of view, the scope of the temporary string "Text" ends in the closing parenthesis of the _pchar() call.

So would "Text" be destroyed after calling the _pchar() function, after calling the MessageboxW() function or upon exiting the Test() function itself? Apart from scope theory, there might even be a hidden variable in play since the Delphi compiler has the peculiarity that it compiles functions with a string result into a procedure with an OUT parameter.

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Pchar typecast to temporary string, still in scope or not? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2018 9:09 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

This was a quick example generated by the Cnpack Messagebox wizard.
It uses "+" instead of "or".

The wizard is wrong.

At first glance, a typecast happens to "look" just like a function
call.

It can be, depending on the type involved. Use the debugger to verify.

Let me clarify what I mean, by rewriting the typecast as a function:

Function _pchar(const s:string):pchar;
begin
  if s='' then result:=NIL else result:=@s[1];
end;
 
Procedure Test;
begin
    MessageBoxW(Handle, _pchar(MyStringList.Text), 'Information',
MB_OK); end;

...From my point of view, the scope of the temporary string "Text"
ends in the closing parenthesis of the _pchar() call.


Maybe from your POV, but not from the compiler's POV. If that
happened, the temporary would go out of scope and be destroyed before
MessageBoxW() is called. Temporaries remain in scope until the
encompassing statement is fully executed (until the ';' is reached).

So would "Text" be destroyed after calling the _pchar() function

Sometime after, yes. But not *immediately' after, no.

after calling the MessageboxW() function

Sometime after, yes.

or upon exiting the Test() function itself?

In this case, yes.

Apart from scope theory, there might even be a hidden variable in play
since the Delphi compiler has the peculiarity that it compiles
functions with a string result into a procedure with an OUT parameter.

Yes, there is a hidden variable involved. If you had debugged your
code and looked at the compiler output at runtime, you would have seen
that your Test() procedure is compiled to the equivilent of the
following code:

Procedure Test;
var
  _temp: string;
begin
  _temp := MyStringList.Text;
  try
    MessageBoxW(Handle, _pchar(_temp), 'Information', MB_OK);
  finally
    _temp := '';
  end;
end;


--
Remy Lebeau (TeamB)
Mark Marks

Posts: 269
Registered: 9/11/00
Re: Pchar typecast to temporary string, still in scope or not? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2018 9:35 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

Arthur Hoornweg wrote:

This was a quick example generated by the Cnpack Messagebox wizard.
It uses "+" instead of "or".

The wizard is wrong.

Just wondering. Why is it wrong? Both work, right?
Example from system.include help page:

The Include(S,I) expression corresponds to S := S + [I], where S is a
set type variable and I is an expression of a type compatible with the
base type of S.

The help file under Set Operators

Operator Operation Operand Types Result Type Example
+ union set set Set1 + Set2
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Pchar typecast to temporary string, still in scope or not? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2018 10:38 AM   in response to: Mark Marks in response to: Mark Marks
Mark Marks wrote:

Just wondering. Why is it wrong? Both work, right?

Not always. The bitwise 'OR' operator is not the same thing as the
numerical '+' operator.

Example from system.include help page:

The Include(S,I) expression corresponds to S := S + [I], where S is a
set type variable and I is an expression of a type compatible with the
base type of S.

A Set and a bitmask are two different things (though a Set is
implemented as a bitmask internally). The '+' operator you are
referring to applies to a Set. The uType parameter of MessageBox() is
a bitmask, not a Set. A bitmask is manipulated using bitwise
operators, like 'OR', not Set operators.

--
Remy Lebeau (TeamB)
Mark Marks

Posts: 269
Registered: 9/11/00
Re: Pchar typecast to temporary string, still in scope or not? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2018 11:59 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

A bitmask is manipulated using bitwise
operators, like 'OR', not Set operators.

Right, my error, I failed to look at the usage.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02