Whenever you take the address of a string element, this is considered a record in the eyes of the compiler. As for this, you now have a raw pointer to the insides of the string, and who knows what you plan to do with it. Thus, from his point of view, he plays in safety. He decides to make a unique copy of the string so that you can do everything you do with your raw pointer.
The code you compile:
Project2.dpr.13: r: = 'Hello';
00419EF8 8D45FC lea eax, [ebp- $ 04]
00419EFB BAA89F4100 mov edx, $ 00419fa8
00419F00 E827D2FEFF call @UStrLAsg
Project2.dpr.14: Writeln (NativeInt (PChar (@r [1])));
00419F05 8D45FC lea eax, [ebp- $ 04]
00419F08 E883D3FEFF call @UniqueStringU
00419F0D 8BD0 mov edx, eax
00419F0F A18CE64100 mov eax, [$ 0041e68c]
00419F14 E853B2FEFF call @ Write0Long
00419F19 E82EB5FEFF call @WriteLn
00419F1E E845A1FEFF call @_IOTest
Project2.dpr.15: s: = r;
00419F23 8D45F8 lea eax, [ebp- $ 08]
00419F26 8B55FC mov edx, [ebp- $ 04]
00419F29 E8FED1FEFF call @UStrLAsg
Project2.dpr.16: Writeln (NativeInt (PChar (@s [1])));
00419F2E 8D45F8 lea eax, [ebp- $ 08]
00419F31 E85AD3FEFF call @UniqueStringU
00419F36 8BD0 mov edx, eax
00419F38 A18CE64100 mov eax, [$ 0041e68c]
00419F3D E82AB2FEFF call @ Write0Long
00419F42 E805B5FEFF call @WriteLn
00419F47 E81CA1FEFF call @_IOTest
Project2.dpr.17: Result: = r;
00419F4C 8BC3 mov eax, ebx
00419F4E 8B55FC mov edx, [ebp- $ 04]
00419F51 E88ED1FEFF call @UStrAsg
Project2.dpr.18: Writeln (NativeInt (PChar (@Result [1])));
00419F56 8BC3 mov eax, ebx
00419F58 E833D3FEFF call @UniqueStringU
00419F5D 8BD0 mov edx, eax
00419F5F A18CE64100 mov eax, [$ 0041e68c]
00419F64 E803B2FEFF call @ Write0Long
00419F69 E8DEB4FEFF call @WriteLn
00419F6E E8F5A0FEFF call @_IOTest
The UniqueStringU call is UniqueStringU by copy-on-write.
source share