views:

158

answers:

4

This large application has a memory pool library which uses a treap internally to store nodes of memory. The treap is implemented using cpp macros, and the complete file trp.h can be found here. I get the following compiler warning when I attempt to compile the application:

warning: this decimal constant is unsigned only in ISO C90

By deleting portions of the macro code and using trial-and-error, I finally found the culprit:

#define trp_prio_get(a_type, a_field, a_node)               \
    (2654435761*(uint32_t)(uintptr_t)(a_node))

I'm not sure what that strange number is doing there, but I assume it's there for a good reason, so I just want to leave it alone. I do want to fix the warning though- any idea why the compiler's saying that it's unsigned only in ISO C90?

EDIT: I'm using gcc-4.1

+6  A: 

2654435761 is the golden ratio number corresponding with 2^32.

In Knuth's "The Art of Computer Programming", section 6.4, a multiplicative hashing scheme is introduced as a way to write hash function. The key is multiplied by the golden ratio of 2^32 (2654435761) to produce a hash result.

Since 2654435761 and 2^32 has no common factors in common, the multiplication produces a complete mapping of the key to hash result with no overlap. This method works pretty well if the keys have small values. Bad hash results are produced if the keys vary in the upper bits. As is true in all multiplications, variations of upper digits do not influence the lower digits of the multiplication result.

http://www.concentric.net/~Ttwang/tech/inthash.htm

Amber
What exactly is meant by the golden ratio of a number? (And the OP's asking about the warning, though I'm sure the background for the number is appreciated.)
Jefromi
Doesn't any odd number share the attribute "no common factors"? 2^n-1 is 3 * 5 * 17 * 157 * 65537, nary a two in sight. ;)
dash-tom-bang
@Jefromi: http://en.wikipedia.org/wiki/Golden_ratio
Amber
@dash-tom-bang: no; any number that is a multiple of any of those factors would share a common factor. (So any multiple of 3, 5, et cetera.)
Amber
So the quoted text should read something to the effect of "Since no other value in the range [0,2^32) has 2654435761 as a factor"?
dash-tom-bang
+2  A: 

I think that it's unsigned because it's bigger than 2,147,483,647, which is the maximum size for long signed integer, so in order to avoid wrap-around, it's treating it as unsigned and giving warning.

AndrejaKo
Thanks for the explanation :)
Ramkumar Ramachandra
+4  A: 

Try to replace that number with

2654435761u

to force it unsigned.

KennyTM
Works nicely, thanks :)
Ramkumar Ramachandra
+1  A: 

The problem is that this constant 2654435761 is greater than 2^31. This means that with older compilers, it will actually turn into a negative value as a signed constant.

Now, in this case it doesn't matter, as due to being multiplied by an unsigned value, it will be converted back to unsigned, and the right thing will happen.

Chris Dodd
Thanks for the explanation :)
Ramkumar Ramachandra