inline фукция.

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

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

Ответить
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

inline фукция.

Сообщение Mr.Smart »

Приветствую сообщество!
Собственно вопрос по сабжу.
Есть функция следующего вида:

Код: Выделить всё

function IfThen(b: Boolean;  const aThen: Integer; const aElse: Integer = 0): Integer; inline;
begin
  if b then
   Result:=aThen
  else
   Result:=aElse;
end;

Собственно директива {$inline on} присутствует.

Существует следующий код её использующий:

Код: Выделить всё

type
  TTest = class
   ...
   function AsInt: Integer;
  end;
...
var
 P: TTest;
begin
...
  // Далее производится поиск и переменная P получает своё значение
  i:=IfThen(p<>nil,p.AsInt,-1);
...

Вопрос в том, что бывают такие ситуации когда P получает значение nil. По логике не должна вызываться функция AsInt, а она всё равно вызывается.
Как (логически) я думаю, что код после трансляции должен выглядеть так

Код: Выделить всё

...
  if p<>nil then
   Result:=p.AsInt
  else
   Result:=-1;
...

и соответственно функция AsInt не должна вызываться, но...

ps Может я что то не понимаю (накосячил), вразумите :wink:

Добавлено спустя 1 минуту 55 секунд:
Да, чуть не забыл. FPC 2.4.0
Odyssey
энтузиаст
Сообщения: 580
Зарегистрирован: 29.11.2007 16:32:24

Сообщение Odyssey »

Поскольку inline-функции это всё же в первую очередь функции, а потом уже inline, я думаю что вычисление параметров происходит перед вызовом, т.е. код разворачивается во что-то вроде этого:

Код: Выделить всё

Param1 := p <> nil;
Param2 := p.AsInt;
Param3 := -1;
if Param1 then
  Result := Param2
else
  Result := Param3;

Имхо, это логично, т.к. если бы поведение inline и обычных функций различалось, это могло бы привести к проблемам. Прямых аргументов, кроме фактического поведения, у меня нет, и ассемблерный листинг я тоже не смотрел. Косвенно эта мысль подтверждается в документации, где пишут, что inline -- это только хинт компилятору, и реально вставка кода inline не гарантируется.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Обидно :wink:
MageSlayer
постоялец
Сообщения: 216
Зарегистрирован: 07.09.2006 12:30:44

Сообщение MageSlayer »

Mr.Smart писал(а):Обидно :wink:


Да. Похоже, что надо дорабатывать компилятор для поддержки чего-то типа pure functions (без побочных эффектов).
Аватара пользователя
hinst
энтузиаст
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Сообщение hinst »

если не хотите, чтобы значение считалось, когда p = nil, то это ж просто. очевидно. :shock:
перегружаем IfThen так, чтобы вторым параметром был указатель на метод. а функция уже будет решать, вызывать метод по этому указателю или нет. и выглядеть вызов будет как-то так

Код: Выделить всё

  i:=IfThen(p<>nil, @p.AsInt, -1);
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

hinst
У меня и так данная функция перегружена с разными типами, но эта вещь универсальна и одному чёрту известно какие параметры будут у метода и метод будет это или просто функция...
Аватара пользователя
hinst
энтузиаст
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Сообщение hinst »

значит, надобно ввести четвёртый параметр

aSecondParameterPoints: TPointsKind = pkJustPointer //по умолчанию
где
TPointsKind - перечисление pkMethod, pkFunction, pkJustPointer
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

hinst Суетно это всё :wink: Я уже забил...

Конечно от inline я ожидал большего...
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

Mr.Smart писал(а):hinst Суетно это всё :wink: Я уже забил...

Конечно от inline я ожидал большего...

Страннолепно ожидать от функции поведения как у макроса. даже С на ето незамахивается - там тоже есть инлайн и там он также не есть макрос.
Аватара пользователя
hinst
энтузиаст
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Сообщение hinst »

да, а вы в курсе что в методе объекта можно делать проверку self = nil ?? намекаю, что сделав так, вы могли бы писать i:=p.AsInt без всяких
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Знаю, но проще переписать без использования IfThen и не париться.
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

ifthen вроде позиционировался как сильно оптимизированая процедура для платформ где процессор позволяет делать безветвистый выбор. в настоящее время компилятор фрюхи под х86 и ряд других целей может делать все то оптимизатором. потенциально на платформы неизвестные науке можно самому написать свой оптимизированый ifthen.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

alexrayne так функция IfThen мною написана и не завязывается на архитектуру
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

Неспорю. Спасибо оптимизатору фрюхи.
Наверное ета функция как нечто ценное устарела, но как средство улучшения читабельности я ее люблю пользовать - всетаки 1 строка вместо 4х строк полновесного if then else
Ответить