LINUX.ORG.RU
ФорумTalks

[opensource][fail] индусокод

 ,


0

2

Понадобилось мне разобраться, как внутри реализована одна из функций самого обыкновенного zip'а. Возрадовался я, значит, опенсорсности его, позволяющей мне это сделать, и скачал тарбол с исходниками. Открыл файл с бесхитростным названием zip.c и начал искать нужный кусок.

За 20 минут копания в куче фекалий я так и не смог отыскать нужный кусок или даже намек на него. Все 6 с лишним тысяч строк - сплошная индусская лапша. Код весь перекопал вдоль и поперек условными директивами, форматирование практически отсутствует (формально отступы конечно есть, но читать мало помогают). Имена переменных - тихий ужас, за который студентам-первокурсникам нужно отрывать руки. Наряду с осмысленными, но краткими 'display_volume', 'tempath', 'filelist' и прочими, везде кишат классические индусские 'd', 's', 'kk' и прочие нечленораздельные звуки.

Как это портянку можно вообще поддерживать в рабочем состоянии? Кто будет копаться в этом по доброй воле (а я бы теперь не стал и за деньги), если разработчик отойдет от дел? Я уже не говорю о простых смертных, которые захотят написать патч для этого ведра лапши.

И вообще, правомерно ли кучу индусокода гордо именовать опенсорсом?

★★★★★

Ответ на: комментарий от i-rinat

Вот не понимаю, как люди в фортрановском коде разбираются. Все заглавными буквами, отступы не пойми как - черт знает что...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

В фортрановском коде не разбираются, его просто используют. А с отступами вообще весело — в f77 было нужно, чтобы первые шесть символов были пробелы. А не-пробелы в тех полях имели особое значение. Плюс у некоторых было ограничение на размер имени переменной, что-то около 6 символов.

i-rinat ★★★★★
()
Ответ на: комментарий от nanonymous

> Последний раз пользовался, когда фиксил баг, который у меня на машине не наблюдался и был только крэш дамп.

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

i-rinat ★★★★★
()
Ответ на: комментарий от Eddy_Em

> Вот не понимаю, как люди в фортрановском коде разбираются.

Мне показали код, который, по слухам, привезли из какой-то лос-аламосской лаборатории. Не знаю, откуда код на самом деле, но в коде том магия. Как работает, никто не разобрался, но оно работает. Правда только на структурированных сетках. Зато быстро и памяти требует мало, все расчеты in-place. Код этот все тупо копировали.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

ха. я и страшнее случаи видал. софтина которую пользуют в ряде крупных американских, южнокорейских и китайских банках. ну там merill lynch, BofA как примеры. Прога генерит код на всяких языках программирования из какого-то своего внутреннего банально-ориентированного языка. язык страшный, к примеру так выглядит присваивание: set a to b;. это b=a означает у нормальных людей.

там вообще ад. программу не переписывали 20 лет, только костылями поправляли, когда добавляли новые фичи. называешь юзера SEER1 или SEER2 и где-то в недрах кода, написанного в 1996м году что-то начинает работать не так. по документации, можно вместо символа $ где-то ставится знак валюты из текущей локали. но эта фича была сломана и ею пользовались корейцы, слелав какой-то софт, где $ в строке что-то обозначал. «фиче» лет 7. её поправили месяц назад, и внезапно корейцы выскочили с багрепортов: где наши доллары?

какой то баг наблюдался только на мэйнфрейме. причем только на корейском мэйнфрейме. приехал из сша мужик(по иной причине) и сидел показывал, как на этот сраный мэйнфрейм залогиниться и что-то там с этой программой сделать потому что он один цука знал - не как работает, не, куда нажимать знал.

ckotinko ☆☆☆
()

Чисто исторически большая половина опенсорса так и написана. Увы и ах. Мне тут тоже как-то понадобилось разобраться с работой кое-чего, и я полез в код NetBSD.

Deleted
()
Ответ на: комментарий от i-rinat

>В фортрановском коде не разбираются, его просто используют. А с отступами вообще весело — в f77 было нужно, чтобы первые шесть символов были пробелы. А не-пробелы в тех полях имели особое значение. Плюс у некоторых было ограничение на размер имени переменной, что-то около 6 символов.

Да-да, 6 символов под метку, седьмой - для обозначения комментария, 80 символов в строке. Наследие перфокарт.

AptGet ★★★
()
Ответ на: комментарий от geekless

Но всякие итераторы, временные переменные и т.п. нет смысла называть длинными именами, хватит чего-нибудь вроде i,j,k; x,y,z; a,b,c;...

Eddy_Em ☆☆☆☆☆
()

Печалька. Меня тоже такие мысли посетили... когда думал как же мне посчитать количество строк в текстовом файле - и залез в исходники wc.c (из coreutils).

Там что-то страшное и мозголомное.

BattleCoder ★★★★★
()

А сейчас пытаюсь разобраться в исходниках примера из nvidia-cuda-sdk (oclReduction)

Нет, там бесспорно понятнее. Разница есть(ни в какое сравнение). И документация по этому есть. Но всё равно тяжело... наверное, я такой тупой. Или так хреново у меня с английским.

BattleCoder ★★★★★
()
Ответ на: комментарий от Eddy_Em

Главное перед этим стараться комментировать, что это за переменная и для чего ;) не все так делают...

P.S. Моё IMHO - комментариев много не бывает.

BattleCoder ★★★★★
()
void Matrix4x4_ToArrayDoubleGL (const matrix4x4_t *in, double out[16])
{
#ifdef MATRIX4x4_OPENGLORIENTATION
	out[ 0] = in->m[0][0];
	out[ 1] = in->m[0][1];
	out[ 2] = in->m[0][2];
	out[ 3] = in->m[0][3];
	out[ 4] = in->m[1][0];
	out[ 5] = in->m[1][1];
	out[ 6] = in->m[1][2];
	out[ 7] = in->m[1][3];
	out[ 8] = in->m[2][0];
	out[ 9] = in->m[2][1];
	out[10] = in->m[2][2];
	out[11] = in->m[2][3];
	out[12] = in->m[3][0];
	out[13] = in->m[3][1];
	out[14] = in->m[3][2];
	out[15] = in->m[3][3];
#else
	out[0] = in->m[0][0];
	out[1] = in->m[1][0];
	out[2] = in->m[2][0];
	out[3] = in->m[3][0];
	out[4] = in->m[0][1];
	out[5] = in->m[1][1];
	out[6] = in->m[2][1];
	out[7] = in->m[3][1];
	out[8] = in->m[0][2];
	out[9] = in->m[1][2];
	out[10] = in->m[2][2];
	out[11] = in->m[3][2];
	out[12] = in->m[0][3];
	out[13] = in->m[1][3];
	out[14] = in->m[2][3];
	out[15] = in->m[3][3];
#endif
}

Это из ufoai-2.3.1-source/src/client/renderer/r_matrix.c

Я правда не СИ-программист, но ИМХО быдлокод.

ados ★★★★★
()
Ответ на: комментарий от Eddy_Em

Но всякие итераторы, временные переменные и т.п. нет смысла называть длинными именами, хватит чего-нибудь вроде i,j,k; x,y,z; a,b,c;...

Если вам понятно, что i,j,k — набор итераторов, x,y,z — координаты обсчитываемого объекта и т.п. — это правильные названия переменных. Но вот разрабы сабжа, обзывая переменные kk, pp и т.п., руководствовались определённо не этим соображением.

geekless ★★
()
Ответ на: комментарий от Eddy_Em

> хватит чего-нибудь вроде i,j,k;

i, j — неудачный выбор, IMNSHO. Необходимость различать i, j, 1 и l очень сильно напрягает. А спутать l и 1 — это, наверное, у каждого было.

i-rinat ★★★★★
()
Ответ на: комментарий от ados

> Это из ufoai-2.3.1-source/src/client/renderer/r_matrix.c

Я правда не СИ-программист, но ИМХО быдлокод.

Матрицу можно разложить в линейный массив двумя способами, поэтому вполне нормальный код, без ненужных ветвлений. А как бы сделали вы? Циклом?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Пользуйтесь нормальным шрифтом, и ничего не спутаете.

geekless ★★
()
Ответ на: комментарий от i-rinat

А как бы сделали вы? Циклом?

Естественно.

Смысл существовать такой узкоспециализированной (4х4) функции?

ados ★★★★★
()
Ответ на: комментарий от i-rinat

Это ж какое хреновое зрение надо иметь, чтобы i, j и 1 перепутать. А одиночную l я стараюсь не использовать (несмотря на то, что с единицей ее сложновато спутать). Шрифтами надо нормальными пользоваться в редакторе!

А вообще, вроде бы даже традиционно называть целые итераторы i,j,k,m,n; числа с плавающей точкой - e,f,g,h; координаты - u,v,w,x,y,z и т.п.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от i-rinat

А как бы сделали вы? Циклом?

Если стоит задача обойтись без цикла, то так:

vadim@host3:~/tmp$ cat 123.c

void Matrix4x4_ToArrayDoubleGL (const matrix4x4_t *in, double out[16])
{
#ifdef MATRIX4x4_OPENGLORIENTATION
#define n(i) out[i] = in->m[i/4][i%4];
#else
#define n(i) out[i] = in->m[i%4][i/4];
#endif
   n(0)
   n(1)
   n(2)
   n(3)
   n(4)
   n(5)
   n(6)
   n(7)
   n(8)
   n(9)
   n(10)
   n(11)
   n(12)
   n(13)
   n(14)
   n(15)
#undef n
}
vadim@host3:~/tmp$ gcc -E 123.c 
# 1 "123.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "123.c"

void Matrix4x4_ToArrayDoubleGL (const matrix4x4_t *in, double out[16])
{





   out[0] = in->m[0%4][0/4];
   out[1] = in->m[1%4][1/4];
   out[2] = in->m[2%4][2/4];
   out[3] = in->m[3%4][3/4];
   out[4] = in->m[4%4][4/4];
   out[5] = in->m[5%4][5/4];
   out[6] = in->m[6%4][6/4];
   out[7] = in->m[7%4][7/4];
   out[8] = in->m[8%4][8/4];
   out[9] = in->m[9%4][9/4];
   out[10] = in->m[10%4][10/4];
   out[11] = in->m[11%4][11/4];
   out[12] = in->m[12%4][12/4];
   out[13] = in->m[13%4][13/4];
   out[14] = in->m[14%4][14/4];
   out[15] = in->m[15%4][15/4];

}
vadim@host3:~/tmp$ 
geekless ★★
()
Ответ на: комментарий от geekless

Для таких случаев можно вообще на препроцессоре какой-нибудь жуткий кодогенератор намутить, чтобы в теле самой функции просто писать что-нибудь вроде DO_MY_STUPID_MACROS(out, in);

Но я очень сильно сомневаюсь, что в конкретно этом случае неиспользование цикла сэкономит заметное время на вычислениях.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Я просто показал, что даже не меняя реализацию метода ни на миллиметр, можно эффективно отDRYить тот быдлокод.

geekless ★★
()
Ответ на: комментарий от Eddy_Em

> Это ж какое хреновое зрение надо иметь, чтобы i, j и 1 перепутать. [...] Шрифтами надо нормальными пользоваться в редакторе!

DOS, знаете ли. Шрифты стандартные, из видеоадаптера. Хотите наступать на грабли - наступайте, никто вам не запрещает.

Это всё личные привычки программиста, вроде той, что заставляет его писать if (0 == k) вместо if (k == 0)

i-rinat ★★★★★
()
Ответ на: комментарий от geekless

Вы из нормального кода сделали быдлокод, поздравляю. Чтобы понять исходный, мне понадобилось секунд 10. Думаю вам не больше. Весь код однородный, помещается на экран. А то, что сделали вы, вам же пришлось иллюстрировать прогоном через препроцессор.

i-rinat ★★★★★
()
Ответ на: комментарий от Eddy_Em

> Но я очень сильно сомневаюсь, что в конкретно этом случае неиспользование цикла сэкономит заметное время на вычислениях.

ага, скорее всего даже замедлит. Сброс конвейера при неверно предсказанном переходе - дорогая операция.

i-rinat ★★★★★
()
Ответ на: комментарий от ados

> > А как бы сделали вы? Циклом?

Естественно.

А цикл вызовет пару сбросов конвейера, да.

Смысл существовать такой узкоспециализированной (4х4) функции?

Здесь собрались существа из трёхмерной вселенной. Нам для преобразования координат хватает матриц 4х4.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

>> А как бы сделали вы? Циклом? > Естественно.

А цикл вызовет пару сбросов конвейера, да.

Или не вызовет. Или компилятор его развернет.

tailgunner ★★★★★
()
Ответ на: комментарий от i-rinat

> Чтобы понять исходный, мне понадобилось секунд 10.

Вам потребовалось целых 10 секунд, чтобы понять, что тут происходит копирование матрицы и, если необходимо, её поворачивание? Либо это epic fail, либо вы не пишете на сях.

А то, что сделали вы, вам же пришлось иллюстрировать прогоном через препроцессор.

И теперь вижу, что не зря, т.к. вы бы иначе его понимали бы, возможно, не меньше минуты. Умение пользоваться подобными макросами и читать их есть у каждого приличного си-программиста. Никакой магии и быдлокода здесь нет.

geekless ★★
()
Ответ на: комментарий от ados

> А когда такая задача может возникнуть?

Например, когда в игрушке fps не хватает, и разработчик хочет оптимизировать горячие участки.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

DOS, знаете ли.

Я DOS уже лет 10 (а то и больше) не видел :)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от tailgunner

> Или не вызовет. Или компилятор его развернет.

Не поленился и проверил на gcc. С -O2 он цикл не развернул. Развернул только с -O3, но мало кто отваживается на -O3. Вот и надейся на компилятор после этого.

i-rinat ★★★★★
()
Ответ на: комментарий от geekless

Вам потребовалось целых 10 секунд, чтобы понять, что тут происходит копирование матрицы и, если необходимо, её поворачивание? Либо это epic fail, либо вы не пишете на сях.

Ну я могу признать, что я тормоз. Нет, не так. Я - ТОРМОЗ. Вам от этого легче?

И теперь вижу, что не зря, т.к. вы бы иначе его понимали бы, возможно, не меньше минуты. Умение пользоваться подобными макросами и читать их есть у каждого приличного си-программиста. Никакой магии и быдлокода здесь нет.

overkill.

#define TRUE FALSE //счастливой отладки, суки...

:-)

i-rinat ★★★★★
()
Ответ на: комментарий от tailgunner

> А с -O2 -funroll-loops?

Развернул. «It also turns on complete loop peeling (i.e. complete removal of loops with small constant number of iterations)»

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Не, лучше так:

#ifdef TRUE
#undef TRUE
#endif
#ifdef FALSE
#undef FALSE
#endif
#define TRUE 0
#define FALSE 1

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от i-rinat

Ну я могу признать, что я тормоз. Нет, не так. Я - ТОРМОЗ. Вам от этого легче?

Да мне абсолютно всё равно.

#define TRUE FALSE //счастливой отладки, суки...

Это вообще при чем? Вам в универе подобную подлость подложил шутник-однокурсник, и вы с тех пор не любите макросы?

Вообще же назвать мой код нечитаемым можно — но тогда придётся назвать нечитаемой и обычную реализацию с циклом. Потому что табличновидная простыня из 16 одинаковых строк бросается в глаза сразу, а 2 строчки цикла еще надо заметить и прочитать надо. Китайский код такой китайский.

geekless ★★
()
Ответ на: комментарий от i-rinat

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

Не, место-то как раз было известно, так как дамп был в виндовом докторватсоновском логе, а разбираться пришлось, как вообще туда попали.

nanonymous
()
Ответ на: комментарий от i-rinat

oh shi. Я ведь это место смотрел, но меня смутило add_filter. Потом рвотные позывы от созерцания одно- и двубуквенных переменных стали нестерпимыми и я сдался.

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

nu11 ★★★★★
() автор топика
Ответ на: комментарий от aho

>ТС перечитался «правильных» книжек

мимо. Не читал ни одной книги про «красивый», «правильный» код, рефакторинг, стили и прочую муть.

это просто другой стиль - более минималистский

а по-моему это обычная индусская портянка

nu11 ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

>А что, по-вашему временные переменные, итераторы и т.п. стоит обзывать так

погрепай ту же переменную kk, она там на диапазоне более 1к строк встречается. Хороший такой местный итератор :)

nu11 ★★★★★
() автор топика

я просто оставлю это здесь

UCHAR_T opCode[2] = {0x02}; // why?

©

vostrik ★★★☆
()
Ответ на: комментарий от nu11

> Не читал ни одной книги про «красивый», «правильный» код, рефакторинг, стили и прочую муть

ну и зря - их читать есть смысл, нет смысла фанатично им следовать

а по-моему это обычная индусская портянка


Кто это говорит? Это говорит граф Толстой? Или Дарвин? (с)

aho
()
Ответ на: комментарий от aho

>ну и зря - их читать есть смысл
мне пока лень садиться за полновесный талмуд :) Иногда попадаются толковые статьи, выдержки и дискуссии. Плюс собственный опыт наступания на грабли, который не заменит ни одна книга.

nu11 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.