Страница 1 из 1

Определить тип переданной в процедуру переменной

СообщениеДобавлено: 19.02.2017 12:55:45
Stargazer44
Всё началось с того, что я обратил внимание на то, что стандартная процедура Val в случае ошибки перевода "портит" предыдущее значение результата.
Ладно, думаю, напишу свою процедуру, которая не занимается бессовестной порчей данных. Но тут возник вопрос: в оригинальной процедуре тип результата явно не задаётся: "Procedure Val (const S : string; Var V; var Code : word);"
Как же процедура определяет тип переменной?
Сейчас вышел из положения, написав на каждый необходимый тип данных по отдельной процедуре, но хочется сделать универсальное решение.

Re: Определить тип переданной в процедуру переменной

СообщениеДобавлено: 19.02.2017 13:11:41
zub
>>Но тут возник вопрос: в оригинальной процедуре тип результата явно не задаётся:
где ты это увидел?

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 - внутренние функции компилятора, с ними обычные подходы не очень прокатывают

Re: Определить тип переданной в процедуру переменной

СообщениеДобавлено: 19.02.2017 21:04:03
beria
Теоретически через тип Variant можно сделать универсальное решение и даже оно будет работать, но это будет такой тормоз с кучей перегружаемого кода, не совершайте моих общибок , что лучше как, правильно выше написали сделать, причем не используя сырцы оригинальной мегакривой кривой реализации Val....

Re: Определить тип переданной в процедуру переменной

СообщениеДобавлено: 19.02.2017 22:12:59
zub
>>причем не используя сырцы оригинальной мегакривой кривой реализации Val....
Чем она мегакривая? Проблема "порчи" данных взята из пальца

Re: Определить тип переданной в процедуру переменной

СообщениеДобавлено: 19.02.2017 23:20:53
bormant
В худшем случае, что перевелось, то и записалось. Тем не менее, никто не мешает:
Код: Выделить всё
  Val(s,t,code);
  if code=0 then n:=t;

Re: Определить тип переданной в процедуру переменной

СообщениеДобавлено: 20.02.2017 01:48:45
beria
zub писал(а):Чем она мегакривая?

Посмотрите сами исходный код процедур. Безумные преобразования и приведения строк, передача оных строк целиком по значению вместо ровно одной ссылки на начало конвертации ( а ежели исходная строка в несколько мегабайт длинной, тоже через copy выкусывать нужный кусок?) в и использование зачем-то динамической памяти. Я как-то делал для себя аналог, так, так вроде в 15 раз быстрей работало даже без ассемблерных вставок и оптимизаций.

Re: Определить тип переданной в процедуру переменной

СообщениеДобавлено: 20.02.2017 17:40:18
bormant
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, что б уж без преобразований и копирований?