HP3000-L Archives

September 1999, Week 4

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:
Wed, 22 Sep 1999 12:06:51 -0700
Content-Type:
text/plain
Parts/Attachments:
text/plain (101 lines)
Keven writes:

> I was coding (NM HP C) a procedure using FLABELINFO to get dates and times.
> It seems that
> any 32 bit item like time MUST be on 32-bit aligned address.

Nope.

> My structure of
> struct {
>    short   mdate;
>    long    mtime;
>    short   rdate;
>    long    rtime;
> }
> would get funny values in mtime and forward. But if I put the 2 half-words
> together, it works.
> struct {
>    short  mdate;
>    short  rdate;
>    long   mtime;
>    long   rtime;
> }
> So it seems you need to have an even number of half-word items, grouped
> together, or place them at the
> end of the structure.

Don't be so quick to blame FLABELINFO :)

Let's examine your first struct with a quick&dirty C program:

   main ()
   {
   struct foo_struc {
      short   mdate;   /* 2 bytes */
      long    mtime;   /* 4 bytes */
      short   rdate;   /* 2 bytes */
      long    rtime;   /* 4 bytes */
   } foo;

   printf ("sizeof foo = %d\n", sizeof (foo));
   printf ("   addr foo.mdate = %x\n", (int) &foo.mdate);
   printf ("   addr foo.mtime = %x\n", (int) &foo.mtime);
   printf ("   addr foo.rdate = %x\n", (int) &foo.rdate);
   printf ("   addr foo.rtime = %x\n", (int) &foo.rtime);
   }

output:

   sizeof foo = 16
      addr foo.mdate = 418451f8
      addr foo.mtime = 418451fc
      addr foo.rdate = 41845200
      addr foo.rtime = 41845204

What did we just learn?  Note the address of foo.mtime (the second
field in the structure).  It's 4 bytes above the address of foo.mdate
(the first field).  But...foo.mdate is only 2 bytes big!  What's in the
other 2 bytes?  Waste space.

Assuming FLABELINFO called with the appropriate item numbers (to get
2 bytes, 4 bytes, 2 bytes, 4 bytes), then the intrinsic faithfully put
the first 2 bytes into your structure where mdate is, and then faithfully
put the next 4 bytes in:  2 bytes of filler, and the upper 2 bytes of
foo.mtime.  The next 2 bytes (for restore date?) were faithfully put on top
of the bottom two bytes of foo.mtime...etc.

I.e., with FLABELINFO, your structure *must* match the return data layout.
In particular, you want to avoid "filler" emitted by the compiler.
In Pascal, the same problem would have happened if you'd declared:

   type foo_struc = record
      mdate : shortint;
      mtime : integer;
      rdate : shortint;
      rtime : integer;
      end;

The problem, in Pascal, would be fixed by making that "...= crunched record...".

Thus, for ease of programming, I always group the 8-byte things first, then
the 4 bytes things, then the 2 byte things when I'm calling FLABELINFO ...
it's easier than making sure the data structure is crunched/packed/whatever.

BTW, I *STRONGLY* recommend never using "short", "long", or "int" in C.
This is *EVEN MORE IMPORTANT* when you're trying to match variables/fields
up with pre-defined data sizes.  Instead, use:  int16, int64, int32.

   struct foo_struc {
      uint16   mdate;   /* 2 bytes */
      int32    mtime;   /* 4 bytes */
      uint16   rdate;   /* 2 bytes */
      int32    rtime;   /* 4 bytes */

Also, note that dates (in CALENDAR format) are properly declared as
*UNSIGNED* 16-bit values, not signed ones!

--
Stan Sieler                                          [log in to unmask]
                                         http://www.allegro.com/sieler/

ATOM RSS1 RSS2