Craig writes: > Most of our (old) Pascal code represents the CALENDAR format (in Pascal) as: > > CALRECORD = PACKED RECORD > CASE BOOLEAN OF > TRUE : (CALINT : SHORTINT); > FALSE : ( > CALYEAR: 0..99; > CALDAY : 0..366; > ) > END; I'd suggest changing it to: calrecord = crunched record {or: calendar_type = ... } calyear : bit7; {or: 0..127} calday : bit9; {or: 0..511} end; Someone screwed you up by going out of their way to incorrectly define the calyear field, limiting the values to a max of 99 (which you know, of course). (more on the dropping of the "case" further below) > Please note the CALYEAR range of 0..99. The Pascal compiler reserves > 7 bits for that info in the shortint; however, should an Intrinsic > return a CALENDAR-type date with 100<= CALYEAR <= 127, then the run-time > execution of the program should fail with an out of bounds range-check > violation. But not always is this the case - read on. It depends upon how the data is transferred from the intrinsic result and into a variable of type calrecord. Here are two examples where the compiler has no way of knowing that you'd ever want the upper 7 bits of of such a variable checked: (using the original "case" version of caltype) var c : calrecord; c.int := calendar; and ffileinfo (fid, 36, c); {36 is allocation date (calendar)} In the first, you're going out of your way to tell the compiler: hey, this isn't really a record composed of two limited-range fields, instead please treat it as a single glob of 16 bits. In the second, you're telling the compiler: pass the address of a variable to this intrinsic ... I hope the intrinsic won't store more data into it than will fit ... Pascal has no clue that you'll be putting stuff into the variable. If you have: var c : caltype; d : caltype; and do: c := d; I'd expect no range checking ... Pascal should assume that "d" is legitimate, and therefore doesn't need to check the range (because c and d are the same type). > 2000 and beyond. In particular, the FFILEINFO Intrinsic item 28 returns > the expiration of an ANSI-labeled tape date in CALENDAR format. Interesting...my intrinsics manual documents 28 and 32 as type "julian", and item 36 as "CALENDAR". So, (after reading your note), I thought I should test it. On disk files, both 28 and 32 seem to return 0, and no error/warning (ugh!), and 36 returns the CALENDAR date. On unlabelled tapes, 28 and 32 return -1, and 36 returns 0. On labelled tapes, 28 and 32 indeed return CALENDAR format dates (I'm updating my manual, and the CSEQ database). > In tests I found the above code *worked* after retrieving the expiration > date from an ANSI-labeled tape with an expiration date of 2001; that is, > CALYEAR contained 101. This should have generated a run-time range- > check violation, but didn't. Hmmm... Even with range checking on, I'd expect the following to work when c.calyear = 101: var c : caltype; i : integer; i := c.calyear; > My point is this: It is a Good Idea (tm) to hand-check any code that > deals with dates in CALENDAR format and expects the CALYEAR (of my > example) to be less than 100. Yep! BTW, my example avoids the "tagless variant", Pascal's most evil aspect. Instead, when I absolutely positively need to get at the value of a variable of type caltype as 16 bits, I'd do: $standard_level 'os_features'$ $type_coercion 'representation'$ var c : caltype; i16 : shortint; ... i16 := shortint (c); Many PC implementations of Pascal have a similar "cast" ability. The nice thing about Pascal/iX's type coercion is that is is possible to constrain it (as above) to working only when the type-name and the value are exactly the same size. Although Pascal/iX does allow you to say "$type_coercion 'noncompatible'$, every use of it I've seen has been a mistake. -- Stan Sieler [log in to unmask] http://www.allegro.com/sieler.html