[P&AM Lab] (без темы)

Константин Никулов nateford на inbox.ru
Пн Апр 4 22:34:49 MSK 2011


Чем спорить, проще признать, что с BLAS  я махнул, неправильно
название подобрал к тому, что пишу. Такое бывает. Тут скорее
библиотечка для удобной (надеюсь такой сделать, да) работы с матрицами.
А в целом хочу написать, наверное, еще несколько функций для решения
СЛАУ методом Гаусса, наверное, а так же функцию, которая будет по
Гауссу решать. Ну, и если найду еще какой-нибудь материал, то другим
методом каким-нибудь. Но BLAS тоже заняться надо будет. А еще можно
будет сделать либку для работы с комплексными числами, и заточить
библиотеку matrix для работы с комплексными числами :) Вообще, что-то
подозрительно много мыслей появляться стало, что бы такого написать
можно..

Не очень понятно, почему в макросах нельзя использовать return. Потому
что это может оказаться неожиданным для стороннего наблюдателя?

Не очень понятно, почему matrix_resize должна возвращать указатель на
матрицу.

Насчет названий. Я думаю поменять префикс на mx, потому что
matrix больно длинно получается, и вобще названия функций сокращенными
сделать. Но тогда, наверное, надо и название структуры менять на mx?
MATRIX_DONE мне тоже не очень нравится, но ничего лучше в голову не
пришло в тот момент.

Да, действительно, надо будет все перепроверить. Я пока что просто
записывал мысли. А рефлексия у меня все-таки не мгновенно происходит..

В Mon, 04 Apr 2011 19:05:13 +0400
"Grigoriy A. Sitkarev" <sitkarev на komitex.ru> пишет:

> Сейчас по порядку.
> 
> 04.04.2011 07:09, Константин Никулов пишет:
> > А чем плохи имена функций и макрос? Я лично вижу только то, что
> > префикс можно укоротить.
> 
> Костя, понимаешь в чём дело, если бы ты знал в чём они плохи, то
> видимо писал бы как-то иначе. Имена функций "плохи" только тем что не 
> соответствуют спецификации BLAS которой ты назвался (я об этом ниже). 
> Если вообще говорить то они выбраны хорошо.
> 
> С макросом плохо потому что ты его суёшь куда нужно и куда не нужно.
> 
> Например, вот твоя функция matrix_resize():
> 
> int
> matrix_resize(matrix *mx, unsigned short rows, unsigned short cols)
> {
> 	double *res;
> 
> 	ptr_check(mx, MATRIX_UNSET)
> 
> 	if (mx->val == NULL) {
> 		mx->val = malloc(rows * cols * sizeof(double));
> 		ptr_check(mx->val, MATRIX_NOMEM)
> 	}
> 
> 	res = realloc(mx->val, rows * cols * sizeof(double));
> 	ptr_check(res, MATRIX_NOMEM)
> 
> 	mx->rows = rows;
> 	mx->cols = cols;
> 
> 	return (matrix_clear(mx));
> }
> 
> Здесь минимум одна серьёзная ошибка есть. Кроме того, код в этом
> случае может быть проще (и должен):
> 
> int
> matrix_resize(matrix *mx, unsigned short rows, unsigned short cols)
> {
> 	double *tmp;
> 	size_t n;
> 
> 	ptr_check(mx, MATRIX_UNSET)
> 
> 	n = rows * cols;
> 
> 	tmp = realloc(mx->val, n*sizeof(double));
> 	
> 	if (tmp == NULL)
> 		return MATRIX_NOMEM;
> 
> 	mx->val = tmp;
> 	mx->rows = rows;
> 	mx->cols = cols;
> 
> 	matrix_clear(mx);
> 
> 	return mx;
> }
> 
> Дальше, например в matrix_mult_matrix():
> 
> 	tmp1 = matrix_new();
> 	ptr_check(tmp1, MATRIX_NOMEM)
> 
> 	tmp2 = matrix_new();
> 	ptr_check(tmp2, MATRIX_NOMEM)
> 
> Это утечка памяти и это безусловно ошибка. Потому что должно было
> быть примерно так:
> 
> 	tmp1 = matrix_new();
> 	if (tmp1 == NULL)
> 		return MATRIX_NOMEM;
> 	
> 	tmp2 = matrix_new()
> 	if (tmp2 == NULL) {
> 		matrix_free(&tmp1);
> 		return MATRIX_NOMEM;
> 	}
> 
> Внимательно все функции нужно пересмотреть потому что есть ошибки. И
> это не последние. Я просто все писать не могу. Поймите, если у вас
> код скомпилировался это ещё ничего не значит, ничего абсолютно.
> Сейчас вы просто что-то пишете и радуетесь если компилятор не
> ругался, но это только первый шаг к тому чтобы код действительно стал
> работать и кто-то мог на него положится в своих расчётах или
> программах.
> 
> Почему вы пишете сложно? Потому что вы зачастую не понимаете
> семантики библиотечных функций, как это работает в действительности,
> у вас нет полной ментальной модели. Поэтому я обхожусь вызовом одного
> realloc(3). Что нужно сделать чтобы понимать семантику? Для этого
> нужно стать Большим Читателем.
> 
> Сейчас вы многое просто копируете механически, не понимая смысла -- 
> почему сделано так а не иначе? А нужно в первую очередь эти вопросы 
> задавать, тогда вы начнёте двигаться вперёд, потому что начнёте
> понимать ЗАЧЕМ и ПОЧЕМУ, а это уже приближение к проектированию.
> 
> Макрос ptr_check() вероятно взят из macros.h который есть почти во
> всех исходниках в репозитории, но он там полный и удобный и его
> назначение -- отлавливать ошибки программиста, а не ошибки которые
> возникают при runtime. У нас они назывались return_if_fail и
> return_val_if_fail, т.к. эти макросы делают return (что в общем
> случае категорически запрещается для макросов) они могут
> использоваться только в самом начале функций и только для проверки
> аргументов которые передавал туда пользователь. Проверка аргументов
> вставляется только в public функции, т.е. те которые идут в API
> библиотеки. В некоторых проектах макросы обрамлены ещё и директивами
> препроцессора #ifndef NDEBUG которые выключают их если код собирается
> без отладочных сообщений и т.д. Но runtime ошибки могут возникать
> всегда и потому они этими макросами не обрабатываются.
> 
> Полнота этого макроса заключалась в том что он выводил место в
> котором случилось безобразие и программист мог быстро найти и
> поправить свой код.
> 
> Макросы, которые занимают больше одной строки, настоятельно 
> рекомендуется заключать в конструкцию do { } while (0). Это позволит 
> избежать возможных трудно-обнаруживаемых ошибок при программировании.
> И хотя в случае с макросом ptr_check() это может и не случится, в
> силу его предназначения, такое обрамление всё равно нужно вставить.
> 
> > Ну, не BLAS так не BLAS. Спецификацию я еще почитать не успел, а
> > мысль, что написать, имеется. Так почему бы и нет? По мере прочтения
> > спецификации можно будет и BLAS писать.
> 
> Потому что здесь как в поговорке "назвался груздем -- полезай в
> короб". Назвался BLAS-ом -- соответствуй спецификации.
> 
> Код возврата MATRIX_DONE режет глаз, почему он не назвался MATRIX_OK? 
> Если у тебя есть MATRIX_DONE, то подразумевается что матрица может
> быть в некотором состоянии MATRIX_BUSY, раз код возврата читается как 
> завершение действия.
> 
> В программировании как и в архитектуре, нет ничего "просто так". И
> оно не должно превращаться в карго-культ -- "делаем так потому что
> видели что кто-то так делал, не понимая зачем".
> 
> --
> Г.А.
> 
> _______________________________________________
> Lab mailing list
> Lab на wiki.syktsu.ru
> http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/lab





Подробная информация о списке рассылки Lab