issue-#59 IN function with SETs

Re: IN function with SETs

Postby Zinn » Sat Jun 06, 2015 8:13 am

Thanks Luowy,

I will add you prefered version to the next CPC edition

Helmut
Zinn
 
Posts: 470
Joined: Tue Mar 25, 2014 5:56 pm
Location: Frankfurt am Main

Re: IN function with SETs

Postby cfbsoftware » Sat Jun 06, 2015 8:17 am

Robert wrote:The language report says
x 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.

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:
x IN s stands for "x is an element of s". x must be of type INTEGER, and s of type SET.

When using Oberon I sometimes find it convenient to write code like this:

Code: Select all
IF i IN {0..9} THEN ...

rather than

Code: Select all
IF (i >= 0) and (i <= 9) THEN ...

and would be disappointed if it didn't work or trapped on some values of i.
cfbsoftware
 
Posts: 204
Joined: Wed Sep 18, 2013 10:06 pm

Re: IN function with SETs

Postby Robert » Sat Jun 06, 2015 10:45 am

There seems to be a growing consensus that the two code fragments
Code: Select all
IF k IN {0..9} THEN ...
IF (k >= 0) and (k <= 9) THEN ...
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?
User avatar
Robert
 
Posts: 1001
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: IN function with SETs

Postby cfbsoftware » Sat Jun 06, 2015 12:16 pm

luowy wrote:which one is better?

None. They are not backward-compatible. The programmer no longer has the ability to skip the runtime checks if that is preferred.
cfbsoftware
 
Posts: 204
Joined: Wed Sep 18, 2013 10:06 pm

Re: IN function with SETs

Postby luowy » Sat Jun 06, 2015 3:25 pm

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?

Hi Robert,
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

to
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



cfbsoftware wrote:None. They are not backward-compatible. The programmer no longer has the ability to skip the runtime checks if that is preferred.

hi Chris,please check the "BT" code desc(in the intel manual part2) carefully:
when k is a variable,the emited code like this:
Code: Select all
BT  [EBP-8], EAX   
SETB   AL

if the k(EAX) is beyond 31, will check the word at memory [EBP-8+ k div 32] ;
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;

you will understand why we need this fixup;if you have any unbackward-compatible source code,please let we know.

luowy
luowy
 
Posts: 207
Joined: Mon Oct 20, 2014 12:52 pm

Re: IN function with SETs

Postby Robert » Sun Jun 07, 2015 7:55 am

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 discuss if the current behaviour complies with the Component Pascal Language Report, but I think we should treat it is a bug, and fix it.

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.
User avatar
Robert
 
Posts: 1001
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: IN function with SETs

Postby Zinn » Sun Jun 07, 2015 8:52 am

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.
Zinn
 
Posts: 470
Joined: Tue Mar 25, 2014 5:56 pm
Location: Frankfurt am Main

Re: IN function with SETs

Postby Ivan Denisov » Sun Jun 07, 2015 9:43 am

Ivan Denisov
 
Posts: 1694
Joined: Tue Sep 17, 2013 12:21 am
Location: Russia

Re: IN function with SETs

Postby Robert » Mon Jun 08, 2015 9:23 pm

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?
User avatar
Robert
 
Posts: 1001
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: IN function with SETs

Postby Josef Templ » Tue Jun 09, 2015 4:40 am

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
User avatar
Josef Templ
 
Posts: 2012
Joined: Tue Sep 17, 2013 6:50 am

PreviousNext

Return to Rejected (Bugs)

Who is online

Users browsing this forum: No registered users and 0 guests

cron