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/
|