amiram@TAURUS.BITNET.UUCP (03/26/87)
A colleague of mine, Yossi Veler of AITECH has come up with the following program in Ada, which seems to create a serious problem. procedure boolsub is subtype bool is boolean range true..true; type arr is array(1..10) of bool; a : arr := (1..10 => true); -- this seems like the only legal value begin a := not a; -- Here a(1)=a(2)=...=a(10)= FALSE !!!! No exception occurs etc. a := (1..10 => false); -- This does cause an exception end boolsub; The program seems legal : we inspected the LRM and also the implementers guide, and we ran it on both the DDC and VERDIX compilers. It seems that a combination of innocent features in Ada produces a result that seems to contradict with the basic philosophy of the language, that is an object posseses a value which is not in the appropriate type. It seems that several features interact to produce this undesirable situation: 1) Boolean is an enumerated type, and one can take a subtype of it. 2) Boolean array operations, which are the only ones operating on all elements of an array. 3) At run time, array assignements are not checked element by element ( I believe in all but this case this check is indeed not required ). Has anyone noticed this before? Is there a way out of it?
joe@petsd.UUCP (04/01/87)
In article <8703261730.AA28726@taurus> amiram@TAURUS.BITNET.UUCP writes: >A colleague of mine, Yossi Veler of AITECH has come up with the following >program in Ada, which seems to create a serious problem. > >procedure boolsub is > subtype bool is boolean range true..true; > type arr is array(1..10) of bool; > a : arr := (1..10 => true); -- this seems like the only legal value >begin > a := not a; >-- Here a(1)=a(2)=...=a(10)= FALSE !!!! No exception occurs etc. > a := (1..10 => false); >-- This does cause an exception >end boolsub; > >The program seems legal : we inspected the LRM and also the implementers >guide, and we ran it on both the DDC and VERDIX compilers. It seems that >a combination of innocent features in Ada produces a result that seems to >contradict with the basic philosophy of the language, that is an object >posseses a value which is not in the appropriate type. Our compiler (C3Ada R00-01.02/Beta) correctly raises CONSTRAINT_ERROR on the statement "a := not a;". regards, joe -- Full-Name: Joseph M. Orost UUCP: ihnp4!vax135!petsd!joe ARPA: vax135!petsd!joe@BERKELEY Phone: (201) 758-7284 US Mail: MS 313; Concurrent Computer Corporation; 106 Apple St Tinton Falls, NJ 07724
cjh@petsd.UUCP (04/01/87)
[] In article <997@petsd.UUCP> joe@petsd.UUCP (Joseph M. Orost) writes: >In article <8703261730.AA28726@taurus> amiram@TAURUS.BITNET.UUCP writes: >>A colleague of mine, Yossi Veler of AITECH has come up with the following >>program in Ada, which seems to create a serious problem. >> >>procedure boolsub is >> subtype bool is boolean range true..true; >> type arr is array(1..10) of bool; >> a : arr := (1..10 => true); -- this seems like the only legal value >>begin >> a := not a; >>-- Here a(1)=a(2)=...=a(10)= FALSE !!!! No exception occurs etc. >> a := (1..10 => false); >>-- This does cause an exception >>end boolsub; >> >>The program seems legal : we inspected the LRM and also the implementers >>guide, and we ran it on both the DDC and VERDIX compilers. It seems that >>a combination of innocent features in Ada produces a result that seems to >>contradict with the basic philosophy of the language, that is an object >>posseses a value which is not in the appropriate type. > >Our compiler (C3Ada R00-01.02/Beta) correctly raises CONSTRAINT_ERROR on the >statement "a := not a;". > Why is this statement illegal? Well... what is the type of the expression "not a" ? It can't be "arr" because its components do not satisfy the subrange constraint. And there isn't any available type with boolean components. The type "arr" may look like a subtype of "ARRAY(1..10) of boolean", but it isn't. On arrays, subtype constraints affect the bounds of indexes, not the values of components. Regards, Chris -- Full-Name: Christopher J. Henrich UUCP: ...!hjuxa!petsd!cjh US Mail: MS 313; Concurrent Computer Corporation; 106 Apple St; Tinton Falls, NJ 07724 Phone: (201) 758-7288 Concurrent Computer Corporation is a Perkin-Elmer company.
ms8k#@andrew.cmu.edu.UUCP (04/02/87)
In article <8703261730.AA28726@taurus> amiram@TAURUS.BITNET.UUCP writes: >A colleague of mine, Yossi Veler of AITECH has come up with the following >program in Ada, which seems to create a serious problem. > >procedure boolsub is > subtype bool is boolean range true..true; > type arr is array(1..10) of bool; > a : arr := (1..10 => true); -- this seems like the only legal value >begin > a := not a; >-- Here a(1)=a(2)=...=a(10)= FALSE !!!! No exception occurs etc. > a := (1..10 => false); >-- This does cause an exception >end boolsub; > >The program seems legal : we inspected the LRM and also the implementers >guide, and we ran it on both the DDC and VERDIX compilers. It seems that >a combination of innocent features in Ada produces a result that seems to >contradict with the basic philosophy of the language, that is an object >posseses a value which is not in the appropriate type. Verdix Ada v1.5 is completely bogus. Don't be amazed by problems like this. Another example is type BYTE is range 0 .. 255; for BYTE'SIZE use 8; Verdix compiler says that the size is too small. type BYTE is new POSITIVE range 0 .. 255; for BYTE'SIZE use 8; same thing! 0 as a POSITIVE does not disturb it. The bit sign is still there. type BYTE is range -128 .. 127 for BYTE'SIZE use 8; is ok (at last), but is not really what was wanted. Another solution may be an enumaration of 256 items, a little painful. ____________________________________________________________ Marc A. Scheurer Arpanet, Bitnet: ms8k@andrew.cmu.edu UUCP : seismo!andrew.cmu.edu!ms8k ____________________________________________________________
ROSENBLUM@SIERRA.STANFORD.EDU.UUCP (04/02/87)
I think that the LRM is pretty clear on this point. 4.5.6 (2) says that the "not" operator takes a value of any array of boolean components, and returns a value of the same array type. The important words here are SAME TYPE. 3.6 (5) says that an array type is characterized by a set of index types and a component subtype. Thus, in the example the value of "not A" must be a value of the type of A, which is ARR. Since the resulting component values do not satisfy the component subtype constraint, the result is NOT a value of type ARR. Ergo, CONSTRAINT_ERROR must be raised by the evaluation of "not A". Note that the fact that the expression appears in an array assignment is not germane; the evaluation of such a "not A" in any context should raise CONSTRAINT_ERROR. -- David. -------
deller@vrdxhq.UUCP (04/03/87)
In article <MS.V3.18.ms8k.80021103.harrisburg.ibm032.535.0@andrew.cmu.edu>, ms8k#@andrew.cmu.edu (Marc Scheurer) writes: > > Verdix Ada v1.5 is completely bogus. Don't be amazed by problems like this. > Another example is ... (and other comments about Verdix Ada 1.5 [sic]) The full original posting follows below in case there is any doubt about the context of this reply, and is followed by code and compilation/execution outputs that illustrate correct handling of bit and size representations by VADS 5.41. I apologize for this lengthy reply; accuracy demands it. Verdix has never had a v1.5 compiler. I presume Marc is referring to VADS 5.1a, which states explicitely in its documentation that bit representations and size representations are NOT supported with that version. The fatal diagnostics that say "type is too small" occurred naturally because of that lack of support. We were adding support with the next version, so we did not feel the need to add a special diagnostic to say "not supported yet". VADS 5.41 has full support for the features Marc complains about, except on two of the machines in our product line (CCI and Sequent). The documentation clearly states whether a release supports those features or not. Sequent (and other 32032 products) will have bit rep support with the next VADS release. VADS 5.1a, used by Marc, was last shipped around April 1986. VADS 5.41 began shipping in January 1987, in stages across all products: Sun, VAX/VMS, VAX/UNIX-ULTRIX, Sequent, Apollo, Masscomp, CCI, 68K crosses, 1750a crosses, and others. 5.41 sources with bit and size representation support have been shipped to all of our source customers (well over 20 computers). As for the original problem mentioned of a constraint error being missed in an array operation, the Verdix 5.41 compiler does indeed fail to raise a constraint error as required by the RM (the code produces the correct "enumerical" :-) result, and only fails to raise the constraint error). Note that raising a constraint error is not a sufficient test of correct execution of the statements presented. Robert Dewar has given an excellent presentation at a SIGAda conference illustrating the problems with this apparently simple construct. If I remember correctly (any errors are mine, not his) the primary problem with the assignment is that it must be atomic, either performed for EVERY array element, or not performed for ANY array element. The code generated must ensure, at the point it detects any result with a constraint error, that all elements are either assigned to by the assignment, or that the elements assigned to so far are "backed out". Efficiency concerns preclude the easy out of using an intermediate temporary array and copying it to the result array if there are no constraint errors. I believe that this code generation complication is part of the reason for the VADS compiler missed the constraint error. The example is clearly a pathological test. A type derived from a boolean but constrained to a single value, yet not a constant, does not appear to be very useful. VADS is built to operate efficiently on types normally encountered in practice, and works well in those cases. Clearly, however, there is an error in VADS 5.41 for this case, which requires a "more proper" solution within the compiler to provide both the efficiency desired and the correctness required by the RM. As a test of the boundary conditions for our code generation with array operations, the original code serves very well. We would like to thank Amiram for providing this test. This error will be fixed in the next release of VADS. As for VADS being "bogus", Marc is mistaken. He is apparently operating with a very old VADS version that explicitly did not support the implementation dependent features he is interested in. That compiler was validated, with the noted limitations in implementation dependent features. VADS 5.41 is validated under the latest validation suite available at this time. Our best identification of his site is a site that chose not to pay for maintenance for the system and product he is using. Sites that have paid maintenance fees (including many sites within his apparent organization) are now receiving VADS 5.41 shipments with full support for bit and size representations specifications. Why a site might choose not to purchase maintenance is their business, but that decision should not then be a reason to spuriously castigate Verdix in such a wide forum as Usenet. The original posting and code example follow. Feel free to hit your "n" key at this point (if you made it this far) :-). Steven Deller Director, Verdix Product Support Original posting, in toto: In article <MS.V3.18.ms8k.80021103.harrisburg.ibm032.535.0@andrew.cmu.edu>, ms8k#@andrew.cmu.edu (Marc Scheurer) writes: > In article <8703261730.AA28726@taurus> amiram@TAURUS.BITNET.UUCP writes: > >A colleague of mine, Yossi Veler of AITECH has come up with the following > >program in Ada, which seems to create a serious problem. > > > >procedure boolsub is > > subtype bool is boolean range true..true; > > type arr is array(1..10) of bool; > > a : arr := (1..10 => true); -- this seems like the only legal value > >begin > > a := not a; > >-- Here a(1)=a(2)=...=a(10)= FALSE !!!! No exception occurs etc. > > a := (1..10 => false); > >-- This does cause an exception > >end boolsub; > > > >The program seems legal : we inspected the LRM and also the implementers > >guide, and we ran it on both the DDC and VERDIX compilers. It seems that > >a combination of innocent features in Ada produces a result that seems to > >contradict with the basic philosophy of the language, that is an object > >posseses a value which is not in the appropriate type. > > Verdix Ada v1.5 is completely bogus. Don't be amazed by problems like this. > Another example is > > type BYTE is range 0 .. 255; > for BYTE'SIZE use 8; > > Verdix compiler says that the size is too small. > > type BYTE is new POSITIVE range 0 .. 255; > for BYTE'SIZE use 8; > > same thing! 0 as a POSITIVE does not disturb it. The bit sign is still there. > > type BYTE is range -128 .. 127 > for BYTE'SIZE use 8; > > is ok (at last), but is not really what was wanted. Another solution may be > an enumaration of 256 items, a little painful. > > ____________________________________________________________ > Marc A. Scheurer > > Arpanet, Bitnet: ms8k@andrew.cmu.edu > UUCP : seismo!andrew.cmu.edu!ms8k > ____________________________________________________________ P.P.S. (For die hard Ada code readers :-) ). The following program and outputs (separated by lines of +++) illustrate correct handling of size representations by the Verdix VADS 5.41 compiler that is currently shipping for Sun-3 systems. Please note the VADS diagnostic for PBYTE, a type originally cited as not being handled correctly by VADS -- that type specification is erroneous Ada as the Marc noted (POSITIVE does not include zero), so I have commented out the offending lines (and left the diagnostics in). I added NBYTE, which uses NATURAL and does include zero. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ size.a with UNCHECKED_CONVERSION ; with TEXT_IO ; use TEXT_IO ; procedure size is type UBYTE is range 0 .. 255; for UBYTE'SIZE use 8; --type PBYTE is new POSITIVE range 0 .. 255; -------------------------------------^A ### --### A:warning: bounds check will raise CONSTRAINT_ERROR at runtime --for PBYTE'SIZE use 8; type NBYTE is new NATURAL range 0 .. 255; for NBYTE'SIZE use 8; type SBYTE is range -128 .. 127; for SBYTE'SIZE use 8; package UB_IO is new INTEGER_IO( UBYTE ) ; package SB_IO is new INTEGER_IO( SBYTE ) ; function TO_UNSIGNED is new UNCHECKED_CONVERSION( SBYTE, UBYTE ) ; NB : NBYTE ; SB : SBYTE ; UB : UBYTE ; begin NB := 255 ; NB := 0 ; SB := 127 ; PUT( "Unsigned conversion of 127 = " ) ; UB_IO.PUT( TO_UNSIGNED(SB) ) ; NEW_LINE ; SB := -128 ; UB := TO_UNSIGNED(SB) ; PUT( "Unsigned conversion of -128 = " ) ; UB_IO.PUT( UB ) ; NEW_LINE ; PUT( "Unsigned conversion of -1 = " ) ; UB_IO.PUT( TO_UNSIGNED(-1) ) ; NEW_LINE ; loop PUT( "Enter value -128..127: " ) ; SB_IO.GET( SB ) ; PUT( "which is a value of " ) ; UB_IO.PUT( TO_UNSIGNED(SB) ) ; PUT_LINE( " unsigned" ) ; exit when SB = 0 ; end loop ; end ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ compile results ========================================= Verdix Ada Compiler, Copyright 1984, 1985, 1986 Version 5.41 - Sun 3 Unix Fri Jan 23 15:06:21 PST 1987 (p) File: /vc/deller/x/size.a compiled Thu Apr 2 07:41:41 1987 by user deller unit: subprogram body size NO Ada ERRORS UNIT ENTERED 37 statements 51 lines TIMES for Front End wall 11.52 cpu 3.80 TIMES for Code Generator wall 2.80 cpu 1.33 TIMES for TOTAL TIME wall 15.24 cpu 5.56 ========================================= Verdix Ada Compiler, Copyright 1984, 1985, 1986 Version 5.41 - Sun 3 Unix Fri Jan 23 15:06:21 PST 1987 (p) TIMES for a.ld wall 34.42 cpu 12.30 TIMES for TOTAL TIME wall 35.14 cpu 12.58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ execution results Script started on Thu Apr 2 07:47:53 1987 ... (elided "junk") gilligan% size.out Unsigned conversion of 127 = 127 Unsigned conversion of -128 = 128 Unsigned conversion of -1 = 255 Enter value -128..127: -127 which is a value of 129 unsigned Enter value -128..127: -126 which is a value of 130 unsigned Enter value -128..127: -10 which is a value of 246 unsigned Enter value -128..127: -5 which is a value of 251 unsigned Enter value -128..127: -3 which is a value of 253 unsigned Enter value -128..127: -2 which is a value of 254 unsigned Enter value -128..127: 1 which is a value of 1 unsigned Enter value -128..127: 2 which is a value of 2 unsigned Enter value -128..127: 3 which is a value of 3 unsigned Enter value -128..127: 126 which is a value of 126 unsigned Enter value -128..127: 0 which is a value of 0 unsigned gilligan% exit ... (elided "junk") script done on Thu Apr 2 07:49:09 1987 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ done -- <end_message> ::= <disclaimer> | <joke> | <witty_saying> | <cute_graphic> {verdix,seismo,umcp-cs}!vrdxhq!deller
ms8k#@andrew.cmu.edu.UUCP (04/03/87)
vrdxhq!deller@seismo.css.gov (Steven Deller) writes: > Verdix has never had a v1.5 compiler... Right. I was thinking of Verdix Ada Compiler, Copyright 1984 Version 4.06 - ACVC 1.5 on VAX/Ultrix. > ... Why a site might choose not to purchase maintenance is their business, but > that decision should not then be a reason to spuriously castigate Verdix in > such a wide forum as Usenet. Right again. I apologize for the inaccuracy. ____________________________________________________________ Marc A. Scheurer Arpanet, Bitnet: ms8k@andrew.cmu.edu UUCP : seismo!andrew.cmu.edu!ms8k ____________________________________________________________
dday@mimsy.UUCP (04/03/87)
In article <12291368304.48.ROSENBLUM@Sierra.Stanford.EDU> ROSENBLUM@SIERRA.STANFORD.EDU (David S. Rosenblum) writes: >I think that the LRM is pretty clear on this point. > You are right, but it must have been missed by almost everybody. I tried the same program out on DEC Ada V1.3; the results were the same (the operation completed successfully without raising CONSTRAINT_ERROR). But if it is impossible to efficiently handle type and constraint checking for every possible pathological boundary condition then I have to come down strongly in favor of efficient implementation of constructs that programmers are actually going to use. -- UUCP: seismo!mimsy!dday Dennis Doubleday CSNet: dday@mimsy University of Maryland ARPA: dday@brillig.umd.edu College Park, MD 20742 Fan of: Chicago Cubs, Chicago Bears, OU Sooners (301) 454-6154
eric@burdvax.UUCP (04/06/87)
in article <6109@mimsy.UUCP>, dday@mimsy.UUCP (Dennis Doubleday) says: > .... But if it is impossible to efficiently handle > type and constraint checking for every possible pathological > boundary condition ... At least in this example, the compiler can determine if the situation could occur at execution time, and take appropriate actions by emitting code for the efficient common situation, or less efficient code for the pathological case. First, the only operators which can partake in this silliness are NOT and XOR, and only if their operand(s) is a subtype of a boolean type constrained to a single value (Yuch). If such a type may exist at execution time, the compiler could emit an if statement like the following. if funny_boolean_type'first != funny_boolean_type'last then emit efficient code for AND and XOR else emit funny code for AND and XOR end if; The funny code for AND is easy, just raise CONSTRAINT_ERROR (what could be more efficient than that :-). For XOR, a component by component test needs to be performed for the detection of CONSTRAINT_ERROR. So it turns out, for efficiency at least, that the XOR operation is the worst case, AND is the best case, and for the common case (a boolean type with both values), an additional if statement is needed. Remember, all of this is only for a boolean type which could turn out to be constrained to only a single value. Eric Marshall Unisys Corporation P.O. Box 517 Paoli, PA. 19301 (215) 648-7223 USENET: sdcrdcf!burdvax!eric {sjuvax,ihnp4,akgua,cadre}psuvax1!burdvax!eric ARPANET: eric@burdvax.prc.unisys.com
drw@cullvax.UUCP (04/07/87)
Is the following program required to raise CONSTRAINT_ERROR (or whatever)? procedure y is subtype x is range 0..100; a : x := 100; begin a := a + 1; end y; This has a major bearing on the "boolean range true..true" program. Dale -- Dale Worley Cullinet Software UUCP: ...!seismo!harvard!mit-eddie!cullvax!drw ARPA: cullvax!drw@eddie.mit.edu Un*x (a generic name for a class of OS's) != Unix (AT&T's brand of such)
keith@telesoft.UUCP (04/08/87)
Dale Worley at Cullinet Software writes: > Is the following program required to raise CONSTRAINT_ERROR (or whatever)? > > procedure y is > subtype x is range 0..100; > a : x := 100; > begin > a := a + 1; > end y; > First, our compiler points out the error: 2: subtype x is range 0..100; ------- >>> Replaced underlined text by " type " So, making that suggested modification results in correct compilation with the runtime result: >>> Unhandled exception: CONSTRAINT_ERROR (Range Check) Raised in Y.Y at line 5 So, yes, absolutely, constraint_error should be raised. I assert that you meant either type x is range 0..100; or subtype x is integer range 0..100; for the purposes of the question, the differences are immaterial. Keith -- Keith Allan Shillington telesoft!keith@UCSD.ARPA 619/457-2700x388.ATT My opinions are mine. {ucbvax!sdcsvax,hp-sdd,bigbang}!telesoft!keith.UUCP
drw@cullvax.UUCP (04/08/87)
keith@telesoft.UUCP (Keith Shillington @prodigal) writes: > Dale Worley at Cullinet Software writes: > > Is the following program required to raise CONSTRAINT_ERROR (or whatever)? > > > > procedure y is > > subtype x is range 0..100; > > a : x := 100; > > begin > > a := a + 1; > > end y; > > > [keith replaces "subtype" with "type" so the code will compile.] > > So, making that suggested modification results in correct compilation > with the runtime result: > > >>> Unhandled exception: CONSTRAINT_ERROR (Range Check) > Raised in Y.Y at line 5 > > So, yes, absolutely, constraint_error should be raised. [...] But I am neither asking whether you thing that it should be raised, nor whether your favorite implementation raises it, I am asking whether the LRM *requires* that it be raised, or is an implementation allowed to not raise it? Sheesh! Don't people understand what *standards* are? Dale -- Dale Worley Cullinet Software UUCP: ...!seismo!harvard!mit-eddie!cullvax!drw ARPA: cullvax!drw@eddie.mit.edu Un*x (a generic name for a class of OS's) != Unix (AT&T's brand of such)