Вверх ↑
Ответов: 4612
Рейтинг: 746
#1: 2020-01-03 12:15:28 ЛС | профиль | цитата
Galkov писал(а):
ты имеешь в виду исключения при попытке модификации в кодовом сегменте, защищенном от записи ???Так не помню я у нас таких строк...

"Кодовый сегмент" - это, насколько я понимаю у нас получается разве что в CharLower(PChar(S)), когда при пустой S Delphi приведением к PChar() подставляет ссылку на байт $00, лежащий где-то там же в коде функции рядом с проверкой строки на пустоту. А CharLower() с какого-то чуда, видимо, пытается этот 0 "ловернуть", хотя по достижении 0 должен был выйти из цикла перебора символов.

Но есть ещё секция констант "только для чтения" в исполняемом файле, где лежат строковые константы. Причём они остаются лежать там даже после множества присвоений переменным и передачи как аргументов функций. До применения UniqueString() или других методов копирования.
Add(MainForm,2953706,21,105)
{
Position=1
}
Add(Button,10504036,168,105)
{
Left=170
Top=40
link(onClick,11970995:doWork,[])
}
Add(InlineCode,11970995,252,105)
{
WorkPoints=#6:doWork|
EventPoints=#8:onResult|
VarPoints=#4:Var1|4:Var2|
DataPoints=#5:Data1|5:Data2|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|4:uses|29: Windows, KOL, Share, Debug;|0:|4:type|29: THiAsmClass = class(TDebug)|11: private|0:|10: public|30: Data1, Data2: THI_Event;|29: onResult: THI_Event; |54: procedure doWork(var _Data: TData; Index: Word);|52: procedure Var1(var _Data: TData; Index: Word);|52: procedure Var2(var _Data: TData; Index: Word);|6: end;|0:|14:implementation|0:|5:const|19: STRCONST = 'AAA';|0:|0:|0:|60:procedure THiAsmClass.doWork(var _Data: TData; Index: Word);|3:var|13: S: string; |5:begin|16: S := STRCONST;|34: CharLower(Pointer(S)); // Падает|29: CharLower('BBB'); // Падает|4:end;|0:|0:|59:procedure THiAsmClass.Var1(var _Data: TData; Index: Word); |5:begin|22: dtInteger(_Data, 0);|4:end;|0:|59:procedure THiAsmClass.Var2(var _Data: TData; Index: Word); |5:begin|22: dtString(_Data, '');|4:end;|0:|4:end.|
}
Тут есть такой любопытный нюанс. Такие константы существовали бы у нас повсюду, где мы задаём строковые свойства по-умолчанию компонентов. Но в кодогенераторе стоит костыль при заполнении строковых свойств:
_prop_Name := PChar('XXX'#0);
Это делает строки в свойствах компонентов модифицируемыми. Но не защищает от возможности получить константу из какого-то другого места. Мне не понравилось, поэтому в данной редакции пакета я это убрал. Кроме того, это не позволяет использовать символ с кодом #0 в строковых свойствах.

Galkov писал(а):
а использование pointer(fn) - не воспринимается.
К счастью. Нужно иметь возможность получить указатель на строку без дельфийского самоуправства.

По форматированию - кроме отступов нужно учитывать ещё регистр идентификаторов, и некоторые правила вроде префиксов "T" для типов, "P" для ссылочных типов, "F" для приватных полей класса.
Скажем, я бы предпочел
function _StrCmp(Str, Msk: PChar): Boolean;
begin
while (Str^ <> #0) and (Msk^ <> #0) do
begin
if Msk^ = '*' then
begin
Result := _StrCmp(Str, Msk + 1);
if Result then Exit;
end
else
if Msk^ = '#' then
begin
if Str^ in ['0'..'9'] then Inc(Msk)
else Break;
end
else
if (Msk^ = '?') or (Msk^ = Str^) then Inc(Msk)
else Break;
Inc(Str);
end;

while Msk^ = '*' do Inc(Msk);

Result := (Str^ = #0) and (Msk^ = #0);
end;
карма: 26

0
Редактировалось 7 раз(а), последний 2020-05-26 16:50:33