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 -- To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org