Re: struct stat

Richard B. Johnson (root@chaos.analogic.com)
Fri, 12 Mar 1999 14:11:21 -0500 (EST)


On Fri, 12 Mar 1999, David A. Greene wrote:

[SNIPPED]

>
> Your point is very valid, though. I just don't know of any compilers
> that have a replacement for /usr/include/statebuf.h.

They come with the 'C' runtime library. If it's GNU, you get GNU
stuff. If I needed to make a 'portable stat thingy', I would do
something like this:

#define CAST(w) *(((size_t *) &(w)))

i |= (int) (CAST(a.st_dev) != CAST(b.st_dev));
i |= (int) (CAST(a.st_ino) != CAST(b.st_ino));

I would do this because 'size_t' is the largest unsigned int that
will fit into a register on the target platform. This will work, up to
that size, with any object including structs and arrays. However, it will
break if the native structure member really uses all of long-long which
is kind of unlikely.

You could even have the compiler figure this one out for you, i.e.,

#if defined(long long)
#define max_cast unsigned long long
#else
#define max_cast unsigned long /* All machines have at least this */
#endif

#define CAST(w) *(((max_cast *) &(w)))

if (CAST(a.st_dev) != CAST(b.st_dev))
do_something();
else

You need to cast stuff, which forces the compiler to use the correct
rules for casting in the target. You can't do a memcmp() (even though
the compiler might), because you don't know what's between the structure
members. It is legal for 'C' to even store something there that you
don't know about like:

struct foo {
char a;
short b;
long c;
};

... may really be
char a;
char __pad[3]; /* 'C' could put its expiration date here!!! */
short b;
short ___pad;
long c;
}

Cheers,
Dick Johnson
***** FILE SYSTEM WAS MODIFIED *****
Penguin : Linux version 2.2.3 on an i686 machine (400.59 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/