Кресты / Говнокод #12337 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
#include <iostream>
using namespace std;

struct T{int a;T(){cout<<"T"<<this<<endl;}~T(){cout<<"~T"<<this<<endl;}};
struct D:public T{int b;D(){cout<<"D"<<this<<endl;}~D(){cout<<"~D"<<this<<endl;}};

int main() {
   T* a = new D[2];
   cout<<"mission failure"<<endl;
   delete[] a;   
   return 0;
}

Писал тест специально для Тараса:
Виртуальный деструктор в базовых классах нужен:
*Для вызова деструкторов всех потомков. Иногда это не нужно, тк поля структуры тривиальны. Согласен с Тарасом.
*Для правильного выбора перегруженного оператора delete. Создал одним менеджером памяти, а удалил в другой - это плохо. Но также бывает редко и только в специфичных проектах.
Но вот то, что демонстрируется в этом примере - думаю чего-нибудь такого создатели той библиотеки, что ковырял Тарас, и опасались.
Не просто было вызван деструктор только для предков, забыв о деструкторах потомков, но и:
*Деструктор предков был вызван для this не по тем адресам, где расположены объекты.
Не удивлюсь, если:
*В некоторых кулхацкерских реализациях менеджеров памяти будет удален буфер меньшего размера и куча попортится или оставшаяся не удаленная часть массива в куче просто утекет.
http://liveworkspace.org/code/2X3MR0$8

Запостил: LispGovno LispGovno, (Updated )

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

  • Нафиг такие языки не нужны, где столько извращений...
    Ответить
    • Сразу минус. Языки без извращений слишком скучны и не сексуальны.
      Ответить
      • Я знал, что крестоблуды заминусуют, и это лишнее подтверждение.
        Если хочется извращений для души, пожалуйста, миллион способов их получить. Напишите объектро-ориентированный Malbolge и занимайтесь содомией до смерти. Но если хочется достигнуть цели, они не нужны.

        Сам слез с крестов 3 года назад, ни о чем не жалею.
        Ответить
            • См. ниже.
              Быдлосишарпик - хороший язык для своих задач.
              Его создатели собрались и сказали, давайте возьмем С++ и выкинем из него все детские грабли. Пусть он будет медленным и домохозяечным, зато программисты не отобьют себе яйца с первого же шага.
              Ответить
              • Медленным, домохозечным, с непредсказуемым временем выполнения любой операции (из-за потока с ГЦ).
                Ответить
                • Вижу, сишрпобляди неосилили С++ и из-за батхерта всех минусуют. Зато крестобоги смотрят на них как на говно.
                  Ответить
                  • Я вижу баттхёрт уборщикоблядей. Я знаю, что уборщик может быть с гарантированной верхней границй задержки, но ведь хуй кто такими пользуется, почему - не знаю. Да и нахрен они не нужны.
                    Ответить
              • По воле долга (временно) перелез с жабы на плюсы, не сказать, что получаю баттхёрт или наступаю на грабли. Не знаю вот теперь, как буду возвращаться на жабу, где нет деструкторов, шаблонов и boost.
                Ответить
                • Ты серьёзно или зелёный цвет забыл?

                  ps: Метопрагромирванье забыл упомянуть.
                  Ответить
                  • > Метопрагромирванье забыл упомянуть
                    Я его не особо использую, ибо
                    1) я пишу код, который будут читать другие люди, скорее всего, не особо искушённые в мета-
                    2) нет пока особой потребности, а метапрограммирование ради метапрограммирования мне неинтересно
                    Ответить
                    • Как же так? Это свитая обязанность каждого крестушка нагенерировать кода через шаблоны, чтобы проект компилировался подольше, а тем временем:
                      http://xkcd.ru/i/303_v1.png
                      Ответить
                    • Я бы поплакал, если бы был уверен, что передо мной не толстый тролль. Сам понимаешь, подифолту все посты на говнокодсру зеленые.
                      Ответить
                      • Я абсолютно серьёзен и честен в этом вопросе. Не думал, что когда-нибудь буду отзываться о крестах хорошо, но этот день настал.
                        Ответить
                        • Ну вот теперь и у меня навернулись слёзы счастья. Плакать от счастья мужику - это нормально. Присоединяйтесь.
                          Ответить
                    • type implicit conversion operator как реально называется по стандарту С++? То есть под каким именем в стандарте упоминается?
                      Ответить
                      • Интересует общепринятое англицкое название оператора из следующего кода, которое упоминается в стандарте:
                        struct C
                        {
                          template<class T>
                          operator T(){return T();}
                        };
                        Ну или хотя бы на русском назовите.
                        Ответить
                          • Забавно, но если раскомментировать строку, то
                            http://liveworkspace.org/code/lGIIZ$21
                            , то не скомпилируется, хотя "лишний" конструктор от int максимально спрятан и вроде влиять не должен.
                            #include <iostream>
                            using namespace std;
                            struct D
                            {
                               template<class T>
                               operator T() const {return T();}
                            };
                            struct M
                            {
                               M(){cout<<"M";}
                               M(const M&){cout<<"koko";}
                               //private: explicit M(int){cout<<"ops";}
                            };
                            int main() {
                               M a((D()));
                               cout<<"ko";
                               return 0;
                            }
                            Ответить
                            • с++ 98, 12.3 Conversions, пункт 2:
                              User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2). Conversions obey the access control rules (clause 11). Access control is applied after ambiguity resolution (3.4).
                              Ответить
                              • Да как верно подметил Борманд, хотелось бы private: explicit учитывать при разруливании амбигити
                                Ответить
                                • Эм, я наоборот подметил, что в стандарте написано, что сначала пытаются разрешить неоднозначности, и только если их нет - проверяется приватность.

                                  P.S. А иксплисит тут вообще не в тему, ты же явно юзаешь конструктор.
                                  int test(M m) {}
                                  int main() {
                                      M m(5); // тут explicit не мешает
                                      test(5); // а тут ругнется
                                      return 0;
                                  }
                                  Ответить
                • > вот теперь, как буду возвращаться на жабу, где нет деструкторов, шаблонов и boost.
                  Но зачем?
                  > не сказать, что получаю баттхёрт или наступаю на грабли
                  Ну и на кой она нужна? По сути сей язык изобрели-то для тех кто обезьян, которые не осилили (и не смогут осилить) плюсы.
                  В плюсиках и перегрузка операторов, и лямбды.
                  А в жабе что? Мегабайты xmlя и паттерны?
                  Ведь удобней бриться острой бритвой, чем тупой жабой. Просто надо быть осмотрительным.
                  Ответить
                  • Может лучше что-то среднее, если жаба и кресты - это противоположности? Например шарпик. И не кресты, но и не жаба.
                    Ответить
                    • Шарпик - кресты 00-х. Туда пихают всё подряд, без меры.
                      Жаба просто не стала быдловской из-за неудобной либы и выского порога вхождения.
                      Для крестов был быдлер, для пхп денвер, для шарпа - студия.
                      Ответить
                      • Кресты появились раньше. С 00х шарпик разрастись не успел, поэтому пока ещё вменяем.
                        Ответить
          • Сначала по работе C#.
            Потом Common Lisp, Objective-C
            Сейчас вот опять приходится к С++ возращаться, точнее к особо извращенной гибродной его форме Objective-C++, потому что некоторые библиотеки чисто на С++, их надо как-то присовокуплять к остальному коду.

            Я не утвраждаю, что C++ говно, просто меня расстраивает неистовое стремление некоторых превратить его богатый набор возможностей в говенное кровавое месиво. И эта тенденция последнее время стала повальной.
            Ответить
              • Это когда в 1м файле два совершенно разным типов ООП, один от Obj-C, второй от C++
                Че-нить типа
                @implementation SomeClass
                
                - (void) someMethodWithParameter: (int) par
                {
                  CppClass *ccpClass = new myNameSpace::cppClass(par);
                  cppClass->doSomeWork();
                  delete ccpClass;
                }
                
                @end


                Или:

                void SomeCppClass::doSomeWork()
                {
                    SomeObjClass *objClass = [[SomeObjClass alloc] initWithCppClass: this];
                    [objClass doSomeOtherWork];
                    [objClass release];
                }


                И прочий маразм 🙂
                Ответить
                • void SomeCppClass::doSomeWork()
                  {
                      SomeObjClass *objClass = [[SomeObjClass alloc] initWithCppClass: this];
                  Шизафрения.
                  Ответить
                  • Да, такое не встречается почти никогда. Но вы ведь любите клубничку?)
                    Ответить
  • > T* a = new D[2];
    Ага, а T и D разного размера, оно хоть иногда нормально работает, a[1] корректно определяется?
    Ответить
    • Неа, индексирование такого говна никогда не заработает.
      Ответить
      • Ага, нормально, только если в прошлом случае прогу не распидорашивало к хуям, из-за того что вызывался не тот деструктор, то теперь будет. (Что, впрочем, лучше, т.к. молчаливая ошибка хуже краша).
        Ответить
      • Ну и в чём смысл удаления этой херни, которую даже использовать нормально нельзя?
        Ответить
        • Она не удалится. delete[] посчитает это массивом более мелких элементов (T), и начнет вызывать у них по порядку деструкторы. На некоторых ему повезет, и там действительно окажется vtable от D, и вызовется деструктор от D, на некоторых вместо vtable будет хуита данные из середины других D. Собственно дойдя до кривого vtable delete[] попытается найти в нем виртуальный деструктор и ... кровь-кишки-распидорасило.

          P.S. Забавно, но в gcc delete[] вызывает деструкторы от конца массива к началу, видимо так цикл получается оптимальней, а в стандарте все равно написано, что вызовутся все, но порядок не указан. Из-за этой фишки на данном примере не получится увидеть "правильно" вызванный деструктор.
          Ответить
  • Говно ты написал очередное. Обманул бедный компилятор крестов. Кастовать указатель на массив в указатель на массив других классов нельзя. Ни при каких обстоятельствах. Кастовать можно только указатель на один объект в указатель на другой объект, то что компилятор позволяет сделать то что ты написал - так он просто не понимает, чего ты там в этих указателях держишь - массив или один объект.
    Ответить
    • Кстати надо посмотреть как адоязык это делает, у него массивы поумнее будут, стопудов где-то хранят размер элементы при выполнении.
      Ответить

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

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8