issue-#59 IN function with SETs
Re: IN function with SETs
Thanks Luowy,
I will add you prefered version to the next CPC edition
Helmut
I will add you prefered version to the next CPC edition
Helmut
-
- Posts: 204
- Joined: Wed Sep 18, 2013 10:06 pm
- Contact:
Re: IN function with SETs
I wonder why they made that change in the transition from Oberon to Component Pascal? The Oberon / Oberon-2 / Oberon-07 Language Reports are all less restrictive:Robert wrote:The language report saysx IN s stands for "x is an element of s". x must be an integer in the range 0..MAX(SET), and s of type SET.
When using Oberon I sometimes find it convenient to write code like this:x IN s stands for "x is an element of s". x must be of type INTEGER, and s of type SET.
Code: Select all
IF i IN {0..9} THEN ...
Code: Select all
IF (i >= 0) and (i <= 9) THEN ...
Re: IN function with SETs
There seems to be a growing consensus that the two code fragments should behave the same, and I would be quite happy with that.
- If we made this change how/where would it be documented?
I think it is compatible with the current language report, which could be interpreted as saying that out of range k is undefined, so FALSE is a permitted result.
Would we consider changing the report back to the Oberon wording to make this clearer?
- Iuowy: Does your second suggested change implement this for VARiable k? Does it implement this for CONSTant k?
Does your suggested change make the run-time code slower?
Code: Select all
IF k IN {0..9} THEN ...
IF (k >= 0) and (k <= 9) THEN ...
- If we made this change how/where would it be documented?
I think it is compatible with the current language report, which could be interpreted as saying that out of range k is undefined, so FALSE is a permitted result.
Would we consider changing the report back to the Oberon wording to make this clearer?
- Iuowy: Does your second suggested change implement this for VARiable k? Does it implement this for CONSTant k?
Does your suggested change make the run-time code slower?
-
- Posts: 204
- Joined: Wed Sep 18, 2013 10:06 pm
- Contact:
Re: IN function with SETs
None. They are not backward-compatible. The programmer no longer has the ability to skip the runtime checks if that is preferred.luowy wrote:which one is better?
Re: IN function with SETs
Hi Robert,Robert wrote:Does your second suggested change implement this for VARiable k? Does it implement this for CONSTant k?
Does your suggested change make the run-time code slower?
1, k is variable! const mode has checked at compile time already.we only need fixup variable mode.
2, only 5 bytes added,
from
Code: Select all
0F A3 45 F8 BT [EBP-8], EAX
0F 92 C0 SETB AL
Code: Select all
83 F8 20 CMP EAX, 32 ;<<<
73 04 JNB 4 ;<<<
0F A3 45 F8 BT [EBP-8], EAX
0F 92 C0 SETB AL
hi Chris,please check the "BT" code desc(in the intel manual part2) carefully:cfbsoftware wrote:None. They are not backward-compatible. The programmer no longer has the ability to skip the runtime checks if that is preferred.
when k is a variable,the emited code like this:
Code: Select all
BT [EBP-8], EAX
SETB AL
thought the BT is valid, but the result depend on the wrong memory word.
that is not we want. if you do a check:
Code: Select all
PROCEDURE Set*();
VAR k: INTEGER;
VAR s: ARRAY 2 OF SET;
VAR b: BOOLEAN;
BEGIN
k := 32;
s[0] := {0..31};
s[1] := {0..31};
Log.Bool(k IN s[0]); Log.Ln;
s[1] := {1..31};
Log.Bool(k IN s[0]); Log.Ln;
END Set;
luowy
Re: IN function with SETs
luowy wrote:If you do a check: ... you will understand why we need this fixup.luowy
Code: Select all
k := 32;
s[0] := {0..31};
s[1] := {0..31};
f.BoolLn (k IN s[0]);
s[1] := {1..31};
f.BoolLn (k IN s[0]);
new symbol file 116 4
TRUE
FALSE
One can write some code (eg , k IN s[0])) test it, find it ok but five minutes later it behaves differently. This could lead to impossible to debug problems; even a random number generator does not behave like this.
I vote for iuowy's second suggestion.
Re: IN function with SETs
I create a new version of CPC edition (RC6 - Built 45) with Louwy's 2nd solution. You can download it for testing at
http://www.zinnamturm.eu/pac/B2015.0607.zip
and its change protocol
http://www.zinnamturm.eu/pac/B2015.0607.txt
Please test it and report the result.
http://www.zinnamturm.eu/pac/B2015.0607.zip
and its change protocol
http://www.zinnamturm.eu/pac/B2015.0607.txt
Please test it and report the result.
-
- Posts: 1700
- Joined: Tue Sep 17, 2013 12:21 am
- Location: Russia
Re: IN function with SETs
For testing the Center version is preferred:
http://blackboxframework.org/unstable/i ... a1.184.zip
http://blackboxframework.org/unstable/i ... -setup.exe
Diff:
http://redmine.blackboxframework.org/pr ... 34812dffde
http://blackboxframework.org/unstable/i ... a1.184.zip
http://blackboxframework.org/unstable/i ... -setup.exe
Diff:
http://redmine.blackboxframework.org/pr ... 34812dffde
Re: IN function with SETs
I have received the following observations from Oleg N. Cher
Dear Robert,
It may be that for argument >= 32 the result of such operation will be
undefined. I'm surprised too. But if you rewrite the code at this manner:
BEGIN
RETURN 33 IN {1}
You will have error "set element greater than MAX(SET) or less than 0".
So BlackBox validates arguments at compile time, but does not at
runtilme. I think, teason of it is improvement of the performance.
Btw, Ofront gives the same error at compile time and the same result of
work in runtime:
static INTEGER Test_k;
static BOOLEAN Test_Fn (void)
{
Test_k = 33;
return __IN(Test_k, 0x02);
}
where macros __IN defined as:
#define __IN(x, s) (((s)>>(x))&1)
So result = (2>>33)&1 = NOT ZERO = TRUE ( Why? )
Tested in MINGW and TCC. As I understand, (2>>33)&1 must be = 0 in 32
bit depth range, but maybe this expression calculated also in
compile-time with bigger bit depth?
Who can say how works BlackBox's IN operation at low-level?
- Josef Templ
- Posts: 2047
- Joined: Tue Sep 17, 2013 6:50 am
Re: IN function with SETs
This is not a bug. Leave it as it is.
It is obvious that the runtime range checks are avoided by default in order to improve performance.
The behavior of using MOD 32 follows from the underlying Intel i386 architecture
and is not a surprise; it is the simplest thing a 32 bit CPU can do.
The proposed fix of returning FALSE is pure nonsense.
Please start thinking before programming.
- Josef
It is obvious that the runtime range checks are avoided by default in order to improve performance.
The behavior of using MOD 32 follows from the underlying Intel i386 architecture
and is not a surprise; it is the simplest thing a 32 bit CPU can do.
The proposed fix of returning FALSE is pure nonsense.
Please start thinking before programming.
- Josef