Delphi XE4 immutable strings

后端 未结 1 1224
天命终不由人
天命终不由人 2021-02-05 11:41

With Delphi XE4 for the iOS platform a new string type was introduced: Immutable zero based strings. So far Delphi had copy on write mutable strings. So the question is, what do

1条回答
  •  青春惊慌失措
    2021-02-05 12:35

    According to Marco Cantù's whitepaper, the string data type in the XE4 iOS target is not in fact immutable, although he seems to contradict himself.

    He says:

    In the new Delphi LLVM-based compiler, there is one string type, representing Unicode strings (UTF16), and mapped to the current string type in Delphi XE3 (an alias for the UnicodeString type on the Windows compiler). However, this new string type uses a different memory management model. The string type is still reference counted, but it is immutable, which means you cannot modify the string contents once it is constructed.

    But he then goes on to say:

    In other words strings are now Unicode-based, soon-to-become immutable, and reference-counted.

    And also:

    Where things start to change, however, is when you modify an existing string, not by replacing it with a new value (in which case you get a brand new string) but when you modify one of its elements, as shown in this line of code (and also in the previous section, where I introduced the topic):

    Str1 [3] := 'x';
    

    All Delphi compilers use a copy-on-write semantics: If the string you modify has more than one reference, it is first copied (adjusting the reference counts of the various strings involved as required) and later modified.

    The new compiler does something very similar to the classic one. It implements a copy-on-write mechanism, unless there is a single reference to the string, in which case the string gets modified in place. As an example, consider the following code, which outputs the in-memory location of the actual string.

    And he then shows a picture of an iOS device with mutating strings.

    And in the official documentation we have:

    Strings are immutable (constant), so you cannot index into a string as an array and manipulate the characters in a string. If you attempt to modify a string, the Delphi mobile compilers might emit the message W1068 Modifying strings in place may not be supported in the future (Delphi). You can specify whether the message x1068 is emitted as a warning or an error. In the Hints and Warnings page, set the warning "Modifying strings in-place...." to "true" or "error".

    So I interpret all that as meaning that the XE4 release of the iOS compiler still has mutable strings. The developers really don't want you to mutate your strings any more and are telling you that strings are immutable on the mobile compilers. But they do appear still to be mutable. Go figure!


    However, you have been served notice that in a future release, the string may become immutable.

    You can prepare for that future release now by setting

    {$WARN IMMUTABLE_STRINGS WARN}
    

    which will give you an idea of the impact of the change. If you want to buckle up and stop mutating strings, you can do this:

    {$WARN IMMUTABLE_STRINGS ERROR}
    

    Once you do that you'll need to convert code that accesses individual string elements. I suspect you'll be surprised by how little such code there is. I just compiled 600,000 lines of code and saw only 120 instances of the warning. And most of those were in third party units. I've seen quite a stir about this change, but I honestly don't believe that very much code mutates strings. In the overwhelming majority of cases strings are built up by concatenation, or by calls to functions like Format. That code is not affected by this.

    I don't think there are any great pitfalls. You can use {$WARN IMMUTABLE_STRINGS ...} to let the compiler guide you through the process. Any code that mutates strings should be converted to use TStringBuilder.

    As for the benefits of immutability, I refer you to Why .NET String is immutable?

    If you are using the traditional Windows or OSX compilers then I see no compelling reason to change. The iOS compiler is brand new. The change to immutable strings has been floated, but it may never happen. It may happen only on the mobile compilers and never on the traditional compilers. Right now, I would sit tight, and wait to see how it all plays out.

    0 讨论(0)
提交回复
热议问题