EDIT: Oh, and I know of another UI bug that's been in their system for about 8 years. It's a Smalltalk newbie classic -- shoving non-identity keys into an IdentityDictionary. I could describe what it is to a Smalltalker in 2 sentences, and they could then find it and fix it. This vendor seems to have the same attitude about this bug, so I've already learned my lesson. They can keep their damn bug!
It's an incredibly frustrating experience.
The most infuriating situations for me are when I submit a working patch, and it is ignored. This is, thankfully, very rare. In some cases, the patch leads to a better fix being written by the maintainer or someone else (an example of this for me was when I needed yum to support authenticated repositories; it didn't, so I patched it, posted the patch to the mailing list, and soon after one of the members of the team rewrote it to be more robust and have nicer configuration syntax within a week).
Since long is 64-bits on 64-bit architecture, and 32 on 32-bit architecture. This is the reason that 0xffffffff is showing up as a non-negative number on the 64-bit machine, but shows up as negative on the 32-bit.
Changing the type to int(which is 32 bits long on both x86 and x64), while it does break 16-bit systems(which don't exist anymore), fixes this completely by removing the x86 and x64 behavior differences with the long type.
The two style issues that he mentions are easily fixed by moving the variable declaration to the top of the function and initializing it there. However, these may be forced by the function structure due to the gotos present in the code...
http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/sys/sys...
So it's really: long = uint(long, (long)uint32) - (uint32-uint32)
Here's the problem on x64: you're converting a 64-bit long to a uint, then doing a subtraction with another uint, then placing that result into a 64-bit long. Since the compiler is just doing an assignment rather than a sign extension, which is why there is a large positive number rather than -1.
Changing it to use the lmin macro would make it: long = long(long, (long)uint32) - (uint32-uint32)
This still has the underlying issue(using 32-bit values in 64-bit buckets), which should work out fine, but may have issues down the road.
It makes more sense to change all the long types to int32/uint32 types rather than just cast longs everywhere. If recwin and adv were changed to int32, it would be: int32 = uint32(int32, uint32) - (uint32 - uint32)
While this potentially has issues if the uints are between 0x80000000 and 0xfffffff, it's a safer solution than using longs.
EDIT: added some explanation
[1]static __inline long lmin(long a, long b) { return (a < b ? a : b); }
[2]static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
Edit: 6.3.1.8 Usualarithmetic conversions in the c-99 standard.
I noticed that C programmers tend to use macros for things where (possibly non-exported) inline functions would make more sense. Why is that? Are they in the habit of building the OS with all optimizations off? Or is it that they're being used as poor man's generic function?
Macros are substituted in before the compiler, so they are always inlined.
EDIT: Hint, not suggestion.
In theory, a compiler could uninline common code blocks, including macro calls, into functions to decrease object code size and/or working set size, thus speeding up the program (example: functions f and g with inlined function h each take 2 cache lines; without inlining, each of f, g and h fit a single cache line)
In practice, using an inline function will give the compiler the opportunity to weigh different objectives (code size, execution speed, debuggability, etc) against each other, and do the better thing.