HP3000-L Archives

September 1996, Week 3

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Stan Sieler <[log in to unmask]>
Reply To:
Stan Sieler <[log in to unmask]>
Date:
Mon, 16 Sep 1996 14:31:29 -0700
Content-Type:
text/plain
Parts/Attachments:
text/plain (127 lines)
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

ATOM RSS1 RSS2