### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Nice feature of sets  (Read 1692 times)

#### PascalDragon

• Hero Member
• Posts: 2622
• Compiler Developer
##### Re: Nice feature of sets
« Reply #15 on: May 03, 2020, 08:02:21 pm »
The compiler checks for these bounds either at compile time (if you're dealing with constants) or at runtime (if the values aren't constant and range checks are enabled).
Even when dealing with constants, it doesn't always check at compile time, e.g, it allows a constant array subscript out of the array's declared bounds, which is incorrect.  Delphi doesn't... it does it right.   You and Jonas have already declined to correct that error, therefore, I am not asking for it to be corrected, just pointing out that FPC does less than it could do (and should do) at compile time.

FPC does warn however and a user can easily elevate this to an error. This way users can at least use one element arrays for tricks with APIs (like the Windows API which has some structs with Bla[] at the end).

I'll give you another opportunity to say "no" again to a different thing here it is... in case 4, which is:
Code: Pascal  [Select][+][-]
1. { case 4 }
2.
3.   a := 200;
4.   b := 400;
5.   c := 301;
6.
7.   writeln('a = ', a, ' b = ', b, ' c = ', c);
8.   write  ('c in [a..b] ? : ');
9.   if c in [a..b] then writeln('yes - correct') else writeln('no - wrong');
10.   writeln;
11. end.
12.
The number of elements in the set bound by "a" to "b" (200..400) is less than 256, therefore, that is a case where the compiler could use its set algorithms to determine if "c" is in the set but, for that, it would need to "rebase" the set (on the fly when generating code).  That's one of the unfortunate limitations of sets in both FPC and Delphi which is, sets are not only limited to 256 elements but, the first element's ordinal _must_ be zero.

That last limitation doesn't really need to be there.  It could be removed (hint, hint)

Technically this would of course be possible, but this would simply lead to more confusion in the end. Currently a set is defined as something that can have elements with values from 0 to 255. Allowing the rebasing of sets would contradict this.

#### 440bx

• Hero Member
• Posts: 2105
##### Re: Nice feature of sets
« Reply #16 on: May 03, 2020, 09:13:04 pm »
Currently a set is defined as something that can have elements with values from 0 to 255. Allowing the rebasing of sets would contradict this.
Yes but, as Howardpc mentioned, it's quite obvious that a cardinal type has quite a few more than 256 elements and the compiler _knows_ that and it also knows that the set range being used is of that type, yet it allows it.

If you're going to apply the rule that a set can only have 256 elements then, it's obvious the variables that determine the boundaries of the set cannot be of a type that go well beyond that range.

If the compiler is going to allow variables of a greater range then it needs to rebase and simply enforce the 256 element rule. Otherwise, as you stated, the behavior is confusing.

FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

#### PascalDragon

• Hero Member
• Posts: 2622
• Compiler Developer
##### Re: Nice feature of sets
« Reply #17 on: May 04, 2020, 09:04:27 am »
Currently a set is defined as something that can have elements with values from 0 to 255. Allowing the rebasing of sets would contradict this.
Yes but, as Howardpc mentioned, it's quite obvious that a cardinal type has quite a few more than 256 elements and the compiler _knows_ that and it also knows that the set range being used is of that type, yet it allows it.

If you're going to apply the rule that a set can only have 256 elements then, it's obvious the variables that determine the boundaries of the set cannot be of a type that go well beyond that range.

If the compiler is going to allow variables of a greater range then it needs to rebase and simply enforce the 256 element rule. Otherwise, as you stated, the behavior is confusing.

The compiler also allows you to assign a LongWord to a Byte without any typecast and will only complain at runtime if you have range checks enabled and the value does not fit the range of Byte. Thus the current behaviour with sets is in line with that behaviour.