Чим відрізняється тип String у Delphi2 і вище від аналогічного у Delphi1

B D2 і вище насправді використовується тип LongString замість String, а старий тип тепер називається ShortString (про що, до речі, написано в help). З того ж help можна дізнатися, що покажчик LongString вказує на nullterminated string і тому можливе звичайне приведення типу LongString до PChar (про що я і написав), яке зводиться просто до зміни вивіски. Там же можна дізнатися, що довжина рядка зберігається в dword перед покажчиком. Є також натяк на те, що при присвоєнні іншій рядку інформація не копіюється, а збільшується тільки лічильник посилань. Більш детальну інформацію можна почерпнути з system.pas:

Від себе додам:

Сама перемінна LongString вказує на байт, безпосередньо наступний за цією процедурою, там же знаходиться власне значення рядка. Значення '' (порожня рядок) представляється як покажчик nil, до речі, тому порівняння str = '' це швидка операція.

Тепер детальніше про лічильник посилань. Я вже говорив, що при присвоєнні копіювання не відбувається, а тільки збільшується лічильник. Коли він зменшується? Hу, очевидно, коли в результаті операції значення рядка змінюється, то для старого значення лічильник зменшується. Це зрозуміло. Більш незрозуміло, коли звільняються значення, на які посилаються поля деякого класу. Це відбувається в System. TObject.FreeInstance при виклику _FinalizeRecord, а інформація береться з vtInitTable (до речі, тут же очищаються Variant). Ще більш незрозуміло, коли звільняються перемінні String, які описані як локальні в процедурах/функціях/методах. Тут працює компілятор, які вставляє ці неявні операції в код цієї функції.

Тепер про тип PString. Насправді змінні цього типу вказують на такі ж значення, як і LongString, але для змінних цього типу для всіх операційзі створення/копіювання/видалення потрібно пам'ятати про ці самі лічильники посилань. Іноді без цього не обійтися. Ось операції для цього типу (sysutils.pas):

Можна зазначити, що явно поставити використання long strings можна декларацією