mirror of
https://github.com/Nekrolm/ubbook.git
synced 2025-12-18 05:14:34 +03:00
overflow in hash
This commit is contained in:
@@ -31,7 +31,21 @@ if (x > 0 && a > 0 && x + a <= 0) {
|
||||
|
||||
Но, увы, это неопреденной поведение. И компилятор имеет полное право [выкинуть](https://godbolt.org/z/dhs83T) такую проверку.
|
||||
|
||||
Корректные проверки куда сложнее и тяжелее.
|
||||
Искусственный пример может быть недостаточно убедительным, так что обратим внимание на следущую, вполне серьезную, функцию вычисления полиномиального хэша строки:
|
||||
```C++
|
||||
int hash_code(std::string s) {
|
||||
int h = 13;
|
||||
for (char c : s) {
|
||||
h += h * 27752 + c;
|
||||
}
|
||||
if (h < 0) h += std::numeric_limits<int>::max();
|
||||
return h;
|
||||
}
|
||||
```
|
||||
Функция, которая никогда не должна, по задумке, возвращать отрицательные числа, таки [выдает](https://godbolt.org/z/4v139E) отрицательное число! Из-за неопределенного поведения и бессмысленной с точки зрения компилятора проверки.
|
||||
|
||||
|
||||
Корректные проверки переполнения куда сложнее и тяжелее.
|
||||
|
||||
Так, для C++20, безопасный обобщенный код арифметических операций над целыми знаковыми числами мог бы выглядеть так
|
||||
|
||||
@@ -199,3 +213,4 @@ x *= x; // переписывается как x = x * x;
|
||||
### Полезные ссылки
|
||||
1. https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
|
||||
2. https://stackoverflow.com/a/46073296
|
||||
3. https://habr.com/ru/post/307702/
|
||||
|
||||
Reference in New Issue
Block a user