Поправил ошибку в bc
Вчера часа проснулся около часа ночи, сна ни в одном глазу. Ворочался-ворочался, думаю надо бы заняться чем-нибудь, мозг утомить. Решил почитать исходный код bc. Он остался у меня с того раза, когда я коммитил туда своё предложение по ускорению функции band().
Бродил по коду туда-сюда, читал случайные куски, пока не дошёл до кусочка, проверяющего дублирующиеся параметры у функции. Вот это место:
for (i = 0; i < f->autos.len; ++i)
{
// Get the auto.
BcAuto* aptr = bc_vec_item(&f->autos, i);
// If they match, barf.
if (BC_ERR(idx == aptr->idx && type == aptr->type))
{
const char* array = type == BC_TYPE_ARRAY ? "[]" : "";
bc_error(BC_ERR_PARSE_DUP_LOCAL, line, name, array);
}
}
Посмотрел что тут происходит и заметил, что в перечислении, описывающем виды параметров, вообще-то три значения — скаляр, массив и массив, передающийся по ссылке. При этом код выше написан так, как будто их только два. Небольшой тест показал, что так и есть. Следующий код должен порождать ошибку, между тем, он выполняется как ни в чём не бывало:
define a(*t[], t[]) {}
Подумал, что уже достаточно утомился, чтобы лечь спать, но не тут-то было! Стоило закрыть глаза, как мозг начал продумывать как поизящнее исправить этот баг. Пришлось снова открыть ноутбук и править.
Уже утром я прочитал сообщение по моему коммиту — автор bc попросил отформатировать код и написать небольшой тест. Я всё исправил и теперь ещё немного моего кода есть в этой прекрасной утилите!
Эх, как часто бывает, смотришь на исходники, кажется, что ошибка, но про себя думаешь: «Не может быть тут ошибки, столько людей ведь проверяли, знающих программистов». А потом оказывается, что так оно и есть (иногда).
Я нашёл две странности, но сложно сказать — баги это или уже особенности.
Хорошо же!
v code ne suschestvuet oshibok.- prosto nedokumentirovanaya ficha