Что такое {$POINTERMATH ON} ?

Вопросы программирования и использования среды Lazarus.

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

Что такое {$POINTERMATH ON} ?

Сообщение Alex2013 » 14.02.2018 08:16:20

Общем столкнулся с тем что "Си-образный" код в примере simplAR без ключа {$POINTERMATH ON} не компилируется от слова совсем ..
(и вроде как и не должен работать по правилам классического паскаля ... но кто-то ведь этот пример писал и запускал ! короче не найдя ничего странного кроме {$POINTERMATH ON} добавил его в свой модуль и "о чудо !" внезапно все заработало ! )

И так :
1 Что это за ключ ?
2 Насколько безопасно его применять ?
3 Возможно ли что без его применения нельзя надежно предавать параметры (вида : ссылка на ссылку на массив записй ) в DLL написание на Си ?
Alex2013
энтузиаст
 
Сообщения: 964
Зарегистрирован: 03.04.2013 11:59:44

Re: Что такое {$POINTERMATH ON} ?

Сообщение runewalsh » 14.02.2018 09:32:45

Документация говорит, что он включен по умолчанию, странно.
$POINTERMATH позволяет использовать арифметику указателей, т. е. сдвигать указатель ^T влево-вправо в предположении, что он указывает на ячейку array of T (собственно, по стандартам Си/C++ любая арифметика указателей, кроме указателей на ячейки одного массива — UB):
Код: Выделить всё
{$POINTERMATH ON}
var
    a: array[0 .. 9] of integer = (0, 11, 22, 33, 44, 55, 66, 77, 88, 99);
    p, p2: PInteger;
begin
    p := @a[0];
    p := p + 4;  // сдвинуть p на 4 элемента (не байта!) вправо
    writeln(p^); // 44
    p := p - 1;
    writeln(p^); // 33

    p2 := @a[6];
    writeln(p2 - p); // вычитание указателей вернёт количество ячеек базового типа между ними.
                     // p указывает на a[3], p2 указывает на a[6], поэтому разница будет 3.
    readln;
end.

С простым pointer арифметика указателей работает как с PByte, т. е. p + 5 сдвинет на 5 байт.

>Насколько безопасно его применять?
Арифметика указателей — низкоуровневый, очень опасный и потенциально мешающий оптимизации приём, никогда её не используй.

>Возможно ли что без его применения нельзя надежно предавать параметры
Нет, у тебя всегда есть оператор @ и модификатор constref.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 405
Зарегистрирован: 27.04.2010 00:15:25

Re: Что такое {$POINTERMATH ON} ?

Сообщение Alex2013 » 14.02.2018 16:42:37

Что ж спасибо за быстрый отклик ! Учту !
Я тут вычитал что этот ключ впервые появился в Дельфи 2009 (хотя я привык считать что совместимость с новинками Дльфи закончилась на уровне 7-мой версии )...
Может еще что-то из новинок "паскалеводства" в новых версиях FPC появилось ?
(Кстати модификатор constref из Дельфи 2010 - читал про него но запутался... написано что constref это const но без копирования значения ... А как же он тогда работает ? Игнорирует команды изменения переменой или запрещает их ставя "только чтение" на область памяти ? )
Alex2013
энтузиаст
 
Сообщения: 964
Зарегистрирован: 03.04.2013 11:59:44

Re: Что такое {$POINTERMATH ON} ?

Сообщение runewalsh » 14.02.2018 18:15:55

Для const-параметра компилятор волен сам выбрать способ передачи — по ссылке или по значению, на разных платформах может решить по-разному (например, передавать по ссылке, если sizeof(param) > sizeof(pointer)). Поэтому const лучше не использовать в импортируемых/экспортируемых функциях. constref всегда передаёт по ссылке, т. е. эквивалентен const type* в C. В остальном они ведут себя одинаково. Собственно, единственное, для чего нужен constref — импорт или экспорт функций.

const в FPC— обещание скорее от программиста компилятору, что переменная не изменится, и никаких проверок, кроме тривиальных во время компиляции (присваивание const-параметру), не делается. Этот код
Код: Выделить всё
var
    s: string;

procedure Foo(const a: string);
begin
    s := 'FA'; s := s + 'KE';
    writeln(a);
end;

begin
    s := 'ORIG'; s := s + 'INAL';
    Foo(s);
end.

спокойно выведет FAKE.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 405
Зарегистрирован: 27.04.2010 00:15:25

Re: Что такое {$POINTERMATH ON} ?

Сообщение Alex2013 » 14.02.2018 21:21:45

"На заборе написано а там дрова... " :D
Разумеется напишет (переменная типа Стринг всегда ссылка ) НО в отличи от Var я могу написать
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
procedure WTF(const a: string);
begin
ShowMessage(A);
end;
begin
WTF( 'WTF?' );
end;


... и это скомпилирует ..
Но если я предам УКАЗАТЕЛЬ и попытаюсь его изменить то по идее ничего не получится .
Alex2013
энтузиаст
 
Сообщения: 964
Зарегистрирован: 03.04.2013 11:59:44

Re: Что такое {$POINTERMATH ON} ?

Сообщение runewalsh » 15.02.2018 01:41:47

>Разумеется напишет (переменная типа Стринг всегда ссылка)
Не напишет, если передать без const.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 405
Зарегистрирован: 27.04.2010 00:15:25


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru