[m-rev.] for review: library changes for `mmc --make' on Windows

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Jul 24 06:15:11 AEST 2003


On 24-Jul-2003, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> On 24-Jul-2003, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > This code assumes that a dev_t and an ino_t are integral types
> > that will fit into a Mercury int.  This assumption is false,
> > and results in a compilation error on mars with lcc, where
> > dev_t is a struct type (because it is 64 bits and lcc has no
> > 64-bit integral type).
> 
> That dev_t is a struct is a bug in glibc, because according to POSIX
> dev_t is meant to be an integral type.

According to my reading, dev_t is only required to be an arithmetic type,
not an integral type.  In other words, it could be a floating point type,
or even (in C99) a complex number type!  Converting that number to an
int is not guaranteed to preserve its value.  Even if dev_t was integral,
conversion to an int is not safe, because it might truncate a 64-bit
long long value.

Defining dev_t as a struct is not compliant with the 2003 POSIX standard.
But Mercury should work on systems which are not compliant with the
latest POSIX standard.  In fact Mercury should work even on systems
which don't claim to support POSIX at all.

> (There's no portable way to
> compare structs for equality, and equality test is the only operation
> that makes sense for dev_t). So, basically, code which uses glibc's
> dev_t can only be compiled with gcc, unless you include lots
> of system-specific hackery.
>  
> > Probably the best fix is to use a foreign_type instead.
> > The foreign type would have to be defined carefully using appropriate
> > #ifdefs, because on non-Posix systems dev_t and ino_t might not exist.
> 
> That needs to be done, but what's the best way to define the
> unification predicate, given the above?

I think that in practice, using memcmp() will be sufficiently portable.

In theory this might cause problems for implementations on which dev_t
contained padding bits, but I think that in practice implemenations will
not have any padding bits in dev_t or ino_t.

A more standard-conforming approach would be to add a configure test
to see whether dev_t supports `==', and if so, use it, and if not, use
memcmp().  That will work on all conforming POSIX 2003 implementations,
which have dev_t is an arithmetic type, even if the arithmetic type's
representation should happen to contain padding.  It will also work on
non-conforming implemenations where dev_t is a struct, provided that the
struct doesn't contain padding.  It might fail on non-POSIX-conforming
implementations where dev_t is a struct whose representation contains padding,
but I think that isn't going to occur in practice.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list