On Thu, Jan 03, 2002 at 08:46:31AM -0600, David M. Lloyd wrote:
> On Thu, 3 Jan 2002, Bryan C. Warnock wrote:
> 
> > On Thursday 03 January 2002 12:33 am, Bryan C. Warnock wrote:
> > > Looks like the chunk_base logic doesn't work on 64-bit Solaris.  Every
> > > test failure I checked was centered around an inaccesable address coming
> > > out of STACK_CHUNK_BASE(*top) [line 85] .  I'll dig deeper tomorrow.  Er,
> > > today.
> >
> > Passes on 64-bit Solaris.  (And 32-bit Linux.)  Probably more correct
> > regardless, as longs are almost always the same size as pointers,
> > whereas ints aren't.
> 
> Maybe we should be using the Configure output to determine what postfix to
> use, based on the size of ints, longs, long longs, etc., and pointers,
> rather than "almost always" being right?

I don't think that we can even safely do this. I think we need explicit
casting. Assuming that this

    stacklow      => '(~0xfff)UL',
    intlow        => '(~0xfff)UL',
    numlow        => '(~0xfff)UL',
    strlow        => '(~0xfff)UL',
    pmclow        => '(~0xfff)UL',

is being turned into

  some_type stacklow = (~0xfff)UL.

If some_type is unsigned long long, and long isn't as large as long long, then
it will go wrong.
Say long long is 64 bit and long is 32, you get ~0xfff evaluating to
0xfffff000 on the right of an assignment, and then the value
0x00000000fffff000 assigned to the long long. (or presumably 64 bit pointer).
When what you really wanted was 0xfffffffffffff000.

You'd need to do

  some_type stacklow = ~((unsigned long long) 0xfff)

I think.

And I believe I've encountered recent versions of gcc that don't promote to
long long as one might expect. (I don't know what ANSI C99 says you should be
doing, but it's actually irrelevant when there are real gccs out there that are
doing something else)

IIRC I had

  unsigned long bar = something.;
  unsigned long long foo = bar << (unsigned long long) 53;

and I was expecting the << to be unsigned long long because one side was ULL.
And bar to be promoted to unsigned long long as an argument to <<.

And what gcc was doing was ignoring the ULLness of the right hand side,
doing an unsigned long shift (which spilled off the end completely. oops.
undefined behaviour, nevermind) and then promoting the result of that to
long long.

Nicholas Clark

  

Reply via email to