freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Devel] Integer issues with FreeType


From: David Turner
Subject: Re: [Devel] Integer issues with FreeType
Date: Mon, 23 Apr 2001 10:36:47 +0200

Hi Tom,

> > It has, among other very interesting things, a table of integer size on
> > realtively different platforms. Even though the info there seems a bit
> > dated (for example, "shorts" can be 8 bits on a 68000 or 386 !?)
> >
> 
> Wow!  I have long thought that Motorla had it going on with chip design 
> (unlike
> Intel).  I can't believe that shorts on 68K chipsets can occupy 8 or 16 bits.
> Perhaps Leonard Rosenthol can speak to this aspect...
>
I'm pretty convinced that this is a compiler feature, not a processor one.
It probably predates ANSI too (some of the machines listed in the table
are really "rusty" :-) and was probably dropped a long time ago..
 
> >
> > >
> > >   i = (j << 32) >> 32.
> > >
> >
> > This is a degenerate example, what about:
> >
> >     i = (j << 31) >> 16;
> >
> > The meaning of this expression varies with the sign of the variables and can
> > lead to potential bugs. You don't need only the exact size, but the exact 
> > sign
> > when bit-shifting..
> >
>
> I don't think you need the exact sign when bit shifting.  If the 32 bit 
> quantity
> read in is supposed to be a signed int, but is positive, (sign bit is not 
> set),
> 
>     i = (j << 32) >> 32
> 
> will still result in the correct value.  But I agree, one needs to know the
> exact integer width before one starts playing bit shifting games.

The problem is that your example can be read in two different ways if
you don't know the context:

  - if "j" is assumed to be a 32-bit int, the result of "i" will always be 0

  - if "j" is a 64-bit FT_Long (on Tru64 for example), then the value of
    "i" is the sign extension of the 32-bit quantity held in "j"

This ambiguity doesn't exist if you use explicit casts, like in:

       i = ((FT_Int64)j << 32) >> 32;

the explicit cast of "j" is free (it doesn't result in additional code),
however, it makes it very clear both to the compiler and developer what's
the statement's meaning is..

Similary, "i = (j << 31) >> 16", can be replaced by one of the following:

    i =  (FT_Int32)(j << 31)  >> 16;
    i = (FT_UInt32)(j << 31) >> 16;

these are respectively equivalent to:

    i = (j & 1) ? 0xFFFF0000  : 0;
    i = (j & 1) ? 0x00010000U : 0;

If i'm not myself completely mistaken :-)

I still think that explicit casts are a much needed _safety_ precaution
when right-shifts (>>) are used..

> There is a
> way to sign extend a 32 bit quantity and stuff it into a N ( > 32 ) bit 
> quantity
> without knowing the exact integer width (one just needs to know the width is
> greater tha 32 bits).  I have to look it up though.  It is in the t1utils code
> (now maintained by Ed Kohler at MIT).
>
That could be intersting, I'd like to see that.. :-)
 
> That example was meant to illustrate taking a signed 32 int and stuffing it 
> into
> a signed 64 bit int.  Unless I got the wrong compiler flags (to force the
> compiler in ANSI compliant mode), this is necessary to sign extend when 
> storing.
> I have to check what problems I ran into with casting from an unsigned 
> quantity
> to a signed quantity, but I believe explict casting didn't always work.
> 
> NOTE: I am not oppsoed to explicit casting when it is necessary.
>
Even when it's not necessary, it makes the code clearer and avoids strange
ambiguities. Think about the occasional hacker who doesn't even know that
the code can run on a 64-bit system, and thinks that FT_Long is 32-bit..

One more reason to get rid of FT_Long usage, and use expressive casts..
 
> >
> > I suppose that the use of FT_Long to store 32-bit quantities is historical
> > (FT_Int32 was introduced rather recently in the history of FT2) and maybe
> > discarded in favor of using the correct data types.
> >
> > However, I fear that changing the meaning of FT_Int and FT_Long is going
> > to introduce its own set of delicious bugs. I'd advocate the creation of
> > new types like FT_Fast16 and FT_Fast32 when "fast integers" are needed,
> > and "FT_Int32" and "FT_Int16" regarding storage..
> >
> 
> Fast integers as in the C99 specification?
>
Yep, definitely the same as "int_fast32_t"..
 
> OK.  But perhaps there were no problems on the boxen I have compiled FT2 code 
> on
> because the quantities being operated on occupied only 32 bits of data, even
> though they were stored in a 64 bit int.  Hence, no overflow/underflow errors
> occured.  Speaking of arithmetic errors, I have not taken a close look at what
> the FT conventions are for this.  Perhaps I should.
>
They're pretty liberal: overflows are generally not checked, because the domain
where computations happen is rather limited (scaling from font units to real
pixels :-)

Of course, there is the case of computing unit vectors and vector lengths.
the current code is ugly, but accurate. It would certainly gain to be
cleaned up to use CORDIC algorithms.. However, this would not provide any
significant improvement in code size of performance according to some
"gperf" tests I've done some time ago, so it's not a priority..

Cheers,
 
- David



reply via email to

[Prev in Thread] Current Thread [Next in Thread]