Recent

Author Topic: [ resolved] Allow case to use const array elements and function results  (Read 2264 times)

Joanna

  • Hero Member
  • *****
  • Posts: 976
Hello , I recently discovered that I’m not allowed to use values from a constant array in a case statement. Like this
Code: Pascal  [Select][+][-]
  1.  
  2. procedure correct (sender:tobject);
  3.                const
  4.                AR_CTRL_NAMES:ARRAY[0..1] OF String = ('MIN_CTRL','MAX_CTRL');
  5. begin
  6. CASE TControl(SENDER).Name OF // doesnt matter what type the control is
  7.      AR_CTRL_NAMES[0]:MAXIMUM := MINIMUM;
  8.      AR_CTRL_NAMES[1]:MINIMUM := MAXIMUM;
  9.      OTHERWISE  ShowMessage(name+'  ERROR ');
  10.      END;  
  11. end;
  12.  
  13.  
The error is constant and case types don’t match.
It will work for lone const strings by themselves of course but I need to keep things organized. The same restrictions seem to apply regardless of type in the array. Is there a reason this can’t work? Yes I know I can use if statement but that looks sloppy and will not scale well for many choices.

I also thought of using function String results in the case statement and that won’t work either.
« Last Edit: January 24, 2024, 01:21:15 am by Joanna »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

440bx

  • Hero Member
  • *****
  • Posts: 4475
Re: Allow case to use const array elements and function results
« Reply #1 on: January 23, 2024, 01:05:52 am »
Is there a reason this can’t work?
The reason is because a case statement is designed to compare against a constant and, in the code you posted, the array - being a typed constant - is actually a variable and the "name" field is also a variable, therefore a "case" statement will be "unhappy" about that situation.

you can easily emulate a variable against variable case statement by creating an inline scope.  e.g,
Code: Pascal  [Select][+][-]
  1. for i := 1 to 1 do  // the fake scope, a loop that executes only once (NOTE: can use a repeat ... until TRUE instead)
  2. begin
  3.   if <somevar> = <someothervar> then
  4.   begin
  5.     DoSomething();
  6.  
  7.     break;  // the break is important
  8.   end;
  9.  
  10.   if <somevar2> = <whoknowswhat> then
  11.   begin
  12.     DoTheOtherThing();
  13.  
  14.     break();
  15.   end;
  16.  
  17.   { more cases here }
  18.  
  19.   // the "otherwise" case
  20.  
  21.   DoTheOtherwiseCase();
  22.  
  23.   // a break is not needed for the emulated "otherwise" but, I recommend you code it just in case it becomes a case instead of the general "otherwise"
  24.  
  25.   break;
  26. end;
  27.  
  28. // code outside the "case" here, which is where the above "break"(s) land
  29.  
  30.  

The above is just like a case without any of the limitations of a case.  That said, the compiler will not optimize such  a "case" statement into a jump table but, it can't do that anyway whenever variables are involved, therefore there is no loss.

HTH.

Just for fun: Delphi 2 (and likely newer versions) optimizes one of these fake scopes by removing the loop then the compiler issues an internal error because it cannot find the target of the "break" (because it removed the loop) <chuckle>

Lastly instead of using "for i := 1 to 1 do", it is a bit clearer to write "for SCOPE := SCOPE to SCOPE do" that should really clue the reader that the "for" isn't a loop but a scope (or repeat... until SCOPE = SCOPE;)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Joanna

  • Hero Member
  • *****
  • Posts: 976
Re: Allow case to use const array elements and function results
« Reply #2 on: January 23, 2024, 01:19:01 am »
Thanks for the answer I didn’t think of as a static variable. Apparently the values in a constant array can be changed.

I wish that there could be a new reserved word for static variables besides const. It is very misleading.  :(
« Last Edit: January 23, 2024, 01:32:48 am by Joanna »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

440bx

  • Hero Member
  • *****
  • Posts: 4475
Re: Allow case to use const array elements and function results
« Reply #3 on: January 23, 2024, 01:39:32 am »
I wish that there could be a new reserved word for static variables besides const. It is very misleading.  :(
Join the club but, the developers have made it clear they will _not_ implement a new reserved word for static variables. 

Also, in addition to misleading, it's really hard to have a straight face when explaining to someone who is new to Pascal that some constants can be changed.  That's when they usually say something to the effect of not being surprised the language has lost popularity (changeable constants... hmmm... just what the industry needed.)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

RayoGlauco

  • Full Member
  • ***
  • Posts: 189
  • Beers: 1567
Re: Allow case to use const array elements and function results
« Reply #4 on: January 23, 2024, 01:46:13 am »
I think the job can get done by using 'else if' sentences:

Code: Pascal  [Select][+][-]
  1. aName:=TControl(SENDER).Name;
  2. if aName = AR_CTRL_NAMES[0] then
  3.   MAXIMUM := MINIMUM
  4. else if aName = AR_CTRL_NAMES[1] then
  5.   MINIMUM := MAXIMUM
  6. else
  7.    ShowMessage(name+'  ERROR ');
  8.  
To err is human, but to really mess things up, you need a computer.

440bx

  • Hero Member
  • *****
  • Posts: 4475
Re: Allow case to use const array elements and function results
« Reply #5 on: January 23, 2024, 01:47:51 am »
I think the job can get done by using 'else if' sentences:
It sure can but, personally, I find the other way much clearer.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

cdbc

  • Hero Member
  • *****
  • Posts: 1496
    • http://www.cdbc.dk
Re: Allow case to use const array elements and function results
« Reply #6 on: January 23, 2024, 08:28:03 am »
Hi
@Joanna: Have a look at this: https://www.freepascal.org/docs-html/rtl/strutils/indextext.html#:~:text=IndexText%20returns%20the%20index%20of,case%20sensitively%2C%20use%20IndexStr%20instead.
It has a cousin, named "IndexStr" which is case/sensitive/.
You use it like this:
Quote
...
  case IndexText(TControl(SENDER).Name,AR_CTRL_NAMES) of
    0: MAXIMUM := MINIMUM;
    1: MINIMUM := MAXIMUM;
    otherwise ShowMessage(name+'  ERROR ');
  end; // case
It works with open & dynamic arrays of string, but I dunno 'bout fixed length arrays of string?!?
Could be worth a try  ;)
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

Joanna

  • Hero Member
  • *****
  • Posts: 976
Re: Allow case to use const array elements and function results
« Reply #7 on: January 23, 2024, 11:05:28 am »
@CDBC
I tried your idea of index text but it gives me a warning
Quote
  Call to subroutine "function IndexText(const AText:AnsiString;const AValues:{Open} Array Of AnsiString):LongInt;" marked as inline is not inlined
what does that mean?
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Thaddy

  • Hero Member
  • *****
  • Posts: 15495
  • Censorship about opinions does not belong here.
Re: Allow case to use const array elements and function results
« Reply #8 on: January 23, 2024, 12:55:20 pm »
That the compiler used can not inline that code, so it hints you that it can not inline (yet).
It is harmless.
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

Joanna

  • Hero Member
  • *****
  • Posts: 976
Re: Allow case to use const array elements and function results
« Reply #9 on: January 23, 2024, 01:53:39 pm »
Oh good I’ve never used inline before.

Quote
Also, in addition to misleading, it's really hard to have a straight face when explaining to someone who is new to Pascal that some constants can be changed.  That's when they usually say something to the effect of not being surprised the language has lost popularity (changeable constants... hmmm... just what the industry needed.)
I know you don’t like oop But I once had an idea that I would put a typed constant into one of my classes because it could have default value. I soon learned that the same typed constant was shared by all class instances
 which was a disaster...  :(

« Last Edit: January 23, 2024, 02:19:13 pm by Joanna »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

PascalDragon

  • Hero Member
  • *****
  • Posts: 5644
  • Compiler Developer
Re: Allow case to use const array elements and function results
« Reply #10 on: January 23, 2024, 09:10:18 pm »
Is there a reason this can’t work?

The branches of a case-statement require true, untyped constants. FPC does not have those for arrays (or records).

ASerge

  • Hero Member
  • *****
  • Posts: 2314
Re: Allow case to use const array elements and function results
« Reply #11 on: January 23, 2024, 09:35:29 pm »
It will work for lone const strings by themselves of course but I need to keep things organized.
Code: Pascal  [Select][+][-]
  1. procedure correct(Sender: TObject);
  2. const
  3.   CMIN_CTRL = 'MIN_CTRL';
  4.   CMAX_CTRL = 'MAX_CTRL';
  5.   AR_CTRL_NAMES: array[0..1] of string = (CMIN_CTRL, CMAX_CTRL);
  6. begin
  7.   case TControl(Sender).Name of // doesnt matter what type the control is
  8.     CMIN_CTRL: MAXIMUM := MINIMUM;
  9.     CMAX_CTRL: MINIMUM := MAXIMUM;
  10.   otherwise
  11.     ShowMessage(Name + '  ERROR ');
  12.   end;
  13.   // ...Use organized AR_CTRL_NAMES
  14. end;

Joanna

  • Hero Member
  • *****
  • Posts: 976
Re: Allow case to use const array elements and function results
« Reply #12 on: January 24, 2024, 01:20:33 am »
@aserge thanks for trying to help.
Unfortunately it was not tricked by putting the const values inside an array.

It seems the solution that is closest is the one using indextext To transform it into a number. Thanks for all the info  everyone.
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

 

TinyPortal © 2005-2018