Сравнение PChar
Модератор: Модераторы
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Обеспечиваются за исключением констант типа shortstring.
- debi12345
- долгожитель
- Сообщения: 5761
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
завершающие #0 у строковых констант обеспечиваются компилятором (пример из fpc 2.6.0)
Точно, забыл
shortstring.
На тест не влияет
Добавлено спустя 44 минуты 22 секунды:
Хм, похоже что фпц 2.6 в любом режиме (турбо, дельфи, обджпас,.) любые строковые константы, имеющие присвоения в коде и посталвяющие аргументы в функции - предваряет длиной и завершает нулем.
А как в НЕконстантными приcвоениями PChar=AnsiString[1] в обход StrPCopy ? Это всегда надежно ?
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Ansistring, Widestring, Unicodestring - всегда автоматически завершаются нулем.
Shortstring - не завершается.
Shortstring - не завершается.
Для операций с короткими строками ($H-, string) как с ASCIIZ, несмотря на наличие у строковой константы завершающего #0, дополнительный завершающий #0 указывать придётся. Дело в том, что завершающий #0 строковой константы не входит в длину строки и дополнительно не обрабатывается (совместимость), соответственно, в короткую строку при её инициализации не копируется:
Код: Выделить всё
# s2 := 's2';
movl $U_P$PROGRAM$S2,%eax
movl $_$PROGRAM$_Ld3,%ecx
movl $255,%edx
call fpc_shortstr_to_shortstr
...
.section .data
.globl _PROGRAM$_Ld3
_PROGRAM$_Ld3:
.ascii \002"s2\000"
- debi12345
- долгожитель
- Сообщения: 5761
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
Я специально этот момент перепроверил - 0 присутсвует.
А как себя ведет AnsiStrComp на чистых (инициализированных константами) аргументах ? Тут либо она глючит, либо присвоение PChar:= String[1]. Пробовали вариант "выделение_памяти+StrPCopy" ?
Добавлено спустя 1 минуту 45 секунд:
Или все перевести на WideString+PWideChar ? Может какая-то фигня с локалями ?
А валидныйЪ PChar вообще может быть nil'ом? Касты же никогда его не возвращают.
- alexs
- долгожитель
- Сообщения: 4066
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
debi12345
Надо попробовать, но переписать не могу пока - я уже писал выше - этот код находится в ZEOS.
runewalsh
Ну как минимум функция олжна проверить коректность входных параметров.
И, кстати, в некоторых случаях оно работает правильно.
И в дельфи оно также работает нормально.
Надо попробовать, но переписать не могу пока - я уже писал выше - этот код находится в ZEOS.
runewalsh
Ну как минимум функция олжна проверить коректность входных параметров.
И, кстати, в некоторых случаях оно работает правильно.
И в дельфи оно также работает нормально.
- debi12345
- долгожитель
- Сообщения: 5761
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
А валидный PChar вообще может быть nil'ом
Функция кажется проверяет - иначе бы "падала" на AV.
Добавлено спустя 1 минуту 39 секунд:
я уже писал выше - этот код находится в ZEOS.
Вообще странно, что их код в этом месте - не юникодный. И о чем только думают
Понимания для (fpc-2.6.2/rtl/objpas/sysutils/sysstr.inc:484):
fpc-2.6.2/rtl/unix/cwstring.pp
fpc-2.6.2/rtl/win/sysutils.pp
fpc-2.6.2/rtl/objpas/sysutils/sysstr.inc
fpc-2.6.2/rtl/objpas/sysutils/sysint.inc
Добавлено спустя 3 минуты 23 секунды:
Так что нужно в первую очередь выяснять, а кто именно бросает исключение, какая из реализаций?
Код: Выделить всё
function AnsiStrComp(S1, S2: PChar): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
result:=widestringmanager.StrCompAnsiStringProc(s1,s2);
end;
fpc-2.6.2/rtl/unix/cwstring.pp
Код: Выделить всё
function StrCompAnsi(s1,s2 : PChar): PtrInt;
begin
result:=strcoll(s1,s2);
end;
...
StrCompAnsiStringProc:=@StrCompAnsi;
fpc-2.6.2/rtl/win/sysutils.pp
Код: Выделить всё
function Win32AnsiStrComp(S1, S2: PChar): PtrInt;
begin
result:=CompareString(LOCALE_USER_DEFAULT,0,s1,-1,s2,-1)-2;
end;
...
widestringmanager.StrCompAnsiStringProc:=@Win32AnsiStrComp;
fpc-2.6.2/rtl/objpas/sysutils/sysstr.inc
Код: Выделить всё
function GenericAnsiStrComp(S1, S2: PChar): PtrInt;
begin
Result:=0;
If S1=Nil then
begin
If S2=Nil Then Exit;
result:=-1;
exit;
end;
If S2=Nil then
begin
Result:=1;
exit;
end;
While (Result=0) and (S1^<>#0) and (S2^<>#0) do begin
Result:=Ord(S1^)-Ord(S2^); //!! Must be replaced by ansi characters !!
Inc(S1);
Inc(S2);
end;
if (Result=0) and (S1^<>S2^) then // loop ended because exactly one has #0
if S1^=#0 then // shorter string is smaller
result:=-1
else
result:=1;
end;
fpc-2.6.2/rtl/objpas/sysutils/sysint.inc
Код: Выделить всё
{$ifndef FPC_NOGENERICANSIROUTINES}
if not assigned(widestringmanager.StrCompAnsiStringProc) then
widestringmanager.StrCompAnsiStringProc:=@GenericAnsiStrComp;
Добавлено спустя 3 минуты 23 секунды:
Так что нужно в первую очередь выяснять, а кто именно бросает исключение, какая из реализаций?
- debi12345
- долгожитель
- Сообщения: 5761
- Зарегистрирован: 10.05.2006 23:41:15
- Откуда: Ташкент (Узбекистан)
Один фиг если строки однобайтные, то вайдменеджер - только для посчета ссылок.
И даже выневая "CompareString" вызывается не юникодной версии
А юникодная CompareStringW умеет сравнивать только до 128 символов. Короче - тема нифига не допилена по части юникодности.
И даже выневая "CompareString" вызывается не юникодной версии
Еще в начале написал, смотрите какая системная функция вызывается в линухе для сравнения, причина в ней. Сам бы посмотрел, но нет под рукой линуха с лазарем.
Это не баг. Нельзя работать с указателями на строки, как со строками. Только хардкор - lstrcmp
