Zend Framework Library Linux file-managers
Oct 23

Начнем издалека… Есть в C++ встроенный тип size_t, который является “целым типом без знака, используемым реализацией для индексирования массивов” © Страуструп. То есть, если вы работаете с индексами в массивах и их длинами, то в общем-то “правильнее” использовать не int, что в большинстве случаев и делается, а именно size_t (для длин можно еще использовать ptrdiff_t - тип, который возвращает операция вычитания двух указателей). Вчера эта “правильность” для меня вышла боком…

size_t length;
...
for(size_t i = 0; i < length; ++i) {
    double x = 2 * (i - length / 2) / length;
    ...
}

Вот такой был изначальный код. Через несколько минут после написания я вспомнил, что неплохо бы сделать так:

size_t length;
...
for(size_t i = 0; i < length; ++i) {
    double x = 2 * static_cast<double>(i - length / 2) / length;
    ...
}

потому что при делении двух целых чисел у нас тоже целое будет, а мне нужно было как раз вещественное.

Но это еще ладно. После этого я отдал свой кусок лабораторной (мы ее пишем парами) своей девушке (а я как раз с ней пишу). Когда она добралась до этого кода и стала тестить его - у нее стали получаться какие-то странные, неправильные числа. Долгое время я копался в коде и не мог понять, в чем проблема, а потом до меня наконец-то дошло - разность двух беззнаковых чисел также будет беззнаковая (т.е. число -1 будет на самом деле 0xFFFFFFFF), после чего код превратился в такой:

size_t length;
...
for(size_t i = 0; i < length; ++i) {
    double x = 2 * static_cast<double>(static_cast<int>(i) - static_cast<int>(length) / 2) / length;
    ...
}

После чего я на всякий случай еще полчаса проверял небольшую программу на вот такие ошибки - на всякий случай. К счастью, таких больше не нашлось, но неприятный осадок остался.

Выводы: или пишите не особо заморачиваясь на правильности употребления типов (везде используйте int и double, например), или пишите семантически правильно, но не делайте таких ошибок, как я… Может, конечно, это только я такой, но мне лично сложно было именно по коду определить, что результат будет получаться не такой как я хочу.

PS. Я теперь немного понимаю, почему в Java нет unsigned типов. :) 

written by FX Poster \\ tags:


Leave a Reply