Recent

Author Topic: "Can't take the address of constant expressions"  (Read 4926 times)

MajinCry

  • Jr. Member
  • **
  • Posts: 51
"Can't take the address of constant expressions"
« on: December 10, 2016, 06:19:44 pm »
Yeah, it's me again.

I've made a tiny program to convert hex strings in a copy-pasted block of text, into decimal numbers. But Lazarus doesn't like me deleting characters from a TStringList, for some reason.

It's under a hundred lines, so it's not some gargantuan mess.

Problem lines:
[spoiler]
Code: [Select]
      Delete(tstrlistDest[iCounter], Pos(tstrlistDest[iCounter], strCurrentHex), iHexLength);
      Insert(strDecimal, tstrlistDest[iCounter], iPos);
[/spoiler]

Current .pas:

[spoiler]
Code: [Select]
unit hextodeclistconv;

{$mode objfpc}{$H+}

interface

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

type

  { TformWindow }

  TformWindow = class(TForm)
    buttonBegin: TButton;
    editBegin: TEdit;
    editEnd: TEdit;
    groupBegin: TGroupBox;
    groupEnd: TGroupBox;
    memoSource: TMemo;
    memoResult: TMemo;
    procedure buttonBeginClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  formWindow: TformWindow;

implementation

{$R *.lfm}

{ TformWindow }

var
  tstrlistSource, tstrlistDest: TStringList;

procedure TformWindow.FormCreate(Sender: TObject);
begin
  tstrlistSource := TStringList.Create;
  tstrlistDest := TStringList.Create;

  tstrlistSource.Sorted := false;
  tstrlistDest.Sorted := false;
end;


function GetHexString(strLine: string; iPos, iNumChars: integer): string;
var
  strHex: string;
begin
  strHex := copy(strLine, iPos, iNumChars);
  Result := strHex;
end;


procedure TformWindow.buttonBeginClick(Sender: TObject);
var
  iCounter, iDecimal, iPos, iNumchars, iHexLength: integer;
  strCurrentHex, strDecimal: string;
begin

  tstrlistSource.Assign(memoSource.Lines);
  tstrlistSource.Sorted := true;
  tstrlistDest := tstrlistSource;
  tstrlistDest.Sorted := true;

  if editBegin.Text = '0' then
     editBegin.Text := '1';
  if editEnd.Text = '0' then
     editEnd.Text := '1';

  iPos := StrToInt(editBegin.Text);
  iNumChars := StrToInt(EditEnd.Text);


  for iCounter := 0 to tstrlistSource.Count - 1 do begin

      strCurrentHex := GetHexString(tstrlistSource[iCounter], iPos, iNumChars);

      iDecimal := Hex2Dec(strCurrentHex);
      strDecimal := IntToStr(iDecimal);

      iHexLength := Length(strCurrentHex);

      Delete(tstrlistDest[iCounter], Pos(tstrlistDest[iCounter], strCurrentHex), iHexLength);
      Insert(strDecimal, tstrlistDest[iCounter], iPos);

  end;

  memoResult.Lines.AddStrings(tstrlistDest);

end;


end.
[/spoiler]

Any idea what the error means?

Blaazen

  • Hero Member
  • *****
  • Posts: 2782
  • POKE 54296,15
    • Eye-Candy Controls
Re: "Can't take the address of constant expressions"
« Reply #1 on: December 10, 2016, 06:40:04 pm »
This error message usually appears when you try to pass property as a parameter-by-reference, i.e.:
Code: Pascal  [Select]
  1.   TForm1 = class(TForm)
  2.     Button1: TButton;
  3.     procedure Button1Click(Sender: TObject);
  4.   private
  5.     FMyInt: Integer;
  6.   public
  7.     procedure MyProc(var i: Integer);
  8.     property MyInt: Integer read FMyInt;
  9.   end;
  10.  
  11. ...
  12.  
  13. procedure TForm1.MyProc(var i: Integer);
  14. begin
  15.  
  16. end;
  17.  
  18. procedure TForm1.Button1Click(Sender: TObject);
  19. begin
  20.   MyProc(MyInt);  //error message will be here
  21. end;
If it's your case (although I cannot see it in your code), copy the property to a local variable.
Lazarus 2.1.0 r59757M FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.11.2, Plasma 5.14.2
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

MajinCry

  • Jr. Member
  • **
  • Posts: 51
Re: "Can't take the address of constant expressions"
« Reply #2 on: December 10, 2016, 06:59:27 pm »
Yup, that worked. Had to chuck the current line from the TStringList into a string variable, work on the string, then replace said line with the modified string.

Odd, but it works.

lainz

  • Hero Member
  • *****
  • Posts: 3270
    • Lainz
Re: "Can't take the address of constant expressions"
« Reply #3 on: December 10, 2016, 07:22:39 pm »
Quote
This error message usually appears when you try to pass property as a parameter-by-reference, i.e.:

Sure there's a reason for that, why that can't be done? Is a question I have.

Blaazen

  • Hero Member
  • *****
  • Posts: 2782
  • POKE 54296,15
    • Eye-Candy Controls
Re: "Can't take the address of constant expressions"
« Reply #4 on: December 10, 2016, 07:35:47 pm »
When you pass parameter-by-reference you pass pointer to a memory. It would be possible, if property is defined by field:
Code: Pascal  [Select]
  1. property MyProp: Integer read FMyProp write FMyProp;
(compiler would automatically replace MyProp with FMyProp).

But property can be defined by getter and setter:
Code: Pascal  [Select]
  1. property MyProp: Integer read GetMyProp write SetMyProp;
In the second case, there's nothing to pass.
Lazarus 2.1.0 r59757M FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.11.2, Plasma 5.14.2
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

lainz

  • Hero Member
  • *****
  • Posts: 3270
    • Lainz
Re: "Can't take the address of constant expressions"
« Reply #5 on: December 10, 2016, 07:43:50 pm »
Thanks Blaazen. Now is clear.