Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is PChar('') guaranteed to be a pointer to #0 (not nil)?

I understand that in Delphi, an empty string (AnsiString or WideString) can be represented by a nil pointer, or by a pointer to an actual empty string.

By experiment I've shown that in Delphi XE2 (with particular compiler settings) PChar('') <> nil. But is this guaranteed, or might it change in a future version, or be dependent on some compiler setting?

I'm having a crisis of confidence. If anyone can give me a definitive answer I'd be grateful.

like image 504
Ian Goldby Avatar asked Feb 12 '13 15:02

Ian Goldby


1 Answers

Yes. Type casts from string literals to PChar will never be null pointers. Type casts from strings of the same character type to PChar won't be null, either. (String to PChar, AnsiString to PAnsiChar, etc.)

Type casts of other things to PChar may be null, though. (Pointer to PChar, AnsiString to PWideChar, etc.)

The documentation covers this in the Mixing Delphi Strings and Null-Terminated Strings section of the String Types topic:

You can also cast a UnicodeString or AnsiString string as a null-terminated string. The following rules apply:

  • If S is a UnicodeString, PChar(S) casts S as a null-terminated string; it returns a pointer to the first character in S. Such casts are used for the Windows API. For example, if Str1 and Str2 are UnicodeString, you could call the Win32 API MessageBox function like this: MessageBox(0, PChar(Str1), PChar(Str2), MB_OK);. Use PAnsiChar(S) if S is an AnsiString.
  • You can also use Pointer(S) to cast a string to an untyped pointer. But if S is empty, the typecast returns nil.
  • PChar(S) always returns a pointer to a memory block; if S is empty, a pointer to #0 is returned.
  • When you cast a UnicodeString or AnsiString variable to a pointer, the pointer remains valid until the variable is assigned a new value or goes out of scope. If you cast any other string expression to a pointer, the pointer is valid only within the statement where the typecast is performed.
  • When you cast a UnicodeString or AnsiString expression to a pointer, the pointer should usually be considered read-only. You can safely use the pointer to modify the string only when all of the following conditions are satisfied:
    • The expression cast is a UnicodeString or AnsiString variable.
    • The string is not empty.
    • The string is unique - that is, has a reference count of one. To guarantee that the string is unique, call the SetLength, SetString, or UniqueString procedures.
    • The string has not been modified since the typecast was made.
    • The characters modified are all within the string. Be careful not to use an out-of-range index on the pointer.

The same rules apply when mixing WideString values with PWideChar values.

like image 113
Rob Kennedy Avatar answered Nov 05 '22 14:11

Rob Kennedy