1. Си / Говнокод #16822

    +136

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    DIR_STRUCT * fill_dir_struct(DIR_STRUCT * dir_stc, _ptr_by_val_(char *) base_dir_path, _ptr_by_val_(char *) offset_dir)
    {
    	DIR_STRUCT * 		sub_dir;
    	DIR * 				srcdir;
    	struct 				stat st;
    	char 				full_sub_dir_path[MAX_PATH_SIZE];
    	struct dirent * 	dent;
    
    	sprintf(full_sub_dir_path, "%s/%s", base_dir_path, offset_dir);
    	dbgprintln("Directory %s", full_sub_dir_path);
    
    	if(NULL != (dir_stc = malloc(sizeof(DIR_STRUCT))))
    	{
    		memset(dir_stc, 0x00, sizeof(DIR_STRUCT));
    		if (NULL != (srcdir = opendir(full_sub_dir_path)))
    		{
    			if(NULL != (dir_stc->dir_path = malloc(strlen(offset_dir) + 1)))
    			{
    				strcpy(dir_stc->dir_path, offset_dir);
    				for( ;(NULL != (dent = readdir(srcdir))); )
    				{
    					if((0 != strcmp(dent->d_name, ".")) &&
    					   (0 != strcmp(dent->d_name, "..")) &&
    					   (0 <= fstatat(dirfd(srcdir), dent->d_name, &st, 0)))
    					{
    						if (S_ISDIR(st.st_mode)) //Directory
    						{
    							if(NULL != (sub_dir = fill_dir_struct(sub_dir, full_sub_dir_path, dent->d_name)))
    							{
    								dir_stc->sub_dirs 		 	  = list_append_node(dir_stc->sub_dirs, sub_dir);
    								dir_stc->dir_files_size 	 += sub_dir->dir_files_size;
    								dir_stc->sub_dir_files_count += sub_dir->sub_dir_files_count;
    							}
    							else
    							{
    								dir_stc = destroy_dir_struct(dir_stc);
    								break;
    							}
    						}
    						else 					//File
    						{
    							dbgprintln("File %s, size %lu bytes", dent->d_name, st.st_size);
    							dir_stc->dir_files 		 	 = list_append_node(dir_stc->dir_files, allocate_and_copy_char_buffer(dent->d_name, strlen(dent->d_name) + 1));
    							dir_stc->dir_files_size 	+= st.st_size;
    							dir_stc->sub_dir_files_count++;
    						}
    					}
    				}//End of for(;NULL != (dent = readdir(srcdir)); )
    				closedir(srcdir);
    			}
    			else//End of if(NULL != (dir_stc->dir_path = malloc(strlen(offset_dir) + 1)))
    			{
    				dir_stc = destroy_dir_struct(dir_stc);
    			}
    		}//End of if (NULL != (srcdir = opendir(full_sub_dir_path)))
    		else
    		{
    			dir_stc = destroy_dir_struct(dir_stc);
    		}
    	}//End of if(NULL != (dir_stc = malloc(sizeof(DIR_STRUCT))))
    
    	return dir_stc;
    }

    Восьмикратный индент, Йода нотейшн, const *(x) const в аргументах. Есть подозрение, что велосипедисты не знали о scandir.

    Это кладезь говна.

    Запостил: codemonkey, 08 Октября 2014

    Комментарии (33) RSS

    • > Йода нотейшн

      Порвало. Возьму на вооружение.
      Ответить
    • //End of if(NULL != (dir_stc = malloc(sizeof(DIR_STRUCT)))
      Типично для исповедующих сишко- (кресто-)блядство обсирать бейсик (аду), что там надо аж целых 2 (джва!) раза писать if и прочие операторы - в начале, и в конце.
      А когда у самих метод подпухнет, то немедленно пишут вот такую говнятину, потому что без неё непонятно какой где блок кода.

      Вот знаю нескольких уже умудренных опытом людей которые пишут похожие комменты (end if, end while) хотя к бейсику/аде положительных чувств детектировано не было.
      Ответить
      • > умудренных опытом людей которые
        не осилили короткие функции
        Ответить
        • Это да, но еще есть легаси, которое могут комментировать для читабельности. Просто интересно насколько часто кто видел/использует такой подход?

          Стоит ли говорить, что при изменении блока кода (с for на while) комментарии в недрах забудут поменять и он будет неактуальным, ведь компилятором оно в отличии от той же ады не проверяется.
          Ответить
          • У них глаза из жопы и IDE из жопы.
            Ответить
          • У нас принято крестонэймспейсы такими комментами закрывать, ибо там естественна и объяснима вложенность и протяжённость, похожие практики видел в бустовых сорцах.
            В остальных случаях порицается.
            Ответить
            • Ну внутри неймспейса, как правило, еще и отступа нету, так что такой коммент весьма полезен...
              Ответить
            • Кстати по поводу длинных методов - можно привести достаточное число примеров серъезных проектов, практически на любом языке, где таких методов полным полно.

              Только быдлоынтырпрайз где правят бал паттерны с декораторами, адаптерами, делегаторами, приспособленцами и прочими тупорылыми обёртками, а классы тупо делегируют работу друг другу, периодически проверяя на недопустимые значения аргумента, то там да, методы длиннее 10 строк - редкость.

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

              >В остальных случаях порицается.
              Если чё, я тоже порицаю. Дабы не возникало разночтений.
              Ответить
            • Еще
              #endif // defined(WHATEVER)
              Ответить
              • Кстати да, особенно злит что все IDE норовят выровнять все #xxx по нулевому столбцу, чтобы не дать по отступам понять какой #endif к чему относится. Это так по какому-нибудь стандарту надо или просто параноики?
                Ответить
                • а так:
                  #ifndef ALPHA
                  #  ifndef BETA
                  #    ifndef GAMMA
                  #       define OMEGA
                  #    endif
                  #  endif
                  #endif
                  Ответить
                  • О_о такой вариант даже в голову не пришел, спасибо!
                    Ответить
      • только эти комментарии не спасут от такого блядства, что если ты пропустишь одну скобочку, то в логе компилятора вместо указания ошибки будет 100-строчный бесполезный понос

        сам несколько раз так охуевал
        или пользовал класс перед объявлением - вместо указания одной ошибки компилятор раскукарекался на меня километрами бесполезных тупорылых ошибок, в которые я минут пять вдуплял
        Ответить
        • >если ты пропустишь одну скобочку, то в логе компилятора вместо указания ошибки будет 100-строчный бесполезный понос
          Неоспоримый факт. Вообще длиннющие крестопортянки ни о чем до сих пор причиняют много НЕПОНИМАНИЯ.
          Ответить
          • В языках с автовыводом типов ситуация врядли лучше. В том же ОКамле можно иногда очень долго и вдумчиво читать километры выхлопа компилятора даже без намека на то в каком файле и что именно за ошибка случилась.
            Ответить
            • >В языках с автовыводом типов ситуация врядли лучше. В том же ОКамле
              На хаскель набрасывайте. Он может через всю программу тип вывести и потом высрать непонятно чо и где.
              Ответить
              • через "всю программу" выводит немеле. а хаскель так себе и выводит предсказуемо. а немерло может где-то из строки ниже вывести рандомной и потом высрать сообщение об ошибке не в том месте, где она реально есть. в хаски тут ещё всё довольно гладко
                Ответить
              • Да, иногда вспоминаешь квадратно-гнездовую Аду, которая хоть и выносит мозг тем, что заставляет декларировать всё и вся по многу раз, зато ошибка сразу видна там, где она есть.
                Ответить
              • > На хаскель набрасывайте.
                Вот не надо, там всем топ-левел биндингам принято явно типы писать, чтобы было видно, где именно проблемы. Компилятор даже ворнинг пишет, если так не делаешь.
                Ответить
                • а если функция шаблонная то всё равно типы не надо писать?
                  Ответить
                  • Шаблоны, в моём хаски?
                    Ответить
                  • Компилятор всегда пытается вывести самый общий возможный тип. т.е.
                    f x y = x + 2 * y
                    будет автоматом работать для любых типов, которые "являются числами" (т.е. для них определён экземпляр класса типов Num). Компилятор выведет тип
                    f :: (Num a) => a -> a -> a
                    Ответить
                    • и где ты тут явно тип напишешь?
                      ааа, Num это какбэ и есть явно тип? то есть и Integer, и Float, и Vector3D - это всё Num?
                      Ответить
                      • > Vector3D - это всё Num?
                        Тут я как-то сомневаюсь что вообще есть c таким названием, и что оно Num.
                        Зато там есть Rational и Fractional
                        Ответить
                        • Vector3D тривиально написать самому, Num его тоже можно сделать без проблем:
                          Prelude> :info Num
                          class Num a where
                            (+) :: a -> a -> a
                            (*) :: a -> a -> a
                            (-) :: a -> a -> a
                            negate :: a -> a
                            abs :: a -> a
                            signum :: a -> a
                            fromInteger :: Integer -> a
                          Прелесть хачкеля в том, что можно взять чужой Vector3D и сделать его Num, не меняя Vector3D.
                          Ответить
                          • >Прелесть хачкеля в том
                            Речь о том что хацкелисты не настолько антиобобщенны чтобы включать в стандартную библиотеку вектор огранниченный унылым трёхмерным пространством.
                            Ответить
                            • > унылым трёхмерным пространством
                              Ну да. Даже в гейдеве векторы очень часто четырехмерны.
                              Ответить
                      • Последняя строка и есть тип f, он прямо так в языке и записывается (обычно строчкой выше декларации, но не обязательно). Пример:
                        -- f и g - функции на целых
                        f, g :: Int -> Int
                        
                        f = undefined
                        g = undefined
                        Num - это не тип, а "класс типов" - набор операций, которыми тип должен обладать, чтобы считаться Num. (Num a) означает ограничение на переменную типа a (что-то вроде template<typename a>, а в новых крестах обещали сделать похожее template<Num a>). Т.е. по сути компилятор вывел "Шаблон с ограничением на типы, которые можно в шаблон подставлять".
                        Ответить
                      • > Num это какбэ и есть явно тип
                        Не, Num это тайпкласс, который должен обладать определенными методами (арифметика вроде бы и че-то там еще). А Integer, Float и т.п. являются его инстансами. Vector3D тоже можно сделать инстансом Num, если получится запилить все методы, требуемые Num'ом, и они будут иметь какой-то смысл.
                        Ответить
                      • Более общее понимание происходящего связано с формальной логикой (не зря же используется символ material implication). Запись f :: (Num a) => a -> a -> a говорит о том, что функция оперделенная на домейне Num (что подразумевает упорядоченность и наличие minimal fixed point) предполагает (implies) существование функции от элемента этого домейна, к элементу этого домейна, скомпонованую с еще одной такой же функцией. Т.е. это формальное обещание того, что в домейне Num существует функция f с вышеописаными свойствами.
                        И с пониманием этого приходит беда-печаль-огорчение, т.как material implication не эквивалентно обычному implication. Т.е. не все, что истинно предполагает другие истины (нужна причинно-следственная связь). Дана Скотт плачет горькими слезами, Милнер стреляется и пьет яд. Конец первого действия.
                        Ответить
                        • >Дана Скотт плачет горькими слезами, Милнер стреляется и пьет яд. Конец первого действия.
                          Прошу Вас пишите еще! Выдающаяся драматургия.
                          Ответить
                • >там всем топ-левел биндингам принято явно типы писать
                  Это и спасает. Но многие не пишут, ОЛОЛО ПОСМОТРИТЕ КАКОЙ КРАТКИЙ ЯЗЫК. Я ДЕЛАЮ ПРОГРАММЫ В ОДНУ СТРОЧКУ.
                  Ответить

    Добавить комментарий