From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!decwrl!ucbvax!AMSTEL.llnl.gov!WILSON From: WILSON@AMSTEL.llnl.gov (One Heppy Heppy 'Ket') Newsgroups: comp.lang.ada Subject: Ada Constraints Message-ID: <4CE1FEE5846FC025DB@icdc.llnl.gov> Date: 15 Aug 90 01:45:00 GMT Sender: usenet@ucbvax.BERKELEY.EDU Organization: The Internet List-Id: Today's Ada Challenge: How can I force range checks on data presented to my Ada program from a foreign (viz., C) routine? Here's the problem. We have many Ada programs which receive many messages from many C programs. These C programs occasionally (erroneously) send messages with values not in the ranges defined by our interface, and hence not in the ranges defined by the associated Ada datatypes. By the time Ada gets involved, the data is already loaded (by the non-Ada network routines) into an Ada record-type variable. Our Ada compiler (VAX Ada V1.5) sees no reason to perform any range checks, since it didn't do the actual assignment which loaded the variable. Eventually the program performs an array index based on a component of the record variable, and gets an access violation, or worse, crashes a task, or who-knows-what. My feeling is that I would like to force a range check on all components of the record as soon as it is read in. Ideally, I would like to perform this check in the generic READ routine in my Ada interface to the network I/O system. However, even knowing the details of the record doesn't necessarily help. Here are some ideas I considered, and then discarded: 1. Assignment to another variable of the same type. Unfortunately, a smart optimizer (such as ours), will determine that no check is necessary, assuming that the source variable has already been checked. 2. Assignment to a variable of a derived type based on the record type. The same problem exists as with idea (1), except that the optimizer needs to be slightly smarter. 3. Try checking discrete fields individually, using "in". Same problem as (1). 4. Try checking discrete fields individually, using predefined operators. For example, for an integer subrange, perform the test: if MESSAGE.INT /= INT_TYPE'last then begin TEMP := INT_TYPE'succ( MESSAGE.INT ); exception when CONSTRAINT_ERROR => raise RANGE_CHECK_ERROR; end; end if; This last one (4) I think would work, but given the large number of programs, message types, and components in each message, (and the fact that it couldn't be implemented in the generic READ routine), this would be a major undertaking, and difficult to maintain and enforce over the project lifecycle. It would also add more overhead than necessary to the program, by performing the increment. It's also possible that a smart compiler might only raise CONSTRAINT_ERROR if the new value is exactly one greater than the upper limit, checking with "=" rather than ">", in which case even this test wouldn't work. So that's the story. I wish there were a pragma "CHECK" which could be placed anywhere in the proper body of a subprogram. In the absence of that, I'll welcome any suggestions from the net. Thanks in advance, --- Rick Wilson Lawrence Livermore National Laboratory (415) 423-6662 wilson@derby.llnl.gov