On Thu, 3 Jan 2002, Nicholas Clark wrote: > On Thu, Jan 03, 2002 at 08:46:31AM -0600, David M. Lloyd wrote: > > > 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.
That's why we would use ULL, not UL. Also, the UL[L] should probably be on the inside of the (): stacklow => '(~0xfffULL)', Because otherwise I'd imagine that most C compilers would assume 'int' as the datatype to apply the ~ to, and then cast the resultant constant to unsigned long. In fact, I'm surprised that seperating UL[L] from the literal constant doesn't give a compiler error. > 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. You would do this: some_type stacklow = ~(0xfffull) > 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. To be perfectly safe, I would cast both operands: unsigned long long foo = (unsigned long long)bar << 53ull; - D <[EMAIL PROTECTED]>