Recent

Author Topic: Array of String lookup gives wrong result  (Read 1360 times)

Wilko500

  • Full Member
  • ***
  • Posts: 118
Array of String lookup gives wrong result
« on: December 08, 2024, 04:08:15 pm »
Lazarus 3-7/FPC 3.2.3/ macOS Monterey
My question here is not how do I fix this because I've already found my coding error.  My question is why was there no complier error, no exception during execution although it seems to me there should have been.

The purpose of the procedure in question is to ask my PV Inverter for State information, to validate the 8 byte response and decode it to strings.

In the code below the problem line is highlighted.  Also included is the first part of the include file showing the definition of arrays TransOK and Trans.  I have incorrectly called gTrans:=TransOk[1]   instead of gTrans:=TransOk[0] and the value that is returned is 51-Command is not implemented which is the first element of the array Trans.  I would have expected an exception but there was none and perhaps a range error?

Any ideas to explain this or is it expected behaviour

Code: Pascal  [Select][+][-]
  1. Procedure DoCmd50(Var iErr:Int32);
  2. {$INCLUDE 'IncCmd50.pp'} //Definition of State Request Codes
  3.                          //For Transmission, Global, Inverter, DC/DC and Alarm
  4. Const
  5.   bb: Byte = $1f;    //Test '31-DC inj error
  6.  
  7. Var
  8.   ibb:    Int32;     //Work var for received byte
  9.   i:      Int32;     //Function return var
  10.   k:      Int32;     //Loop counter
  11.   RcvBuf: ar8;       //Receive buffer
  12. Begin
  13. Try
  14.   For k:= 1 to 3 Do   //Try 3 times
  15.       Begin
  16.       Form1.AdvLed1.Flash(LedFlashDur);
  17.       Form1.LazSerial1.SynSer.Purge;
  18.       i:=Form1.LazSerial1.SynSer.SendBuffer(@RdState,10);
  19.       Sleep (RcvInvWait);  //Give time for inverter to respond;
  20.       Form1.AdvLed2.Flash(LedFlashDur);
  21.       i:=Form1.LazSerial1.SynSer.RecvBufferEx(@RcvBuf,8,RcvWait);
  22.       If Form1.LazSerial1.SynSer.LastError <> 0 Then
  23.           //Timeout or other error
  24.           Begin
  25.           WriteLn('Error in Get State Request: Try ' + ' - ' + IntToStr(k) + '  Error= ' + IntToStr(Form1.LazSerial1.SynSer.LastError));
  26.           iErr:=i;
  27.           End
  28.       Else
  29.           //Ok response
  30.           Begin
  31.           //Check if response is valid
  32.           If IsResponseValid(RcvBuf, 7) = 0 Then
  33.               //Yes, response is good
  34.               Begin
  35.               //Decode state request
  36.               //Alarm State first
  37.               ibb:=Integer(RcvBuf[5]);
  38.               gAlarmState:=Alarm[ibb];
  39.  
  40.               //Then decode Transmission State
  41.               ibb:=Integer(RcvBuf[0]);
  42.               If ibb = 0 Then
  43.                   //Special case, OK
  44.                   Begin
  45.                   gTrans:=TransOk[1];      //<<=================
  46.                   End
  47.               Else
  48.                   //Do look up
  49.                   Begin
  50.                   gTrans:=Trans[ibb];
  51.               End;{If}
  52.  
  53.               //And DC/DC State Inv 1
  54.               ibb:=Integer(RcvBuf[3]);
  55.               gDcDc1:=DcDc[ibb];
  56.               //And DC/DC State Inv 2
  57.               ibb:=Integer(RcvBuf[4]);
  58.               gDcDc2:=DcDc[ibb];
  59.  
  60.               //Next Inverter State
  61.               ibb:=Integer(RcvBuf[2]);
  62.               gInverter:=Inverter[ibb];
  63.  
  64.               //And lastly Global State
  65.               ibb:=Integer(RcvBuf[1]);
  66.               If ibb >= 98 Then
  67.                   //Special case
  68.                   Begin
  69.                   gGlobal:=Global2[ibb];
  70.                   End
  71.               Else
  72.                   Begin
  73.                   //Do Look up
  74.                   gGlobal:=Global[ibb];
  75.               End;{If}
  76.               //Output to form for testing
  77.               Form1.Edit6.Text:=(gAlarmState + '|' + gTrans + '|' + gDcDc1 + '|' + gDcDc2 + '|' + gInverter + '|' + gGlobal);
  78.               Application.ProcessMessages;
  79.               iErr:=0;
  80.               Break;
  81.               End
  82.           Else
  83.               Begin
  84.               //Try again. cause is logged in IsResponseValid
  85.           End;{If}
  86.           //Try again
  87.       End;{If}
  88.    End;{For}
  89. Except
  90.     On E: Exception Do
  91.     Begin
  92.     WriteLn('Exception in DoCmd50: ' + E.ClassName + ':' + E.Message);
  93.     End;
  94. End;{Try}
  95. End;{Procedure DoCmd50}  

Code: Pascal  [Select][+][-]
  1. //Include State Request definitions for 'IncCmd50.pp'
  2. Const
  3.   TransOk:    Array[0..0] Of String = ('0-Everything is OK');
  4.                                      
  5.   Trans:      Array[51..58] Of String = ('51-Command is not implemented',
  6.                                        '52-Variable does not exist',
  7.                                        '53-Variable value is out of range',
  8.                                        '54-EEprom not accessible',
  9.                                        '55-Not Toggled Service Mode',
  10.                                        '56-Can not send the command to internal micro',
  11.                                        '57-Command not Executed',
  12.                                        '58-The variable is not available, retry');
  13.  
MacBook Pro mid 2015 with OS Monterey 12.7.6
FPC 3.2.3 Lazarus 3.7
FPC 3.2.2 Lazarus 3.4

TRon

  • Hero Member
  • *****
  • Posts: 3817
Re: Array of String lookup gives wrong result
« Reply #1 on: December 08, 2024, 04:24:43 pm »
Array [0..0] is a special case and is expected behaviour. Turn on range checking and you'll get the result you expected.
I do not have to remember anything anymore thanks to total-recall.

Wilko500

  • Full Member
  • ***
  • Posts: 118
Re: Array of String lookup gives wrong result
« Reply #2 on: December 08, 2024, 05:43:48 pm »
@TRon, thank you. Presumably array[1..1] is what I should have used. I had copied another definition that was array[0..43] and edited it without thinking, well it was 05:30 am😂.  I am interested in the special case. Might you have a link that explains this thank you.
Every day a school day. Always something new to learn.
MacBook Pro mid 2015 with OS Monterey 12.7.6
FPC 3.2.3 Lazarus 3.7
FPC 3.2.2 Lazarus 3.4

TRon

  • Hero Member
  • *****
  • Posts: 3817
Re: Array of String lookup gives wrong result
« Reply #3 on: December 08, 2024, 08:37:38 pm »
@TRon, thank you. Presumably array[1..1] is what I should have used.
It happens to the best of us  :)

fwiw: reason for me to try and stick to low(array) and high(array) in order to always provide/obtain a valid index to/from an array

Quote
Might you have a link that explains this thank you.
Sure, it is here.

Also note the compiler did try to warn you about this situation
Code: [Select]
Warning: range check error while evaluating constants (1 must be between 0 and 0)
Adding the range-checking option makes it more explicit and let the compiler trip over it.
« Last Edit: December 08, 2024, 08:40:00 pm by TRon »
I do not have to remember anything anymore thanks to total-recall.

cdbc

  • Hero Member
  • *****
  • Posts: 1786
    • http://www.cdbc.dk
Re: Array of String lookup gives wrong result
« Reply #4 on: December 08, 2024, 08:55:26 pm »
Hi
Back in the day, this:
Code: Pascal  [Select][+][-]
  1. Array[0..0] Of
was used to implement a /dynamic/ or variable array, in collaboration with a pointer to the array and getmem / freemem + rangechecks OFF...
Just thought to mention it...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

TRon

  • Hero Member
  • *****
  • Posts: 3817
Re: Array of String lookup gives wrong result
« Reply #5 on: December 08, 2024, 09:04:03 pm »
Which is exactly what I was referring to cdbc so, thank you very much for the elaboration on that part.

imho real bad coding practice but we all have our dirty little secrets I guess  :)
I do not have to remember anything anymore thanks to total-recall.

jcmontherock

  • Sr. Member
  • ****
  • Posts: 274
Re: Array of String lookup gives wrong result
« Reply #6 on: December 09, 2024, 11:50:47 am »
Maybe it would be more easy to use dynamic arrays...
Windows 11 UTF8-64 - Lazarus 4RC1-64 - FPC 3.2.2

 

TinyPortal © 2005-2018