Преобразрвание Integer Pointer

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

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

sign
энтузиаст
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Преобразрвание Integer Pointer

Сообщение sign »

У меня есть такое присваивание:

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

var Val: Integer;
...
  TList(FValue.VClass).Items[i] := Pointer(Val);

и такое

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

    Val := StrToInt(S);
    TList(FValue.VClass).Add(Pointer(Val));


Компилятор выдаёт в том и том случае хинт: Hint: Conversion between ordinals and pointers is not portable
Можно, конечно, загасить этот хинт, но, хочется, чтобы преобразование было грамотным.
Как это сделать правильно?
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Сообщение Maxizar »

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

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var I,X:Integer;
    List:TList;
begin
   I:=12;
   X:=444;
   List:=TList.Create;
   List.Add(@X);     //@ - дает аддрес переменной
   List.Add(@I);
   Memo1.Lines.Add('X= '+IntToStr(Integer(List[0]^)));
   Memo1.Lines.Add('I= '+IntToStr(Integer(List[1]^)));
   Memo1.Lines.Add('Аддрес X= '+IntToStr(Integer(List[0])));
   Memo1.Lines.Add('Аддрес I= '+IntToStr(Integer(List[1])));

   List.Free;
//Integer(List[0]^)  - что это такое
// List[0] - Содержит указатель типа Pointer и List без понятия че там лежит
//А мы должны знать и говорим чтоб это указатель был разименован  List[0]^ (Галочке справа)
//И после разименовывания привести к типу  Integer
//При этом нужно помнить все это будер работать тока Локально
//те если Лист глобальный то в него нельзя добовлять указатели на локальные переменные
//Те эти переменные будут удалены при воходе из процедуры и указатели будут уже указывать на фигню
//ДЛя этого нужно использовать указатели :) см процедуру New()  etc.
end;

end.

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

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

sign

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

x:=Pointer(PtrInt(12))
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

sign писал(а):Компилятор выдаёт в том и том случае хинт: Hint: Conversion between ordinals and pointers is not portable. Как это сделать правильно?


на скриншоте!

не стоит путать Hint и Warning: Conversion between ordinals and pointers is not portable.
отключать этот Warning я настоятельно не рекомендую, под страхом вырывания рук. :) А Hint отключить - пожалуйста.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
sign
энтузиаст
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Сообщение sign »

Не, я ничего не отключаю, стараюсь, чтобы никаких предупреждений не было.
В данном случае, спасибо Mr.Smart за PtrInt.

Вопрос обошел так:

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

var P: Pointer;
    I: PtrInt absolute P;
begin
  I := Val;
  TList(FValue.VClass).Items[k] := P;
...
Аватара пользователя
Nik
энтузиаст
Сообщения: 573
Зарегистрирован: 03.02.2006 23:08:09
Откуда: Киров
Контактная информация:

Сообщение Nik »

При переносе проекта с Delphi на Lazarus столкнулся с аналогичной проблемой.

При сборке проекта компилятор выдаёт целую кучу Hint'ов и парочку Warning'ов со следующим сообщением:

main.pas(1906,15) Hint: Conversion between ordinals and pointers is not portable



Почти все они связаны с кодом, отвечающим за выдёргивание данных из узла TreeView или записью этих данных. Например, так:

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

Ind: integer;

CategorTree.Selected.Data:=Pointer(Ind);
...
Ind:=Integer(CategorTree.Selected.Data)


Проблема в том, что при запуске программы все строки, для которых компилятор показывает hint'ы, приводят к вылету с ошибкой (Access Violation). Попытка заменить Pointer() на PtrInt() никакого эффекта не дала.
Odyssey
энтузиаст
Сообщения: 580
Зарегистрирован: 29.11.2007 16:32:24

Сообщение Odyssey »

С PtrInt есть проблема, о которой написано в документации FPC. Вкратце:
PtrInt считается опасным, и почти никогда не должен использоваться в действующем коде, т.к. указатели обычно беззнаковые.
...
Введение типа PtrInt было ошибкой. Пожалуйста, используйте вместо него PtrUInt.
Аватара пользователя
Nik
энтузиаст
Сообщения: 573
Зарегистрирован: 03.02.2006 23:08:09
Откуда: Киров
Контактная информация:

Сообщение Nik »

Замена PtrInt на PtrUInt ничего не дала. Начинаю подозревать, что косяк берёт свои корни при записи CategorTree.Selected.Data:=Pointer(Ind), но пока придумать/найти ничего для замены не могу...
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Nik писал(а):Замена PtrInt на PtrUInt ничего не дала. Начинаю подозревать, что косяк берёт свои корни при записи CategorTree.Selected.Data:=Pointer(Ind), но пока придумать/найти ничего для замены не могу...


Капитан Очевидность подсказывает, скорее всего CategorTree=nil или CategorTree.Selected = nil :mrgreen:
а PtrInt тут совершенно ни при чём! как насчёт дополнительных проверок?!
Аватара пользователя
Nik
энтузиаст
Сообщения: 573
Зарегистрирован: 03.02.2006 23:08:09
Откуда: Киров
Контактная информация:

Сообщение Nik »

КО как всегда прав :) Оказалось, что в LCL объект Selected для Node создаётся как-то иначе, чем в Delphi и становится доступным только после события OnChange (в Delphi удобнее было вешать обработку на OnCahging, но в Lazarus обращение из этой функции к Node или Selected вызывает ошибку, даже если эти свойства не равны nil).
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Nik писал(а):КО как всегда прав :) Оказалось, что в LCL объект Selected для Node создаётся как-то иначе, чем в Delphi и становится доступным только после события OnChange (в Delphi удобнее было вешать обработку на OnCahging, но в Lazarus обращение из этой функции к Node или Selected вызывает ошибку, даже если эти свойства не равны nil).

в багрепорт с простеньким примером
Аватара пользователя
Nik
энтузиаст
Сообщения: 573
Зарегистрирован: 03.02.2006 23:08:09
Откуда: Киров
Контактная информация:

Сообщение Nik »

Не могу зарегиться в Mantis - письма с активацией не дошли до трёх ящиков на разных серверах (первое письмо жду уже часов 12)...
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Nik писал(а):Не могу зарегиться в Mantis - письма с активацией не дошли до трёх ящиков на разных серверах (первое письмо жду уже часов 12)...

раздел spam проверял? попробуй на ящик gmail.com зарегиться...

пожаловаться на Mantis можно сюда: http://lists.lazarus.freepascal.org/mai ... fo/lazarus, зарегистрировавшись :D
Аватара пользователя
Nik
энтузиаст
Сообщения: 573
Зарегистрирован: 03.02.2006 23:08:09
Откуда: Киров
Контактная информация:

Сообщение Nik »

Четвёртое письмо таки дошло (на Яндекс, как ни странно).

Багу запостил: http://bugs.freepascal.org/view.php?id=16632 (английский знаю ReadOnly, так что надеюсь, меня поймут правильно :) )
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

чтобы в будущем не создавать темы вроде: "Почему русские разработчики Лазаруса такие злые" (а прецедент уже есть). Очень прошу, к баг репорту 16332, приложить тестовое проект (на Лазурсе), с ехидной подписью "The same code works in Delphi". Чтобы команде было ясно, что нарушилась совместимость с Делфи!


к 16333 так же приложить тестовый проект на Delphi, который конвертируется не полностью. Например, в проекте 2 формы, одна по нажатию кнопки показывает вторую. Но прикол в том, что в .dpr внесена только одна форма, а не другой нет. Что не позволяет выполнить конвертацию Delphi -> Lazarus успешно.

Недостаток знания буржуйского (да и своего) языка, с лихвой окупается хорошими и понятными примерами!
Ответить