Расшифровка предупреждения странного компилятора о десятичной константе без знака - PullRequest
5 голосов
/ 24 мая 2010

Это большое приложение имеет библиотеку пула памяти, которая использует внутреннюю память для хранения узлов памяти.Треап реализован с использованием макросов cpp, а полный файл trp.h можно найти здесь .При попытке скомпилировать приложение я получаю следующее предупреждение компилятора:

warning: this decimal constant is unsigned only in ISO C90

Удалив части кода макроса и используя метод проб и ошибок, я наконец нашел виновника:

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

Я не уверен, что этот странный номер делает там, но я полагаю, что он там есть по уважительной причине, поэтому я просто хочу оставить его в покое.Я действительно хочу исправить предупреждение - есть ли идея, почему компилятор говорит, что он не подписан только в ISO C90?

EDIT: Я использую gcc-4.1

Ответы [ 4 ]

6 голосов
/ 24 мая 2010

Попробуйте заменить это число на

2654435761u

, чтобы заставить его без знака.

6 голосов
/ 24 мая 2010

2654435761 - это число золотого сечения, соответствующее 2 ^ 32.

В разделе 6.4 «Искусство компьютерного программирования» Кнута мультипликативная схема хеширования представлена ​​как способ записи хеш-функции.,Ключ умножается на золотое отношение 2 ^ 32 (2654435761) для получения результата хеширования.

Так как 2654435761 и 2 ^ 32 не имеют общих общих факторов, умножение производит полное отображение ключа нарезультат хеширования без наложения.Этот метод работает очень хорошо, если ключи имеют небольшие значения.Плохие результаты хеширования получаются, если ключи меняются в старших битах.Как и во всех умножениях, вариации старших цифр не влияют на младшие цифры результата умножения.

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

2 голосов
/ 24 мая 2010

Проблема в том, что эта константа 2654435761 больше 2 ^ 31.Это означает, что с более старыми компиляторами это фактически превратится в отрицательное значение как константа со знаком.

Теперь, в этом случае это не имеет значения, поскольку из-за умножения на значение без знака, это будетпреобразован обратно в неподписанное, и правильная вещь случится.

2 голосов
/ 24 мая 2010

Я думаю, что он без знака, потому что он больше чем 2 147 483 647, что является максимальным размером для длинного целого числа со знаком, поэтому во избежание переноса он обрабатывается как неподписанный и выдает предупреждение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...