Работа со строками через адрес (PString, Pointer)

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Re: Работа со строками через адрес (PString, Pointer)

Сообщение zub » 12.02.2014 22:47:08

>>Да, я абсолютно серьёзен. Покажите в документации (или хотя бы в исходниках fpc), что String(nil) — это всегда пустая строка, а не что-то невалидное.
http://www.freepascal.org/docs-html/ref ... 380003.2.6
If the string is empty (’’), then the internal pointer representation of the string pointer is Nil. If the string is not empty, then the pointer points to a structure in heap memory.

Исходников под рукой к сожалению нет, но там доказательств будет предостаточно

>>Это, конечно, перебор, ибо это базовая вещь и задокументирована. Но польза от такой проверки тоже может быть
Пользы от этого никакой нет, ибо это попытка выполнить работу компилятора и вынести ее в рантайм, хотя компилятор с ней прекрасно справится в compiletime
В данном примере TMySuperBool.false и boolean.false ничего общего не имеют, хоть и называются одинаково, компилятор не даст явно заменить одни другим. При желании програмист конечно может "кастануть" одно в другое, но это клиника... никакие проверки тут не помогут - лучше отрезать руки по самые колени))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Работа со строками через адрес (PString, Pointer)

Сообщение VirtUX » 13.02.2014 01:58:57

zub писал(а):If the string is empty (’’), then the internal pointer representation of the string pointer is Nil. If the string is not empty, then the pointer points to a structure in heap memory.

Отсюда я могу сделать заключение, что...
Код: Выделить всё
...
var
u: Pointer = nil;
begin
String(u) := 'Any string';
...

... не будет вызывать исключений?

Добавлено спустя 7 минут 12 секунд:
проверил:
Код: Выделить всё
var
  u: Pointer;
  s: string;
begin

  String(u) := '';
  if Assigned(u) then s := 'true'
  else s := 'false';
  Edit1.Text:= s; // s = 'false'
  String(u) := 'wer';
  if Assigned(u) then s := 'true'
  else s := 'false';
  Edit2.Text:= s;  // s = 'true'

все верно -
VirtUX писал(а):не будет вызывать исключений
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Работа со строками через адрес (PString, Pointer)

Сообщение Vadim » 13.02.2014 08:22:08

Если чисто теоретически, то String(u) приводит указатель к типу String, но память под string не выделяет. Могу ошибаться, поэтому лучше всего спрашивать у разработчиков FreePascal.
Но если я прав, то просто используются ячейки памяти в куче без указания, что они заняты. Значит их кто-нибудь может перехватить на свои нужды.
Integer(u) - тот же принцип, но SizeOf(Pointer) = SizeOf(Integer), поэтому чужие ячейки памяти тут не используются.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Работа со строками через адрес (PString, Pointer)

Сообщение zub » 13.02.2014 08:52:44

VirtUX писал(а):Отсюда я могу сделать заключение, что...Код: Выделить всё...varu: Pointer = nil;beginString(u) := 'Any string';...... не будет вызывать исключений?
проверил:

И в проверке забыл инициализировать u - так будет работать до поры пока в u не окажется какойнить мусор

Vadim писал(а):Если чисто теоретически, то String(u) приводит указатель к типу String, но память под string не выделяет.

выделяет - в этом случае все точно также какбудьто u объявлен стрингом, только без его автоматической инициализации\финализации, поэтому это нужно сделать руками
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Работа со строками через адрес (PString, Pointer)

Сообщение VirtUX » 13.02.2014 09:20:29

zub писал(а):И в проверке забыл инициализировать u

Так вот же:
VirtUX писал(а):String(u) := '';

Согласно сказанного:
zub писал(а):If the string is empty (’’), then the internal pointer representation of the string pointer is Nil.

и:
zub писал(а):Это особенность string`а, пустая строка представляется nil`ем в переменной, так было всегда


Добавлено спустя 57 секунд:
и при проверке (как видно из комментария) - это действительно - так
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Работа со строками через адрес (PString, Pointer)

Сообщение zub » 13.02.2014 09:34:41

>>Так вот же:
нет, это нето

u=nil;
просто запишет nil в указатель, а
String(u) := '';
перед записью проверит куда указывает u и если там не nil то попытается уменьшить рефкаунт и если надо финализировать строку, считая что u указывает на область памяти выделенную ранее "стринговыми" операциями. такчто именно на такой инициализации всё и вылетит, если u будет не инициализирован нормальным способом (например локальной переменной, в которой обычно лежит мусор)
перед кастованием указателя в стринг (не шортстринг) нужно обязательно позаботиться чтобы в нем был NIL или указатель на валидную строку
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Работа со строками через адрес (PString, Pointer)

Сообщение Дож » 13.02.2014 10:25:59

zub писал(а):>>Да, я абсолютно серьёзен. Покажите в документации (или хотя бы в исходниках fpc), что String(nil) — это всегда пустая строка, а не что-то невалидное.
http://www.freepascal.org/docs-html/ref ... 380003.2.6
If the string is empty (’’), then the internal pointer representation of the string pointer is Nil. If the string is not empty, then the pointer points to a structure in heap memory.

Исходников под рукой к сожалению нет, но там доказательств будет предостаточно


Верю, но документация лучше исходников — в исходниках пришлось бы проверять под разными платформами :)

С этого и надо было начинать, а то в теме постоянно идёт «проверка кодом, что это отработало и не упало».
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Работа со строками через адрес (PString, Pointer)

Сообщение zub » 13.02.2014 10:41:16

>>а то в теме постоянно идёт «проверка кодом, что это отработало и не упало».
стринги (как и вся прямая работа с памятью) очень копризная штука, они могут падать только на "компе тёти Груни" или на "25ом" вызове этой безобидной процедуры или вообще в другом месте (когда какаято структура данных нужная сейчас в несвязанном напрямую с прошлым кодом месте была ранее "испорчена" неверным обращением со стрингами или памятью). Поэтому "проверка кодом" нужна очень серъезная, а не скомпилилось-неупало - значит всё ок.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Работа со строками через адрес (PString, Pointer)

Сообщение VirtUX » 13.02.2014 11:22:45

zub, спасибо за подробные разъяснения!
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Работа со строками через адрес (PString, Pointer)

Сообщение Дож » 13.02.2014 13:02:51

стринги (как и вся прямая работа с памятью) очень копризная штука, они могут падать только на "компе тёти Груни" или на "25ом" вызове этой безобидной процедуры или вообще в другом месте (когда какаято структура данных нужная сейчас в несвязанном напрямую с прошлым кодом месте была ранее "испорчена" неверным обращением со стрингами или памятью). Поэтому "проверка кодом" нужна очень серъезная, а не скомпилилось-неупало - значит всё ок.


10 постами выше Вы сами высказывались против Assert'ов :)
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Работа со строками через адрес (PString, Pointer)

Сообщение zub » 13.02.2014 13:19:31

Я не против асертов, даже за)) просто в том примере они лишние - всё видно по соощениям компилятора.
Но от того молча ли упадет программа или предварительно поплачется в окно ассерта - пользователю легче не станет, а програмисту гораздо полезней лог и отладчик))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Работа со строками через адрес (PString, Pointer)

Сообщение Дож » 13.02.2014 13:23:54

Я не против асертов, даже за)) просто в том примере они лишние - всё видно по соощениям компилятора.

Как раз таки для AnsiString тот ассерт сработал нормально (ошибка вываливалась для ShortString, и не на тему того, что nil <> '', а на тему того, что один тип не удалось сконвертировать). Ну, и тот мой ассерт проверяет не совсем то, что нужно, его нужно немного переписать, но в целом проверку nil = '' я не считаю такой уж плохой затеей, если относится с подозрением к строкам.

Ассерт сразу скажет в чём проблема, а AV может себя долго не проявлять.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Работа со строками через адрес (PString, Pointer)

Сообщение zub » 13.02.2014 13:50:12

Там была проверка того что задокументировано. Я не сторонник теории заговора, поэтому имхо это лишнее))
Проверка u на nil тоже выглядит странно - инициализировать забыли, а проверить не забыли - лучше стараться наоборот))
В общем случае в переменной лежит указатель на строку, а не nil и проверить его на валидность не получится. Такчто это не более чем проверка "а не забыли ли мы инициализировать переменную" или "не разучился ли компилятор сам инициализировать переменные" - в ходе работы программы и реальных багов наврятли поможет
По моему асерту место там, где несошлась контрольная сумма, не нашлось то что должно было найтись и т.п. случаях, но это имхо... а с тем что "лишних" проверок много не бывает я абсолютно согласен))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Пред.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11

Рейтинг@Mail.ru