Всё началось с того, что я обратил внимание на то, что стандартная процедура Val в случае ошибки перевода "портит" предыдущее значение результата.
Ладно, думаю, напишу свою процедуру, которая не занимается бессовестной порчей данных. Но тут возник вопрос: в оригинальной процедуре тип результата явно не задаётся: "Procedure Val (const S : string; Var V; var Code : word);"
Как же процедура определяет тип переменной?
Сейчас вышел из положения, написав на каждый необходимый тип данных по отдельной процедуре, но хочется сделать универсальное решение.
Определить тип переданной в процедуру переменной
Модератор: Модераторы
-
Stargazer44
- новенький
- Сообщения: 10
- Зарегистрирован: 24.12.2013 23:49:31
>>Но тут возник вопрос: в оригинальной процедуре тип результата явно не задаётся:
где ты это увидел?
ppsrc-rtl-inc-lstrings.pp (слэши форум почемуто трет)
Вот так и определяет
Добавлено спустя 13 минут 17 секунд:
val и str - внутренние функции компилятора, с ними обычные подходы не очень прокатывают
где ты это увидел?
ppsrc-rtl-inc-lstrings.pp (слэши форум почемуто трет)
Код: Выделить всё
...
Procedure Val (Const S : LongString; var R : real; Var Code : Integer);
{Procedure Val (Const S : LongString; var D : Double; Var Code : Integer);}
Procedure Val (Const S : LongString; var E : Extended; Code : Integer);
Procedure Val (Const S : LongString; var C : Cardinal; Code : Integer);
Procedure Val (Const S : LongString; var L : Longint; Var Code : Integer);
Procedure Val (Const S : LongString; var W : Word; Var Code : Integer);
Procedure Val (Const S : LongString; var I : Integer; Var Code : Integer);
Procedure Val (Const S : LongString; var B : Byte; Var Code : Integer);
Procedure Val (Const S : LongString; var SI : ShortInt; Var Code : Integer);
...
Вот так и определяет
Добавлено спустя 13 минут 17 секунд:
val и str - внутренние функции компилятора, с ними обычные подходы не очень прокатывают
Теоретически через тип Variant можно сделать универсальное решение и даже оно будет работать, но это будет такой тормоз с кучей перегружаемого кода, не совершайте моих общибок , что лучше как, правильно выше написали сделать, причем не используя сырцы оригинальной мегакривой кривой реализации Val....
>>причем не используя сырцы оригинальной мегакривой кривой реализации Val....
Чем она мегакривая? Проблема "порчи" данных взята из пальца
Чем она мегакривая? Проблема "порчи" данных взята из пальца
В худшем случае, что перевелось, то и записалось. Тем не менее, никто не мешает:
Код: Выделить всё
Val(s,t,code);
if code=0 then n:=t;
zub писал(а):Чем она мегакривая?
Посмотрите сами исходный код процедур. Безумные преобразования и приведения строк, передача оных строк целиком по значению вместо ровно одной ссылки на начало конвертации ( а ежели исходная строка в несколько мегабайт длинной, тоже через copy выкусывать нужный кусок?) в и использование зачем-то динамической памяти. Я как-то делал для себя аналог, так, так вроде в 15 раз быстрей работало даже без ассемблерных вставок и оптимизаций.
beria писал(а):Безумные преобразования и приведения строк
Это не System.Val. Это реализация оберток для LongString, в том числе и Val:
src/rtl/inc/lstrings.pp
Код: Выделить всё
{
This file contains the implementation of the LongString type,
and all things that are needed for it.
LongSTring is defined as a 'silent' pchar :
a pchar that points to :
@ : Longint for size
@+4 : Unused byte;
@+5 : String;
So LS[i] is converted to the address @LS+4+i.
beria писал(а):а ежели исходная строка в несколько мегабайт длинной
Копируется максимум 255 байт. Тем не менее, вы точно уверены, что именно эту строку нужно было передавать Val?
Опять же, почему не ShortString для непосредственно System.Val, что б уж без преобразований и копирований?
