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

Форум для изучающих FPC и их учителей.

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

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

Сообщение Stargazer44 » 19.02.2017 12:55:45

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

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

Сообщение zub » 19.02.2017 13:11:41

>>Но тут возник вопрос: в оригинальной процедуре тип результата явно не задаётся:
где ты это увидел?

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 - внутренние функции компилятора, с ними обычные подходы не очень прокатывают
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение beria » 19.02.2017 21:04:03

Теоретически через тип Variant можно сделать универсальное решение и даже оно будет работать, но это будет такой тормоз с кучей перегружаемого кода, не совершайте моих общибок , что лучше как, правильно выше написали сделать, причем не используя сырцы оригинальной мегакривой кривой реализации Val....
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

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

Сообщение zub » 19.02.2017 22:12:59

>>причем не используя сырцы оригинальной мегакривой кривой реализации Val....
Чем она мегакривая? Проблема "порчи" данных взята из пальца
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение bormant » 19.02.2017 23:20:53

В худшем случае, что перевелось, то и записалось. Тем не менее, никто не мешает:
Код: Выделить всё
  Val(s,t,code);
  if code=0 then n:=t;
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

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

Сообщение beria » 20.02.2017 01:48:45

zub писал(а):Чем она мегакривая?

Посмотрите сами исходный код процедур. Безумные преобразования и приведения строк, передача оных строк целиком по значению вместо ровно одной ссылки на начало конвертации ( а ежели исходная строка в несколько мегабайт длинной, тоже через copy выкусывать нужный кусок?) в и использование зачем-то динамической памяти. Я как-то делал для себя аналог, так, так вроде в 15 раз быстрей работало даже без ассемблерных вставок и оптимизаций.
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

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

Сообщение bormant » 20.02.2017 17:40:18

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, что б уж без преобразований и копирований?
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01


Вернуться в Обучение Free Pascal

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

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

Рейтинг@Mail.ru