1. C++ / Говнокод #19698

    +1

    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
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    template < typename CType >
        void list < CType >::sorted_push(CType val, long int key)
    {
    	if (head) {
    		// Создаём контейнер и помещаем в него полученное значение
    		container < CType > *new_cont;
    		container < CType > *tmp = head;
    
    		new_cont = new container < CType >;
    		new_cont->set_key(key);
    		new_cont->set_cargo(val);
    
    		while ((tmp != tail) && (key > (tmp->get_key())))
    			tmp = tmp->get_next();
    
    		if ((tmp == tail) && (key > (tmp->get_key()))) {	// Если выполнились одновременно два условия в цикле
    			new_cont->set_next(tmp->get_next());	// Вставляем в самый конец
    			new_cont->set_past(tmp);
    			tmp->set_next(new_cont);
    			tail = new_cont;
    		} else {
    			new_cont->set_next(tmp);
    			new_cont->set_past(tmp->get_past());
    			if ((tmp->get_past()) != NULL)
    				tmp->get_past()->set_next(new_cont);
    			if (tmp == head)
    				head = new_cont;
    			tmp->set_past(new_cont);
    		}
    
    		if (empty) {
    			empty = false;
    			tail = head;
    		}
    	} else {
    		container < CType > *new_cont;
    
    		new_cont = new container < CType >;
    		new_cont->set_key(key);
    		new_cont->set_cargo(val);
    
    		new_cont->set_next(head);
    		tail = head = new_cont;
    		empty = false;
    	}
    }
    
    template < typename CType > CType queue < CType >::pop()
    {
    	container < CType > *tmp = list<CType>::head;
    
    	if (tmp == NULL) {
    		std::cerr <<
    		    "Стек пуст! Стек возвращает мусор! ";
    		list<CType>::empty = true;
    	} else {
    		CType tmpval = list<CType>::head->get_cargo();
    		// Переходим к следующему элементу
    		list<CType>::head = list<CType>::head->get_next();
    		if (list<CType>::head == NULL)
    			list<CType>::empty = true;
    		delete tmp;
    		return tmpval;
    	}
    }
    
    template < typename CType > CType stack < CType >::pop()
    {
    	container < CType > *tmp = list<CType>::tail;
    
    	if (tmp == NULL) {
    		std::cerr <<
    		    "Очередь пуста! Возвращается мусор! ";
    		list<CType>::empty = true;
    	} else {
    		CType tmpval = list<CType>::tail->get_cargo();
    
    		// Переходим к предыдущему элементу
    
    		if (list<CType>::tail != list<CType>::head)
    			list<CType>::tail = list<CType>::tail->get_past();
    		else
    			list<CType>::empty = true;
    		delete tmp;
    		return tmpval;
    	}
    }

    пострелял себе в ногу

    Запостил: viktorokh96, 25 Марта 2016

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

    • сложный прекол
      Ответить
      • Просто говнище. После pop() остаются указатели на мёртвые блоки памяти в head/tail. Есть ненулевой шанс потом на них налететь, особенно если в push() проверка такая же как в push_sorted (т.е. на head вместо empty)...
        Ответить
        • Похоже на лабу

          Давайте лучше обсудим вот http://goo.gl/9wa58a
          Меня аж рапирает от желания поделиться
          Ответить
          • echo '<option value="myaso"> Мясо </option>';
            echo '<option value="moloko"> Молоко </option>';
            echo '<option value="navoz"> Навоз </option>';

            годно

            >if ($_POST['table']=='xleb') $table=$_POST['table'];
            братишка
            Ответить
    • > Стек возвращает мусор!
      > Возвращается мусор!
      За возврат мусора надо убивать. Но почему-то отсутствие return'а - всего лишь warning.
      Ответить
      • >>За возврат мусора надо убивать.
        Так это же первое правило сей: "мусор на входе -- мусор на выходе", не?
        Ответить
        • А где здесь мусор на входе?

          Не можешь вернуть - кидай исключение. Нелья исключение - делай аборт.
          Ответить
          • Мусор-на-входе это неправильное состояние.

            Существует два подхода сообшить о невозмжности сделать что-то:
            1) потребовать от клиента всегда проверять возможность (и тогда если он полез без проверки можно кидать эксепшен или срать мусором)
            2) возвращать заранее оговоренное (нуль, минус один итд)

            В частности тут можно написать так: "клиент обязан следить за тем что очередь не пуста. Если пуста -- это UB и УГ"
            Ответить
        • Ну или хотя бы просто assert(tmp != NULL), а не это говно с cerr и возвратом мусора втихушку...
          Ответить
          • да в чуть более высокоуровневых ЯП так и принято делать
            ну там в джавововом ентерпрайзе принято проверять Preconditions, чтобы сразу кинуть IllegalStateException("Can't pop, queue is null") чем вернуть null, и потом через 100 строк получить NPE
            Ответить
            • Ну у нас и в сишке/плюсах принято прекондишены как минимум ассёртать.
              Ответить
              • ну наверное лучше так, да
                тем более что ассерт можно отключить в продакшен коде (даже в жабе можно)

                Макконел в своей красной книге "code complete" целую главу написал про правильные контракты

                типа если у вас написано "не пихайте сюда число больше чем 42" то лучше сразу проверьте и упадите

                с другой стороны один рубист писал что нефиг тратить строчки на "защиту от дурака". Если клиент кода не читает мануалов и сует пальцы в розетку -- сам дурак
                Ответить
                • Рубисты еще те ЧСВ-шные мудни.
                  Ответить
                  • да?
                    а мне казалось они добрые и японские
                    Ответить
                    • Ты наверно и про гопников то же думаешь.
                      Ответить
                      • а тебя рубисты пиздят и кидают на телефоны?
                        Ну извини тогда

                        Может тебе в секцию бокса записаться?
                        Ответить
              • > прекондишены как минимум ассёртать.
                так это везде принято
                фаст фейлр же
                Ответить
          • Я тупо не понимаю что может вернуть шаблонная функция, если тип неизвестен, ибо нуб. Если кидать исключение - как обрабатывать? Была версия с абортом, но потом передумал... Вот и хз)
            Ответить
            • null ;)
              Ответить
              • Да, но
                Null где то задефайнен в 0, и компилер просто материться что тип который я ему сую ( а сую класс) не может принять ноль... Хотя можно бросать ссылку.. Хм а это идея))
                Ответить
                • Не, не прокатит, буду возвращать ссылки вместо значений - выстрелю себе в ногу еще раз, а она уже и так вся дырявая. Просто элементы стека удаляются и ясное дело в штатном режиме вернется указатель на мусор... Потому то я от этой идеи изначально отказался
                  Ответить
            • Просто ассёрт напиши, если клиент обещает не звать pop() на пустом стеке.

              А если хочется возвращать пустое значение - boost::optional в помощь.
              Ответить
              • Теперь предупреждении от компилера нет, вроде норм
                template < typename CType > CType stack < CType >::pop()
                {
                	try {
                		if (list < CType >::is_empty())
                			throw "Falure! Stack is empty!";
                
                		container < CType > *tmp = list<CType>::head;
                		CType tmpval = list<CType>::head->get_cargo();
                		list<CType>::head = list<CType>::head->get_next();
                		delete tmp;
                		if (list<CType>::head == NULL)
                			list<CType>::empty = true;
                		return tmpval;
                
                	}
                	catch (const char *falure) {
                		std::cout << falure << std::endl;
                		abort();
                	}	
                }
                Ответить
                • Улучшил.
                  template < typename CType > CType stack < CType >::pop()
                  {
                  	try {
                  		if (list < CType >::is_empty())
                  			throw "Falure! Stack is empty!";
                  
                  		container < CType > *tmp = list<CType>::head;
                  		CType tmpval = list<CType>::head->get_cargo();
                  		list<CType>::head = list<CType>::head->get_next();
                  		delete tmp;
                  		try {
                  			if (list<CType>::head == NULL)
                  				throw &stack < CType >::pop;
                  		}
                  		catch (CType(stack<CType>::*)()) {
                  			list<CType>::empty = true;
                  		}
                  		return tmpval;
                  	}
                  	catch (const char *falure) {
                  		std::cout << falure << std::endl;
                  		abort();
                  	}	
                  }
                  Ответить
                  • Ну да, так лучше. Но ты tail всё-таки занули, когда список опустеет. Некрасиво оставлять указатели на мусор.
                    Ответить
    • >> Стек пуст! Стек возвращает мусор!

      Щито? Щито блеадь?
      Ответить
      • что-что
        сразу представляется как BP или SP перехлестывают через границу стека и делают stack underflow

        А на самом деле там ничего даже близко такого нет
        Ответить
        • а СК в ТБ не КПСС, ХСС?
          Ответить
          • а што не так?
            тебе кажется смешным тот факт что SP указывает на стек (и BP тоже, если не включен режим omit-frame-pointer)?
            Ответить
            • Вероятно, он привык абстрагироваться от железа.
              Ответить
              • Да я тоже не то что бы на асме каждый день пишу
                Ответить
        • 16-битные x86 ещё не устарели?
          Ответить
          • RSP, RBP
            так лучше?
            Ответить
            • Нет. Тут уже не будет тёплого лампового underflow этих регистров...
              Ответить
              • А можно перейти в 64битный режим без включения протектед мод и пейджинга?
                Ответить
                • Нет.
                  Ответить
                  • А в 32х битный можно

                    тогда считайте что я сказал ESP и EBP

                    Просто у меня почерк такой что я E часто пишу как R
                    Ответить
    • Почему чем больше в коде шаблонов, операторов сравнения и обращений к указателям на объекты, тем больше он похож на говно?
      Ответить
      • потому что тебе не стоит кодить на плюсах
        Ответить
      • Потому что ты не умеешь операторы сравнения, шаблоны и указатели
        Вот тебе так и кажется
        Ответить
        • Нет, просто все эти волосатые идентификаторы, лишние скобки шаблонов, звёзды и т.п. отвлекают от сути, снижают абстрактность, порою меняют смысл. Нужно смотреть, нет ли там звезды, которая сделает элемент массивом.
          Сравните,
          fac x = if x <= 0
            then 1
            else n * fac x

          int fill_with_fac(int x, int* fac) {
            if(x < 0) return 1;
            *fac = 1;
            while(x > 0) {
              *fac *= x;
              x --;
            }
            return 0;
          }

          В первом случае видна суть алгоритма, во втором - видна реализация, а суть ускользает.
          Ответить
          • > Сравните

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

            Поскольку чистые функциональные языки тоже не нужны, даже в каскеле есть IORef и прочие IOArray.

            Ну и вся эта абстракция к тому же разбивается о суровые реалии производительности, поэтому часто важно использовать какой-нибудь UnboxedXxx и писать тонны бройлерплейта.
            Ответить
            • Можно и на сишке написать ближе к сути:
              int fac(int x) {
                int f = 1;
                for(int i=1; i<=x; ++i) f *= i;
                return f;
              }

              > разбивается о суровые реалии производительности
              Вот в том и дело, что кроме сути в коде приходится вычитывать всякую питушню о производительности, особенностях хранения, особенностях языка.

              P.S. А переполнение я не учёл ни там, не здесь. И вот придётся кому-то потом читать код правильного факториала ещё и с проверкой на переполнение.
              Ответить
              • > приходится вычитывать всякую питушню о производительности, особенностях хранения, особенностях языка

                Добро пожаловать в суровый мир инженеров.
                Ответить
                • Дяденька, а вам технический спирт выдают для инженерных нужд?
                  Ответить
                • )вспоминается мышхъ который оптимизировал программу под ширину банка памяти, гг) знаете же эту книжку?
                  Ответить
                  • это вообще-то все делают, кто с линейной алгеброй работают, например
                    Ответить
                    • все? с алгеброй? вот реально под ширину банка?
                      То есть если у меня ранг состоит из 16x4 то у меня одна версия программы, а если 8x8 то другая?

                      Даже КК признавал что 80% его оптимизаций специфичны для конкретного чипсета (точнее контроллера памяти) а теперь-то и вовсе
                      Ответить
                      • > То есть если у меня ранг состоит из 16x4 то у меня одна версия программы, а если 8x8 то другая?
                        разные версии никто не пишет, есть кодогенератор, который детектит всё это при билде под конкретную машину
                        так сделано в ATLAS и FFTW, к примеру
                        Ответить
                        • В jitах и вовсе адаптивная генерация на ходу.

                          Например всякие деления оптмизируются в умножения на константу плюс сдвиг >> size_t. НО ТОЛЬКО в случае если на целевой машине деление достаточно тормозное.
                          Ответить
              • если тебе не нужна "всякая питушня с производительностью", то тебе и плюсы не нужны.
                Ответить
              • Внезапно, программисты программируют компьютеры. А все эти твои тараканы у тебя от того, что ты девственник.
                Ответить
            • > Поскольку чистые функциональные языки тоже не нужны, даже в каскеле есть IORef и прочие IOArray

              наличие этих вещей не делает кацкел не чисто функциональным
              Ответить
              • > наличие этих вещей не делает кацкел не чисто функциональным

                Да, тут я слукавил. Ведь каскел программа ничего не производит эффектов, только лишь конструирует чистое значение IO, которое магически исполняется грязным рантаймом.
                Ответить
                • это тоже довольно далёкое от реальности представление, хотя и допустимое
                  щас я длинно отвечаю на другой пост, там будет изложен мой дзен
                  Ответить
          • ты только что доказал что функциональный подход няшнее императивного
            ктож спорит-то?

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

            но си это си, без сей никуда
            увы
            Ответить
            • > ты только что доказал что функциональный подход няшнее императивного
              > ктож спорит-то?
              Я бы мог поспорить, коли больше знаний было.
              Няшнее - что-то среднее. Где при случае можно и чистую функцию и GC, и при случае - когда можно переписать 1 бит в сложной структуре вместо того, чтобы возиться с неизменяемыми структурами данных.
              Ответить
          • рекурсия по значению в первом и цикл по указателю во втором случаях. Вам фабрикацией улик надо было заниматься...

            int fac(int x) {
                return (x <= 1) ? 1 : x * fac(x-1);
            }
            Ответить
            • Я пытался ввести максимальные различия. Код, где максимально хорошо виден алгоритм и код, в котором максимально хорошо видна реализация, и алгоритм в ней тонет.
              Хотел что-то такое, как у Вас, написать вместо первого кода, но понял, что с введением псевдохаскеля контраст будет выше.
              Ответить
              • а ты не обфусцируй код и его будет просто читать
                Ответить
      • ВОТ ЭТО ДА
        Ответить
      • показать все, что скрытоvanished
        Ответить
      • ну так сказал, и перешел на ПХП, да?
        Ответить
    • показать все, что скрытоvanished
      Ответить
      • ЁБ ТВОЮ МАТЬ.
        Ответить
      • throw UserNotFoundException()

        они там все наглухо ебанутые. ну какое это исключительное блядь поведение?
        при чем у них же в стандартной библиотеке куча методов типа bool TryGet(key, ref reference), он блядь мимо них что ли прошел?
        Ответить
        • да сука

          Какой способ ваш любимый
          33.72%
          Exceptions
          Ответить

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