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

    +167

    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
    struct LexicalToken
            {
            public:
                LexicalToken(DataStructs::Lexem &lex,
                             SyntaxTree::SyntaxNode::Type type,
                             const IOSystem::Position &pos = IOSystem::Position()) :
                    lexem(lex), position(pos), type(type)
                {}
    
                LexicalToken(const LexicalToken &other) :
                    lexem(other.lexem), position(other.position), type(other.type)
                {}
    
                LexicalToken& operator = (const LexicalToken &other)
                {
                    memcpy(this, &other, sizeof(LexicalToken));
                    return *this;
                }
    
                DataStructs::Lexem &lexem;
                IOSystem::Position position;
                SyntaxTree::SyntaxNode::Type type;
            };

    Use pointers, Luke

    Запостил: Elvenfighter, 09 Мая 2011

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

    • Обратите внимание на operator =
      Ответить
      • Никогда, никогда не делайте так.
        Ответить
        • Зато потом можно через memcmp() сравнивать :)
          Ответить
        • показать все, что скрытону только при наследовании косяк может возникнуть... а в данном примере это - херовый стиль, но работает...
          Ответить
          • Не только. Например у нас в полях содержится std::string. memcpy попросту скопирует указатели из одного обьекта в другой. Естественно, когда уничтожится один из обьектов (и вызовется деструктор для его std::string), то указатель из std::string внутри другого обьекта не будет валидным.

            А при наследовании какраз косяков не возникнет. А именно: при высходящем преобразовании ссылок/указателей они меняют свое значение, чтобы точно указывать на родительский обьект внутри дочернего. В результате работать будем всегда со ссылкой на нужный нам обьект, и копирование будет вполне адекватным.
            Ответить
            • а если оператор присваивания унаследуется от родителя?
              Ответить
              • Вдруг - бывает только пук. Оператор присвоения и конструкторы не наследуются, осильте матчасть.
                Ответить
                • Как это не наследуется оператор присваивания?
                  Создай родительский класс и дочерний. У родителя реализуй оператор присваивания, а у потомка - нет. Потом проверь код:
                  потомок1 = потомок2;
                  Ответить
                  • Будет вызов дефолтного оператора присвоения, который вызовет оператор присвоения родительского класса. Чтобы разрешить использование родительского оператора напрямую нужно написать чёто типо using Parent::operator =;
                    Ответить
                    • Не парьтесь, в наше время редко кто-то докапывается до сути, все принимают за чистую монету то, что видят.
                      Ответить
                    • А, так вы просто терминологией не владеете.

                      Есть понятие наследования (inheritance), есть понятие видимости (visibility). Это - два совершенно разных понятия, друг к другу никакого отношения не имеющих.

                      Как я уже писал, оператор присваивания предка прекрасно наследуется потомком. Проблема только в том, что уналедованный оператор приваивания в потомке невидим (hidden). Вы, похоже, прекрасно заете, как сделать его видимым (unhide при помощи using-declaration). Но к наследованию/ненаследованию это никакого отношения не имеет, вопреки вашим ошибочным представлениям.

                      P.S. Отдельно стоит заметить, что в языке С++ нет понятия "дефолтного оператора присваивания". Есть понятие compiler-provided оператора присваивания (не знаю, как лучше сказать по-русски). Термин "дефолтный" (default) имеет в С++ особый, четко определенный смысл, к compiler-provided оператору присваивания никакого отношения не имеющий.
                      Ответить
                      • http://en.cppreference.com/w/cpp/language/copy_assignment

                        > class_name & class_name :: operator= ( const class_name & ) = default;

                        а это что блядь?
                        Ответить
                • Про оператор присваивания - бред полный. Где это вы такое вычитали? Если уж "осиливать" матчасть, то не по говноучебникам, и не будет таких конфузов.

                  Оператор присваивания - прекрасно наследуется. Не надо просто забывать, что он после этого скрывается оператором присваивания класса-наследника. Это тем не менее не отменяет того факта, что он наследуется.

                  Скрытый унаследованный оператор можно "открыть" при помощи using-декларации. Альтернативно, скрытый унаследованный оператор можно вызвать через квалифицированное имя.

                  С конструктором - другое дело. Он "не наследуется", но от этого никому ни жарко ни холодно, ибо язык С++ не предосталяет синтаксиса для вызова конструктора.
                  Ответить
                  • Бьярн Страуструп, "Язык С++", раздел 12.2.3, последний абзац: "... операторы копирования не наследуются. Конструкторы никогда не наследуются". чистописец, учи матчасть, ты уже неоднократно замечен в несении откровенной пурги.
                    Ответить
                    • нихуя такого в 12.2.3 не вижу, в последнем абзаце про слайсинг. Издание какое трупастрауса? Если старое то информация может быть не актуальна для сегодняшнего стандарта.
                      Ответить
                    • В издании ANSI ISO IEC 14882 2003 пункт 12.2.3 состоит из одного единственного абзаца и говорит о временных объектах.
                      Ответить
                      • гость говорит не про стандарт, а про книгу страуструпа, но в ней тоже ничего про ненследоапние операторов присвоения нет
                        Ответить
                    • Во-первых, ничего подобного в 12.2.3 в TC++PL у Страуструпа нет.

                      Во-вторых, читать TC++PL надо таки в оригинале, а не в переводе Васи Гири из соседнего двора. Остюда, по-видимому, и терминологическая каша у тебя в голове.

                      В-третих, в TC++PL можно вычитать много чего, как например заявления о том, что у скалярных типов есть констукторы (что совершенно не верно). Не надо забывать о том, что TC++PL - это сознательно упрощенный учебник "для чайников" (сравните по объему стандарт языка и книгу Страуструпа), который никаким авторитетом в области формального/профессионального понимания языка не обладает. Язык С++ определяется его стандартной спецификацией, а не тем, что там понаписано в страуструповской книжке для пионеров, да еще и в непонятно каком переводе.

                      Поэтому, великодушно даю правило под запись: когда ты видишь расхождения с тем, что говорю я, и тем, что написано у Старауструпа в TC++PL, ты не в форум квакать лезешь, а быстренько берешь красный фломастер, аккуратненько вычеркиваешь соответствующий абзац из Страуструпа, а рядышком на полях приписываешь то, что сказал я, слово в слово. Заучиваешь перед сном. Повторяешь утром. Это, надеюсь, поможет тебе хоть чему-то научиться и избежать подобных публичных ляпаний задницей в лужу в будущем.

                      И наконец, в четвертых, "откровенная пурга" - она в твоей голове. Поэтому-то она тебе везде и мерещится.
                      Ответить
                      • TheCalligrapher разбушевался:)
                        Ответить
                        • классическое жжение в нижней части спины, даже менторский тон поблек и перешел на "ты"
                          Ответить
                          • А у меня просто временами фидошные манеры просыпаются. В Фидо на "Вы" обращаются только тогда, когда пора уже бить морду.
                            Ответить
                            • Забавно встретить фидошника ка сайте, где большинство комментаторов родилось в 1996 году
                              Ответить
                        • Да ну... Какое там "разбушевался"... В первый раз, что ли? Лениво запостил стандартный шаблонный ответ на стандартный шаблонный наезд, лишь вставив в специально оставленные места некоторые специфические детали.

                          Все настолько стандартно-шаблонно, что меня, я думаю, по этому ответу в пять минут выгуглить можно.
                          Ответить
                      • Морон, ты не отличаешь TC++PL от книги "Язык С++" авторства Б. Страуструпа, издание 3, специальное? Ну тогда вобщем-то очевидно и понятно, почему ты там этого не нашёл, и почему ты вечно путаешь право с лево и несёшь ахинею.
                        Ответить
                        • Ты пиздишь. Что по твоему TC++PL ?
                          Ответить
                        • По существу, значит, сказать нечего?

                          Кстати, может у тебя какое-то особо "специальное" издание TC++PL? Не иначе как в переводе Васи Гири из соседнего двора...

                          P.S. Я надеюсь, не надо объяснять, что TC++PL - это и есть "Язык С++" авторства Б. Страуструпа?
                          Ответить
                      • ебаааать, вы посмотрите на эту крестоблядь, распетушился своей крестоеблей ЛОЛ
                        засунь свой петушиный стандарт себе в очко *lmfao*
                        Ответить
                  • >не по говноучебникам, и не будет таких конфузов.

                    ЛОМАЮЩИЕ ИЗВЕСТИЯ!
                    ГЛАВНАЯ БИБЛИЯ КРЕСТОБЛЯДЕЙ -- ГОВНОУЧЕБНИК!
                    БИЯРНЕ ТРУПОСТРАУС -- ГОВНОПИСАТЕЛЬ!
                    СПЕШИТЕ ВИДЕТЬ У ВСЕХ ПАРАШ СТРАНЫ!!
                    Ответить
                    • Тарас, залогиньтесь.
                      Ответить
                    • Итак, блядь: C++ Standard - ANSI ISO IEC 14882 2003

                      13.5.6
                      ......Themeaning of the operators =, (unary) &, and , (comma), predefined for each type, can be changed for specific class and enumeration types by defining operator functions that implement these operators. Operatorfunctions are inherited in the same manner as other base class functions.

                      13.5.3.1
                      An assignment operator shall be implemented by a non-static member function with exactly one parameter.Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (12.8), a base class assignment operator is always hidden by the copy assignment operator of thederived class.
                      Ответить
                      • Хорошее сокращение у п. 13.5.3 - [over.ass].
                        Ответить
                      • Ну то есть мои слова буквально, но по-английски.

                        Не разберешь только, кто постит - сплошные guest-ы...
                        Ответить
    • Отдельная песня - необоснованное использование 'sizeof(type)'. Код должен быть настолько типонезависим, насколько это возможно. По этой причине 'sizeof' должен по-возможности использоваться с выражениями, а не с типами. В данном случае (закрывая на минутку глаза на говокодовость такого подохода к реализации оператора присваивания), 'memcpy' должен был выглядеть так
      assert(sizeof other == sizeof *this); // тут лучше static assert 
      memcpy(this, &other, sizeof other); // или 'sizeof *this'
      Ответить
      • -
        Ответить
      • некоторые так не считают смотри в MSDN
        там смотри sizeof(MEGASTRUCT) знаеш почему ?
        видно ты ниразу не брал размер указателя когда хотел
        узнать размер объекта
        бывает есть имя переменной var ты автоматом пишеш sizeof(var)
        и получаеш баг если это был указатель я подъебывался на этом
        поэтому способ sizeof(MEGASTRUCT) обоснован и имеет право на жизнь
        и более того именно так делает MS код в MSDN'е
        Ответить
        • хватит уже
          постить всякую
          хуйню
          в столбик
          Ответить
        • Завтра Вася Пупкин сделает эти указатели указателями на 'SUPER_MEGASTRUCT', а по всему коду будут по-прежнему разбросаны 'sizeof(MEGASTRUCT)'. Будет запущен грандиозный проект по "переходу на новый тип данных", в рамках которого толпа Кумар Пателов займется глобальным выискиванием в коде упоминаний 'MEGASTRUCT' и заменой их на 'SUPER_MEGASTRUCT', по пути лихорадочно соображая, где надо заменять, а где не надо... Сказка!

          Еще раз: код должен быть настолько типонезависм, насколько это возможно. Имена типов используются только в декларациях, ибо именно для этого имена типов и предназначены. Использование имен типов вне деклараций - запрещается (за исключением узкого набора ситуаций, когда этого действительно не избежать). Вышеприведённое соврешенно неоправданое использование 'sizeof(тип)' - пример из аналов говнокодирования.

          А MSDN... Ты хочешь сказать, что в MSDN полно говнокода? Кто бы мог подумать...
          Ответить
        • Мощный аргумент. Ты вызываешь сайзоф, и не знаешь на чем. А вдруг там вообще не переменная, а имя функции?
          Ответить
    • Пиздец, крестопроблемы.
      А в Аде просто есть метод Adjust у класса Controlled, он заменяет и конструктор копирования, и оператор присвоения, и никакой такой еботни "наследуется/не наследуется" думать не надо.
      Ответить
      • >думать не надо.
        первый шаг к деградации :)
        Ответить
        • Ага, настоящие, не деградировавшие, мужчины, пишут только на Си, потому что они не боятся опасностей и не боятся ходить по лезвию бритвы.
          Ответить
          • Не многовато ли запятых?
            Ответить
            • Что-то я запятнулся, да. Блин, неудобная система запятых в русъязе, деление на смысловые части получается неправильное.
              Ответить
              • лол, тебе уже и рус яз не нравится. только дельфи, тарасег, нравится?
                Ответить
              • просто свои мысли нужно делить на предложения. запитые для более связанных по смыслу элементов служат
                Ответить
              • > неудобная система запятых в русъязе

                (What the world needs (I think) is not (a Lisp (with fewer parentheses)) but (an English a Russian (with more.)))
                Ответить
            • потому, что
              Ответить
              • показать все, что скрытопотому, чмо
                Ответить
              • В русском языке пишется как ", потому что", так и "потому, что" в зависимости от смыслового нюанса, который хотел передать автор. Я бы сказал, что в данном случае уместнее именно ", потому что"
                Ответить
      • .
        Ответить
      • > А в Аде

        Какая в жопу Ада? Ты в прошлом веке живешь?
        Ответить
        • 80е года запомнятся нам как время перехода с хороших языков Вирта на говноси
          Ответить
          • Почему Си — говно?
            Ответить
            • потому что войдзвездочки и утечки
              Ответить
              • > войдзвездочки

                А они где-то необходимы? Это ж вроде для того, чтобы кусок памяти воспринимать как хочешь, например как число и строку одновременно. Грязный низкоуровневый трюк, который в соответствующих ситуациях и используется.

                В паскале делать такое же ещё уёбищнее, там придётся заранее знать все варианты, делать определение типа с case с дурацким синтаксисом, и размер типа будет такой, какой у самого большого из case.

                > утечки

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

              Но уже лет 20 как понятно кто победил, так что кроме ностальгии других применений у паскаля, ады и оберона нет
              Ответить
              • > нет арифметики указателей

                Как же? Разве что не используется как приём, потому что Вирт там концептуально на каждом шагу написал: the cake is lie это грязный хак. А так-то кто тебе мешает.

                > структуры данных более логичны

                Вот этого не понимаю. Что ты имеешь ввиду.

                Вирт, насколько я понимаю, делал языки такими, чтобы для них было просто написать компилятор. Создатель языка как бы выбирает одно из двух зол — сложную реализацию языка, либо избыточный или сложный синтаксис.

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

                Умиляет только, что Денису Ритчи удалось создать язык со сложным синтаксисом и очень сложной реализацией.
                Ответить
                • >>Как же?
                  Ну, в BP не было:) Там был Inc(), а на произвольное число было не подвинуться.

                  >>Что ты имеешь ввиду.
                  Subranges были например(sun..sat) и enumы были не обертками вокруг инта, можно было (емнип)возвращать массивы и строки итд.

                  Вообще сам синтаксис определения типабыл более стройный:ты определял тип с помощью ключ слова type, да и запись var:type лучше чем "type var" это уже все поняли.

                  А еще оператор присваивания не возвращал значения, и это не позволяло писать кулхацкерскеий код, зато код был чище)

                  В целом паскаль более академичный язык, не зря он был лучшим ЯПом для обучения

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

                  ну при этом синтаксис паскаля намного проще синтаксиса сей)
                  Ответить
              • >меньше ключевых слов
                Разве?

                В любом случае в си ключевые слова и значки короче.
                Ответить
                • меньше, если конечно не считать операторы
                  Ответить
                  • В сишке меньше. Даже если из паскаля убрать and,or,xor,shl,shr,begin,end
                    http://wiki.freepascal.org/Reserved_words

                    http://tigcc.ticalc.org/doc/keywords.html


                    Standard ANSI C recognizes the following keywords:
                    
                    auto
                    break
                    case
                    char
                    const
                    continue
                    default
                    do
                    double
                    else
                    enum
                    extern
                    float
                    for
                    goto
                    if
                    int
                    long
                    register
                    return
                    short
                    signed
                    sizeof
                    static
                    struct
                    switch
                    typedef
                    union
                    unsigned
                    void
                    volatile
                    while
                    Ответить
                    • Если ты уберешь операторы (типа and) и конструкции языка (типа then) и всякий ООП мусор типа destructor (которого не было в классическом паскале) то получится меньше
                      Ответить
                      • Даже обычный паскаль громозкий по кейвордам, за что мне никогда не нравился.

                        Там for крайне уёбищный: downto/to. Ну вот не могли нормальный произвольный инкремент запилить?

                        >и конструкции языка (типа then)
                        Тогда сравнение некорректное получится. then — вполне ключевое слово. В сишке в список даже типы включены.

                        Еще label не имеет аналогов. С какой целью заёбывать программиста объявлять метки?
                        Ответить
                        • @Там for крайне уёбищный: downto/to. Ну вот не могли нормальный произвольный инкремент запилить?

                          Если ты про обращение к счётчику, то всё с этим норм.
                          Всё дело в том, как работает цикл. For..Do считает границы 1 раз, while..do столько раз, сколько выполнится цикл.
                          Ответить
              • >меньше ключевых слов
                на циклы repeat/until/for/do/while; у си for и do while
                на методы: function/procedure; у си void
                лишний then, итд
                Ответить
        • Какой забавный.
          Решил пооткапывать все треды и пообщаться с Тарасом.
          Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить

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