Re: Программирование на функциональных языках - как научить?
On Fri, Aug 21, 2009 at 05:12:13PM +0400, Alexey Pechnikov wrote:
> Hello!
>
> On Friday 21 August 2009 16:11:21 Stanislav Maslovski wrote:
> > if ( sqlite3_value_type(argv[2]) == SQLITE_INTEGER &&
> > sqlite3_value_int(argv[2]) >= 0 && sqlite3_value_int(argv[2]) <= 32 )
> > ^^^^^^
> >
> > Алексей, тут нужна проверка на строго больше 0, иначе ты можешь
> > заработать undefined поведение со сдвигом в строке ниже, см. мои
> > соседние письма в этом треде. Или надо переписать вычисление битовой
> > маски, если ты хочешь-таки включить в обработку (имхо, вымороченный)
> > случай с /0.
>
> Не вижу проблемы, т.к.
> mask = ~ ( (((u_int32_t)1) << (32 - mask)) -1 );
>
> Специально условие записал так, что вычисление с /0 корректно выполнялось.
В том и дело, что результат сдвига при mask = 0 в правой части
undefined. На моей архитектуре значение всего выражения получается
0xffffffff, но на другой архитектуре это выражение может запросто дать
0x00000000. Я уже устал повторять, в чем там загвоздка. Читай мои
письма.
То, что ты это выражение подогнать под "правильный" результат на
выходе функции пытался, связано еще и косвенно с тем, что ты пару
"маска" - "адрес сети" на взаимное соответсвие не проверяешь...
> Выражение, конечно, не очень очевидное, лучше бы таких избегать.
Само по себе выражение очевидное, а вот интерпретация его в
соответствии со стандартом языка -- не всегда очевидна.
> Правда, маска 0 это наверняка ошибка вызывающего приложения, так что,
> подумав, сделал возврат NULL в этом случае.
То, что сделал, - хорошо. То, что не осознал зачем, - плохо.
> Теперь переписал вычисление маски, чтобы с /32 работало без доп.
> проверки, т.е.
> mask = (u_int32_t)-1 << ( 32 - mask );
Новое выражение при mask = 0 в правой части имеет ту же проблему с
undefined result. Но так как ты проверку на 0 уже добавил...
А при mask = 32, имхо, и старое выражение работало - давало
0xffffffff.
> > Также, я вижу, что ты оставил в других местах atoi(). Имхо, если
> > позволяет переносимость, то лучше что-нибудь вроде strtol().
> >
> > strtol() conforms to SVr4, 4.3BSD, C89, C99 and POSIX.1-2001.
> >
> Зачем? Если маску /0 не использовать, то atoi() оптимальнее.
atoi() не возвращает ошибку, strtol() -- возвращает. Ты хочешь,
чтобы работа твоего кода зависела от значения, которое возвращает
atoi() при невозможности сконвертировать строку в число? Твое дело,
код твой, тебе его поддерживать.
--
Stanislav
Reply to: