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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,f6204cee2f9f77e2 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-01-12 15:38:06 PST Newsgroups: comp.lang.ada Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!newsmi-us.news.garr.it!NewsITBone-GARR!news.mailgate.org!news2.euro.net!uunet!ash.uu.net!world!news From: Robert A Duff Subject: Re: Constraint_Error in arithmetic expressions User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 Sender: news@world.std.com (Mr Usenet Himself) Message-ID: Date: Sun, 12 Jan 2003 23:37:26 GMT Content-Type: text/plain; charset=us-ascii References: NNTP-Posting-Host: shell01.theworld.com Mime-Version: 1.0 Organization: The World Public Access UNIX, Brookline, MA Xref: archiver1.google.com comp.lang.ada:32949 Date: 2003-01-12T23:37:26+00:00 List-Id: Michal Nowak writes: > Hello, > > I've been reading chapter about exceptions in Cohen's > "Ada as a Second Language". In section 14.3.1 Constraint_Error > there are points concerning raising exception in arithmetic > expressions: > > "In the evaluation of an arithmetic expression, an intermediate > result that overflows may raise Constraint_Error, but it is not > guaranteed to do so. There are several reasons for this: > ... > > o As explained in Section 4.6, a type declared as > type T is range A .. B; > really declares T to be a subtype of some anonymous type whose > range includes the range A .. B. For Constraint_Error to be raised, > it is not enough for the subtype range A .. B to be exceeded; the > wider base-subtype range T'Base'First .. T'Base'Last must be > exceeded. Whether this happens depends on the anonymous type that > the compiler selects for T." > > Suppose that if I declare: > type T is range 1 .. 200; > A : T := 150; > B : T := 150; > the compiler may choose 1 byte (0 .. 255) or 2 bytes (0 .. 65535) for > example, for the base subtype. No. "is range" declares a signed integer type, and for signed integers, the base range is always symmetric about zero (or has an extra negative value). So the minimal base range the compiler can choose in this case is -200..200. It can choose a wider range. Compilers usually choose a range that is supported by the hardware. However, there is another rule that says that compiler is always allowed to get the right answer, instead of overflowing. The point is, (A + B)/2 might overflow. Any result in the base range is guaranteed not to overflow. Any result outside that range might overflow. A+B is outside -200..200, so it might overflow. Note that overflow is different from a constraint violation. You are guaranteed that any assignment into an object of type T (or passing to a parameter of type T) will raise C_E due to the constraint. But you are never guaranteed to get C_E due to overflow. A correct (but inefficient) implementation of Ada could always use multi-precision arithmetic to get the right answer for "if (A**B)*1_000_000 > 123 then", for example. But who cares? As a programmer, you want to *avoid* overflow. So the correct way to write the above is: type T_Base is 1..400; subtype T is T_Base range 1..200; A, B: T; Then (A + B)/2 is guaranteed *not* to overflow, because T'Base = T_Base'Base, which is at least -400..400. The problem of course is portability: a program that works just fine on one compiler might cause overflow on another. - Bob