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

    +15

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    struct Point3D {
      float x,y,z;
    
      float& operator [] (int i) {
        switch (i) {
        case 0: return x;
        case 1: return y;
        case 2: return z;
        default: assert(false);
        }
      }
    };

    Писал Жабапоглащенный.

    Запостил: LispGovno, 08 Января 2014

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

    • Плюсик. Бесят знаковые индексы. BTW, не думаю, что моё return *(&x + i); чем-то лучше приведенного.
      Ответить
      • > Бесят знаковые индексы
        А что ты с Жабапоглощенного хотел?
        я за .x();, .y(); ... и [].
        Ответить
        • >> А что ты с Жабапоглощенного хотел?
          http://habrahabr.ru/post/121799/
          Ответить
          • Начало типичной крестостатьи на хабре:

            Наверное, все любители языка C++, которые использовали другие языки, такие как C#, удивляются: почему же в плюсах нет {{feature.name}}? Ведь это действительно удобное средство, позволяющее {{feature.description}}. Недавно и я заинтересовался данным вопросом. Подумав, полистав Страуструпа и наконец, погуглив, я пришёл к выводу, что {{feature.name}} можно реализовать средствами языка...
            Ответить
            • http://habrahabr.ru/post/202754/#comment_7003730
              Ответить
            • Синдром Блаба.
              Ответить
              • Синдром Блабла.
                Синдром Бабла.
                Ответить
              • Почему?
                Ответить
                • Я задал этот вопрос так как:
                  Синдром блаблабла - это когда питушок не признает фичи языка из другого языка. Тут чувак имеет фичу (то есть находиться как бы в языке более высокого уровня по наличию фичи) и пытается сэмулировать в крестах. Он не говорит, что фича не нужна. Он говорит что её можно использовать, а это уже не является синдромом блаба. Синдром блаба - семантическая слепота.
                  Ответить
                  • Кстати я уже начинаю жалеть, что в крестах нету свойств ну или хотя бы раздельных прав на чтение поля и запись поля.
                    Задрал этот ёбаный понос m_size, size(), m_length, length(), это уёбищное () везде писать.
                    Ответить
                    • > это уёбищное () везде писать.
                      Тебя проклял кто-то
                      Страуструп
                      Ответить
          • Да ты же упоротый. На гейдеве подрались из-за:

            float &x, &y, &z;
            float a[3];

            Из-за очень возможного 100% оверхеда по памяти, а ты предлагаешь:
            class Property ...
            {
                typedef Type (Owner::*getter)();
                typedef void (Owner::*setter)(Type);
                Owner * m_owner;
                getter m_getter;
                setter m_setter;
            на каждый член
            Ответить
            • Теоретически комплятор может соптимизировать всё это, как будто этого Property и не было.
              Ответить
            • Интересно, вынести геттер с сеттером в параметры шаблона не судьба была?
              Ответить
              • Это же шаблон пилить ;)
                Ответить
                • Там уже шаблон с 3-мя параметрами. В теории и режимы доступа можно легко выводить из того, какая комбинация геттеров/сеттеров на входе.
                  Ответить
                  • Я статью не читал, но осуждаю ее.

                    Шарповые свойства это же всего лишь синтаксический сахар, не более того.

                    От них профит только в том, что кода меньше писать, чем врукопашную делать геттер и сеттер. Ну и вызов на две скобки короче.

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

                    P.S. Да, у меня синдром Блаба, и я не признаю удобство свойств.
                    Ответить
                    • Ну и в любой крестовой реализации свойств неизбежен оверхед - ссылка на родительский объект.

                      Так что, имхо, не нужны они в крестах.

                      === BEGIN HOLY WAR ===
                      Ответить
                      • А container_of, как в Linux (я имею в виду ядро), не получится запилить?
                        Ответить
                        • Ну вот во-первых меня смущает фраза в мане от offsetof, что "type shall be a POD class (including unions). " (c++98) и "type shall be a standard-layout class (including unions)." (c++11).

                          Во-вторых мы теряем полиморфизм (хотя мы его уже потеряли из-за требования на standard-layout или POD). Свойство не сможет понять, встроено оно в класс A, или в его потомка - класс B.

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

                          P.S. Или я туплю?
                          Ответить
                          • что значит шэлл би? может маст би? а то как то странно требование звучит, типа можно, но не обязательно
                            Ответить
                            • Не обязательно, но никто не гарантирует, что не порвет сраку при работе.
                              Ответить
                        • че за контэне_оф?
                          Ответить
                          • #define container_of(ptr, type, member) ({ \
                                            const typeof( ((type *)0)->member ) *__mptr = (ptr); 
                                            (type *)( (char *)__mptr - offsetof(type,member) );})
                            Ответить
                      • >> неизбежен оверхед - ссылка на родительский объект
                        Еще как избежен!
                        1. можно инкапсулировать данные в самом свойстве, а не в родителе. Родителя, соответственно, зафрендить.
                        2. указатель на родительский объект получается в вычитанием из this объекта свойства некоторой константы.
                        Ответить
                        • > 1. можно инкапсулировать данные в самом свойстве, а не в родителе
                          Очень ограниченно. Теряем половину профита от сеттеров. Разве что валидацию и read-only так можно замутить.

                          > 2. указатель на родительский объект получается в вычитанием из this объекта свойства некоторой константы.
                          И полиморфизм смывается в унитаз. Если я не туплю сегодня.
                          Ответить
                          • >> Очень ограниченно.
                            Таки да.
                            Пункт два - я тупанул, пустой класс тоже что-то весит.
                            Ответить
                          • > И полиморфизм смывается в унитаз.
                            Или все-таки не смывается... Жарко дома, башка совсем не варит ;(

                            Пойду попробую реализовать.
                            Ответить
                            • > Пойду попробую реализовать.
                              Фейл. offsetof(my_class, my_prop) нельзя передать как параметр шаблона для типа самого же my_prop. Что в общем-то логично ;(

                              У кого еще есть какие-нибудь предложения, как замутить свойство без хранения в нем ссылки на тот объект, в котором оно лежит?)
                              Ответить
                              • static метод в классе, возвращающий этот самый offsetof. И передать этот static метод как параметр шаблона в проперть. И все это гавно завернуть в define (что бы в глаза не бросалось)
                                Проверено, работает
                                Ответить
                      • А как же сериализация?
                        Ответить
                        • А ее один хуй в крестах не запилишь без геморроя и рукопашного кодинга. Рефлексии же нет.

                          В Qt, в принципе, прикрутили метасистему. Там к свойствам из js можно обращаться, просто дергать их по имени... Но она работает только на QObject'ах, и представляет собой жуткий костыль с генерацией дополнительной сишки.
                          Ответить
                          • Но хотя бы не придётся делать разными читателя и писателя.
                            Ответить
                            • Ну метаинфу для читателя и писателя можно описать и без свойств.
                              Ответить
                              • Да, можно передавать структуры из указателя на геттер и сеттер.
                                Ответить
                                • Там видишь еще что. Может захотеться, чтобы некоторые поля сериализовывались, но доступа извне к ним не было. Иногда через сеттер десериализацию прогнать не получится, т.к. он может проверять согласованность с другим полем, а оно еще не загружено. Некоторые поля нужно рассчитывать заново после десериализации.

                                  Так что так просто не отделаться ;(
                                  Ответить
                    • >> Шарповые свойства это же всего лишь синтаксический сахар, не более того.

                      а вот и нет. теперь этот сахарок в ASP.net стал важен - вьюшка и контролер не могут с полями на автомате работать, только с свойствами.

                      нет, методами можно, но это выливается в анальную боль.
                      Ответить
                      • Причем здесь поля? С полями свойства глупо сравнивать. Это совсем разные сущности.

                        > нет, методами можно
                        Ч.т.д. Сахар. Удобный, не спорю, но сахар.
                        Ответить
                        • ну я может не так высказался. я говорил о том, что уже пошла тенденция завязывать на этот сахар другие структуры. можно и руками, но порой это добавляет дофига кода за пределами класса, что вообще не айс. Хотя по сути сахар. По сути и массивы в с сахар)
                          Ответить
                          • > По сути и массивы в с сахар)
                            Тогда и структуры тоже сахар. Т.к. без этого "сахара" я не смогу описать структуру.
                            Ответить
                            • кстати у структурах
                              интересное и позновательное

                              в дотнете структуры преполагается юзать приимущественно в ансейвед коде, поэтому по умолчанию по порядок следования полей в структуре в памяти определяется юзером. Однако в классах порядок выбирается компилятором. Сменить метод расположения полей можно атрибутом
                              [StructLayout(LayoutKind.xxxx)]
                              Так же можно явно задать положение полей с помощью смещений памяти
                              Ответить
                            • Без массивов то можно обойтись
                              int *a = malloc(size);
                              *(a+n) = something();
                              Ответить
                              • > Без массивов то можно обойтись
                                Тем самым ты обходишься и без структур :)

                                Q.E.D.
                                Ответить
                            • > Т.к. без этого "сахара" я не смогу описать структуру.

                              А со свойствами смог бы, в геттерах-сеттерах считал бы указатель и возвращал ссылку на смещение.
                              Ответить
                    • >>Безнаказанно рефакторить поля на свойства, без перекомпиляции классов, использующих данный, емнип, они в шарпе все равно не позволяют, т.к. поломается интерфейс класса. Но я могу ошибаться. Шарпеи, вы где?

                      правду глаголишь, боярин. Ибо метаданные разные. Свойство - это свойство, а поле - это поле. Свойство даже автоматеческое, всегда прячет за собой поле, пусть и неявно
                      Ответить
                      • > Свойство даже автоматеческое, всегда прячет за собой поле, пусть и неявно
                        Ну скажем так, не всегда. Например если я делаю прямоугольник, и хочу сделать ему свойства left, right, width,то одно из них останется без переменной.
                        Ответить
                        • ну так все равно какие то переменные с ним связаны. Я про то говорил. что если написать автосвойство
                          int x{get; set;}
                          то все равно создается поле, правда явно оно не доступно.
                          Ответить
                          • > ну так все равно какие то переменные с ним связаны
                            Ну ок, я читаю значение свойства temperature с термометра, подключенного по 1-wire. Где оно хранится? )
                            Ответить
                            • Борманд, ты зануда

                              В окружающей среде, естественно


                              А нахрена ему свойство? Мы будет градуснику по 1-wire температуру задавать?)
                              Ответить
                              • > Мы будет градуснику по 1-wire температуру задавать?)
                                Почему нет? Вдруг это какой-то управляемый термостат. Читаешь из свойства текущую температуру, записываешь желаемую ;)
                                Ответить
                                • ) Программирование для шаманов. Приближение лета с помощью термостата
                                  Ответить
                    • >>Шарпеи, вы где?

                      Да уж персонально меня зови, один я у вас такой.)

                      Задавая умные вопросы, товарищ Борманд, вы таки заставляете меня луркать (так как я не могу ответить такому человеку как вы^_^) и тем самым заставляете меня учиться
                      Ответить
                    • > Шарповые свойства это же всего лишь синтаксический сахар, не более того.
                      Кажется я был не прав. Конечно же свойства, геттеры\сеттеры и поля отличаются на уровне метаданных и видны через рефлексию именно как свойства.

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

                      ps: вопрошатель уже все понял
                      Ответить
            • union?
              Ответить
              • Только апельсинковых mad skills нам тут не хватало, давайте без трюкачества с типами.
                Ответить
      • > моё return *(&x + i);
        не только твоё
        оно всё-таки пооптимальнее
        Ответить
        • Угу, а откуда такая уверенность что адреса координат идут строго в очереди (и на любой платформе?), а если создано в куче и число i вне 0...2, читаем значение с адреса вне динамической памяти и кобздец котенку.
          Ответить
          • кресты не переставляют поля
            Ответить
            • Не забывай добавлять "... в POD'ах (с++98) или standard-layout классах (c++0x)".
              Ответить
              • так вообще не переставляет. он может вставлять всякие втбл или указатель на виртуальный предок в виртуальном наследовании (обычно в начало класса), а ток нормально все будет. гарантия что не переставит
                Ответить
                • Там написано что имплементешнидефайнд для не подов.
                  Ответить
          • я вот только подумал что может быть литл индиан машина или биг. тогда придется вычитать i, ну или прибавлять к &z
            Ответить
            • Да каомпилятор не дурень - с адресной арифметикой целевой платформы управится как надо.
              Ответить
            • > литл индиан машина
              Индейцы вроде не помешают. Они же влияют только на порядок байт в том же флоате. Но никак не на порядок флоатов между собой.
              Ответить
          • Ну для POD'ов вроде как стандартом гарантируется порядок. А этот Point3D всяко POD.

            Ну и Тарас же не говорит, что эта реализация безопасна. Он только сказал, что она оптимальней.

            > число i вне 0...2
            Ну а что поделать? Либо проверка и теряем производительность зазря, либо нет проверки, но есть небольшой, но риск.

            Можно конечно что-то типа такого запилить: p.get<0>(), но оно неюзабельно в циклах. А раз неюзабельно в циклах - вместо него можно юзать банальное p.x ;)
            Ответить
            • Насчет проверок:

              Одно дело, когда этот индекс взят из внешних данных. Тогда проверка нужна.

              И совсем другое дело, если этот индекс юзают только в десятке функций, оперерирующих над матрицами и векторами, и больше никто к ним никогда не полезет.

              Я все-таки за то, чтобы выпилить этот оператор [] нахер, а в коде всяких умножений матриц юзать .x, .y, .z, анролльнув его вручную или простеньким скриптом на питоне. Зачем этот оператор нужен то, кроме лени автора либы и ее читабельности (на которую нам немного насрать, т.к. либа явно точится под производительность)?
              Ответить
              • И вместо полей, наверное, все-таки стоит запилить акцессоры. Тогда можно будет безболезненно переделывать векторы и матрицы под ссе и все что душе угодно ;)

                Координаты векторов и ячейки матриц, имхо, мало кому нужны кроме самой либы. А сама либа во френдзоне и работает с полями напрямую, поэтому скобочки мешать не будут.
                Ответить
    • Да там весь тред жиром истекает, дайте уже сразу всю ссылку: http://www.gamedev.ru/flame/forum/?id=184630
      Ответить
      • А зачем вообще в геймдеве динамический доступ к полям вектора? :) В математических операциях скорость же важна, только рукопашный анролл, только хардкор. А при копировании все равно копируется целиком вся структура, глупо копировать ее по полям.
        Ответить
        • > зачем вообще в геймдеве динамический доступ к полям вектора
          Матрицы любят циклами на вектора перемножать
          Ответить
          • Ну это от силы десяток функций. Можно и анролльнуть руками или скрипт написать.
            Ответить
            • через шаблоны
              нафига руками
              Ответить
              • Циклы на мпл что ли? Да ну их нахуй. Рукопашный анролл и то лучше читаться будет.

                r.x = m[0]*a.x + m[1]*a.y + m[2]*a.z
                Вот на тачскрине даж набрал. Хули тут писать то.
                Ответить
                • нах мпл. просто рекурсия шаблонных функций по шаблону
                  Ответить
                  • Кстати, а зачем каждый гейдевовец пишет свои точки, матрицы и кватернионы? Неужели нет годной опенсурсной либы с ними, которая умела бы симд для тех архитектур, где он есть?
                    Ответить
                    • есть, но геймжевовцы не умеют не пользоваться велосипедами
                      Ответить
                • > Хули тут писать то.
                  Бывают и побольше вектора, а развернуть охота
                  Ответить
                  • > Бывают и побольше вектора, а развернуть охота
                    Ну вот там уже можно и развернуться :) Но там уже и проблем с .x, .y, .z не будет. Там уже будет простая и тупая индексация.
                    Ответить

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