2010-05-24 10 views
5

Questa grande applicazione ha una libreria del pool di memoria che utilizza un tracing internamente per memorizzare i nodi della memoria. Il treap viene implementato utilizzando i macro cpp e il file completo trp.h può essere trovato here. Ottengo il seguente avviso del compilatore quando si tenta di compilare l'applicazione:Decifrare un avviso del compilatore queer sulla costante decimale senza segno

warning: this decimal constant is unsigned only in ISO C90 

Eliminando porzioni del codice della macro e l'utilizzo di tentativi ed errori, ho finalmente trovato il colpevole:

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

I Non sono sicuro di quello che sta facendo quel numero strano, ma presumo sia lì per una buona ragione, quindi voglio solo lasciarlo da solo. Voglio però aggiustare l'avvertimento ... un'idea del perché il compilatore dice che è senza segno solo in ISO C90?

EDIT: sto usando gcc-4,1

+0

Sarebbe utile dirci quale compilatore stai usando. – AndrejaKo

+0

L'avviso è anche lì per un motivo.Ti dice che il tipo di letterale è cambiato da una versione C all'altra, quindi qualunque buona ragione lo sviluppatore originale potrebbe ora essere sbagliato, il che potrebbe inficiare il tuo codice in modi interessanti. – gnasher729

risposta

6

provare a sostituire quel numero con

2654435761u 

per forzarlo non firmato.

+0

Funziona bene, grazie :) – artagnon

6

2654435761 è il numero corrispondente rapporto aureo con 2^32.

In Knuth di "The Art of Computer Programming ", sezione 6.4, un sistema di hashing moltiplicativo è introdotto come un modo per scrivere la funzione di hash . La chiave viene moltiplicata per il rapporto d'oro di 2^32 (2654435761) a e produce un risultato hash.

Da 2.654.435,761 mila e 2^32 non ha alcun fattori comuni in comune, la moltiplicazione produce una completa mappatura della chiave ai risultati con alcuna sovrapposizione hash. Questo metodo funziona bene con se le chiavi hanno valori piccoli. I risultati di hash errati vengono prodotti se i tasti variano nei bit superiori. Allo stesso modo di true in tutte le moltiplicazioni, le variazioni delle cifre superiori non influenzano le cifre più basse del risultato di moltiplicazione .

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

+1

Cosa si intende esattamente per il rapporto aureo di un numero? (E l'OP sta chiedendo l'avvertimento, anche se sono sicuro che lo sfondo per il numero è apprezzato.) – Cascabel

+0

Nessun numero dispari condivide l'attributo "nessun fattore comune"? 2^n-1 è 3 * 5 * 17 * 157 * 65537, nary a due in vista. ;) –

+0

@Jefromi: http://en.wikipedia.org/wiki/Golden_ratio – Amber

2

penso che è senza segno, perché è più grande di 2.147.483.647, che è la dimensione massima per intero lungo firmato, così al fine di evitare avvolgente, è trattandolo come unsigned e dare l'allarme.

+0

Grazie per la spiegazione :) – artagnon

2

Il problema è che questa costante 2654435761 è maggiore di 2^31. Ciò significa che con i compilatori precedenti, in realtà si trasformerà in un valore negativo come costante firmata.

Ora, in questo caso, non importa, poiché essendo moltiplicato per un valore senza segno, verrà convertito in non firmato e la cosa giusta accadrà.

+0

Grazie per la spiegazione :) – artagnon

Problemi correlati