Няшная / Говнокод #3599 Ссылка на оригинал

0

  1. 1
enum {size = 10, timeout = 50};

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

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

    • Вероятно, это просто такой "способ" объявлять константы 🙂

      В том смысле, что похоже, что timeout - это кол-во секунд соотвествующие timout-у в какой-то операции, а size - это размер какого-нибудь буфера.
      Ответить
      • встретился такой способ для объявления констант. лично по мне - такой способ похож на сравнивание полкило яблок и трех лампочек.
        Ответить
        • константы как константы, отличаются от привычных тем, что у них нельзя взять адрес.
          Ответить
        • Я охреневаю, anonymous enum уже считается говнокодом...
          Ответить
          • рейтинг этого кода показывает что говнокодеров на сайте больше чем программистов... готов оформить платную подписку чтоб видеть тех кто плюсует и минусует...
            Ответить
            • страйкер задумайся... готов платить $10 в год за такую возможность...
              Ответить
            • Я против платной подписки, но знать поименно говнокодеров давно хочу:)
              Ответить
  • не говнокод 100%. у нас в кодгайдлайне такой метод рекомендован...
    эти константы 100% компайл тайм...
    к стати они допускают компайл тайм вычисления (если это возможно), допустим так
    enum
    {
      kSize = sizeof(Some),
      kAlignedSize = (kSize + 15) & (~0xF),
      kUnaligned = (kSize != kAlignedSize) ? 1 : 0;
    };

    ну и те кто поопытней, знают что такой код:
    // .h file
    
    class Some
    {
      static const int MaxbufSize = 16;
    
      
    }
    
    // .cpp file
    
    Some::SomeMethod()
    {
      char buf[MaxbufSize]; <== это компилится не везде...
    }
    Ответить
    • Коль это вписано в раздел "Си", стало быть это си, а в си принято юзать дефайны, которые -- не поверишь -- константы 100% компайл тайм. Говно 100%.

      > не говнокод 100%. у нас в кодгайдлайне такой метод рекомендован...

      Говногайдлайны уж постить нельзя?
      Ответить
      • define не 100% компайл тайм...
        оптимизация такого дефайна
        #define kAlignedSize(kSize) (kSize + 15) & (~0xF)
        ляжет на плечи компилятора, и если оптимизации отключены или компилятор не понял идей аффтара, то вычисление переедет в рантайм...
        в енаме компилятор гарантирует компайл тайм иначе будет ошибка...
        Ответить
        • Во всех нормальных компиляторах если kSize - константа, то результат высчитывается в компайлтайме. И зачем отключать оптимизации? Для дебуга особо рантаймный оверхед не критичен. Да и оверхедом это сложновато назвать.

          В любом случае, это что касается "составных" дефайнов. В приведённом же примере имеем тупо числа, они 100% в любом самом засраном компиляторе будут компайл-тайм, т.е. конкретно приведённый пример есть говнокод, за остальное я не говорю.
          Ответить
          • я тебе еще раз говорю, енам гарантирует компайл тайм, дефайн просто подменяется выражением, без каких либо гарантий и с надеждой, что компилятор поймет что ты хотел ему сказать... поведение в дебаге и релизе будет совсем разным...
            Ответить
            • #define ZHOPA (CONST1 + CONST1)
              s = ZHOPA;

              после работы препроцессора выглядеть в коде будет так (если CONST1 == 1):

              s = (1 + 1);

              Теоретически гарантий может и нету, но практически они есть в любом адекватном компиляторе. Или ты считаешь, что компилятор будет тупо делать push 1; push 1; add?!

              > поведение в дебаге и релизе будет совсем разным...

              С чего бы? Объект константен вне зависимости от того, инициализируется он в рантайме или в компайлтайме. Ты не тяни сюда свой с++, мы не может сделать константный объект, который бы в своём конструкторе мог делать сайд-эффект на окружение. Да и в сиплюсе юзание сайд-эффектов при конструкции константного объекта было бы говнокодом. Поведение будет одно и то же. Или ты путаешь поведение с реализацией поведения?
              Ответить
              • > Или ты считаешь, что компилятор будет тупо делать push 1; push 1; add?!

                Ага, call add. Сложение путём вызова подпрограммы.
                Ответить
              • я слово гарантирует даже жирным выделил, что означает что если выражение не может быть посчитано то будет ошибка, причем в месте расчета а не в куче мест использования... не надо съезжать на С++, это все можно в С...
                если не понимаешь профита от компайл тайм вычислений так и скажи, не надо пытаться убеждать окружающих, что кактус вкусный и в сыром виде...
                Ответить
                • Кактус нужно просто уметь готовить... И да. В пустыни выпьешь, что угодно, если не ядовито.

                  А по делу:
                  Компилитайм вычисления редко нужны. А там где нужны - экономия на спичках. И вообще, всё что можно посчитать во время компилитайма - можно посчитать и в другое время один раз. Например при старте приложения или в момент ипользования(линивые вычисления).
                  Ответить
                  • если хотел написать по делу, то напиши что удобнее
                    enum
                    const int
                    define
                    Ответить
                    • Для каждой задачи своё. Однозначного ответа нет, иначе бы не плодили так много методов, а давно удалили бы всё говно за ненадобностью.
                      Ответить
                      • для констант, я описал порядок в котором надо выбирать правильный ответ... define лучше оставить для подстановок, а не для констант... для инт констант enum единственно верный православный и правильный со всех сторон вариант... для float enum не подходит, хотя я видел реализацию правда с кодогенерацией, ну и fixed_point никто не отменял (к стати неплохой вариант для работы с флоатом в шаблонах)...

                        P.S. я против удаления define из С++, так как есть места где без него плохо, допустим в ASSERT...
                        Ответить
                  • > Кактус нужно просто уметь готовить...

                    Не надо меня готовить! Есть растения, более лёгкие в приготовлении.
                    Ответить
                • Т.е. предлагаешь юзать энум, чтобы стопнуть компиляцию, если случайно где-то в аргументах затесается неконстантное значение?

                  Мне таких хаков задаром не надо... Внимательней будь и всё.
                  Один хуй после стряпания кода будешь юзать профайлер (или вы в вашей говноконторе их не юзаете?) и найти такое проблемное место будет довольно несложно (если оно действительно проблемное, а не тупое "premature optimization" в ущерб чистоте кода).
                  Ответить
                  • твои размышления тянут максимум на год-полтора опыта... человек не может быть всегда внимательным... человек даже теоретически не может все 7 раз проверить и быть уверенным что так оно и будет...
                    код должен говорить программисту о его ошибках!
                    Ответить
                    • > код должен говорить программисту о его ошибках!

                      Не тот язык выбрал, значит. Си именно что славится своей нестрогостью. И попытки сделать его строгим всегда останутся хитровыебанными хаками.
                      Ответить
                    • Алсо, это вовсе не ошибка, а вариант реализации
                      И-таки почитай про premature optimizations, опытный ты наш.
                      Ответить
                      • свертывание констант в компайл тайме это не оптимизация... я знаю эту цитату, и в данном случае она неприменима...
                        и она неприменима в 90% случаев в которой ее пытаются применить, так как эту цитату чаще применяют как отмазку своей неопытности, как в примере с тобой...
                        Ответить
                        • +1, реально заебали с этой цитатой, просто заебали. Пошли они нахуй.
                          Ответить
                          • +1, так заебали
                            "преждевременная оптимизация - залог здорового говнокода"
                            =)
                            Ответить
                            • оптимизация никак не связана с говнокодом...
                              неоптимизированный код тоже может быть говнокодом...
                              Ответить
                        • А если вдруг захочется подставить неконстантное значение (изменилась логика, дебуг и т. д.) - придётся переписывать из энума обратно в дифайн.

                          > свертывание констант в компайл тайме это не оптимизация

                          Да в полне оптимизация.
                          Логически (если рассматривать как blackbox) программа будет получать одно и то же значение - по этому верно будет сказать, что значение - константно.
                          А вот как это значение в ассемблере реализуется - это уже детали реализации. То что ты предлагаешь - это хитровыебанные хаки, чтобы заставить компилятор генерировать нужный тебе ассемблер-код. Это, конечно, полезная идея, однако 99% кода особо остро не нуждается в компайл-тайм свёртке и в 99% случаев (исхожу из практики) комплиятор уже всё сам сворачивает в компайл-тайме. Исходя из этого можно сказать, что сий хак не стоит выеденного яйца (по крайней мере, чтобы пихать его всюду).
                          Ответить
                          • я потом посмотрю как ты будешь это дебажить... только не надо намекать на то что ты настолько крут что твои программы всегда правильные...
                            Ответить
                            • Ну я не знаю, каким с++ником нужно быть, чтобы в макро-константу подставить неконстантное значение. У меня по проектам практически нет глобальных переменных, вероятность случайно подставить неконстантное значение в макро-константу стремится к нулю. Сий хак - паранойя, не более. Больше вероятности вообще всё написать не так (и тут никак не обезопасишь код от самого себя).
                              Ответить
                                • Есть вероятность вместо 2+2 написать "format c:". Какой синтаксическое средство Си мы можем использовать?
                                  Ответить
                            • А что дебажить? Есть юнит-тесты, профилирование, можно глянуть в геренируемый асм-код, если что...

                              С юнит-тестами и валгриндами, я знаю, что мои программы правильные. Не всё же дебажить с помощью printf'ов...
                              Ответить
                              • очень хотелось бы узнать что тебе ответит толпа наших китайских и вьетнамских тестеров на такое заявление...
                                Ответить
                                • Откройте для себя юнит-тесты, и надобность в тестерах по большому счёту отпадёт.
                                  Ответить
              • #define DOUBLE_ZHOPA(ZHOPA) ((ZHOPA)+(ZHOPA))

                int i = 0;
                int zhopa = DOUBLE_ZHOPA(i++);

                дефайны - в жопу!
                Ответить
                • Не в тему. Речь о макросах-"константах", а не макросах-"функциях". Макрос-"константа" не может принимать содержать переменные.
                  Ответить
                    • Да, юнит-тестами. Кнопочку нажал - и всё само проверилось. Офигенно, да?
                      Ответить
                        • Ха-ха. Твой "грамотный" код - это уродливые и малополезные хаки.
                          Ответить
                          • очень хорошо что у тебя есть свое мнение, но то что ты считаешь его единственно верным очень плохо...
                            Ответить
                        • >грамотный код

                          literate programming?
                          что-то я не видел, чтоб его крестофилы использовали
                          Ответить
                          • не, я немного не про то...
                            я про то, если есть возможность написать код который не будет доставлять в будущем, то лучше это сделать...
                            define практически всегда невыдерживает рефакторинга, об ограничениях const я написал. я понимаю что это все в С++, но никто не мешает использовать это в С...
                            Ответить
            • GCC O1:

              #define kAlignedSize(kSize) (kSize + 15) & (~0xF)
              
              void f(void)
              {
                  int i = kAlignedSize(21);
                  printf("%d\n", i);
              }


              asm:
              pushl	%ebp
              	movl	%esp, %ebp
              	subl	$24, %esp
              	movl	$32, -4(%ebp)
              	movl	-4(%ebp), %eax
              	movl	%eax, 4(%esp)
              	movl	$LC0, (%esp)
              	call	_printf
              	leave
              	ret


              Gcc o3:

              pushl	%ebp
              	movl	$32, %eax
              	movl	%esp, %ebp
              	subl	$8, %esp
              	movl	%eax, 4(%esp)
              	movl	$LC0, (%esp)
              	call	_printf
              	leave
              	ret


              Уже сразу херачит 32... То же самое, если подставить, допустим, sizeof(int) - сразу оперирует с числом 16.
              Ответить
      • Принято, да, увы и ах.
        Но енумы все-таки лучше, они типизированы, разные вкусные штучки на уровне компилирования, например, если в свиче не все значения.
        И их видно в дебугере!

        Сделали б еще определение количества элементов, цены б ему не было, а то извращаться приходится.
        Ответить
        • Энумы круты, да. Только как это относится к обсуждаемому говнокоду? В нём явно энумы не нужны: 1) между timeout и size нет ничего общего 2) константы - тупо числа, можно обойтись дефайном.
          Ответить
          • Это комментарий на то, что в C принято юзать дефайны. Прошу прощения, наболело, у нас в проекте чуть больше 9000 дефайнов на чиселки, из них не меньше 90 процентов ДОЛЖНЫ быть енумами.
            Ответить
            • да, дефайны надо делать енумами, если это, к примеру, коды ошибок.
              но в таком случае - никогда.
              ну и уж тем более нельзя загонять под один енум.
              Ответить
              • это интовые константы, они должны быть енумами! дефайн для констант это один из паттернов говнокода...
                Ответить
                    • Да, но использование энума вместо дифайна - это (говно?)гайдлайн с++, ибо в Си прекрасно обходятся дифайнами.
                      Ответить
                • Глупо и необоснованно. Дефайн - это нормально для одной константы (не групп).
                  Иногда const int удобнее, не спорю.
                  Енум - легкое извращение.
                  А упор был на то, что в один енум запхнуть - это просто идиотизм.
                  Проще тогда вообще все константы модуля в один енум закинуть.
                  Ответить
                  • дефайн это нормально для подстановок, для этого он и был создан... для констант есть enum и const.
                    Ответить
                    • почему бы не воспринять константное значение, как быструю подстановку?

                      Идея-то в чем? изменить одно значение по необходимости в одном месте с минимальным усилием.

                      К тому же, если уж так смотреть на удобство дальнейшего использования, то дефайн позволяет потом сделать что-то вроде
                      #define timeout (getTimeout())
                      Ответить
                      • к сожалению, программист должен понимать что он делает...
                        если ему нужна константа он создает константу, если ему нужна подстановка он использует дефайн...
                        к счастью, этот сайт всегда рад тем кто не понимает этого простого правила...
                        Ответить
                        • >к сожалению, программист должен понимать что он делает...
                          Почему к сожалению? О_о
                          Ответить
                          • потому, что большинство коментов в этой теме говорят об обратном...
                            большая часть темы, это:
                            - компилятор сделает все за меня
                            - зачем напрягать свой моск
                            - я уверен в том что этот говнокод рабочий
                            - ...
                            - premature optimisation
                            И при этом эти люди считают себя довольно крутыми программистами...
                            Ответить
                          • обрати внимание на коменты тех кого заминусовали (кроме тролей конечно), в их коментах есть истина...
                            Ответить
                        • Если смотреть с этой стороны, то использование енумов - тоже неверно, так как они созданы для перечисляемых типов.
                          Ответить
    • [quote]
      ? 1 : 0;
      [/quote]

      Смотрите, смотрите, Пушков бульшитит!
      Ответить
      • pushkoff, вам нужно больше тренировать компилитайм вычисления. Пока кактус получается невкусный.
        Ответить
        • результат сравнения имеет тип bool, тернарный оператор для енамов считается в компайл тайме, если все его аргументы - константа... единственная проблема в том куске кода это ;...
          Ответить
          • Ответ совершенно в тему...

            >результат сравнения имеет тип bool, тернарный оператор для енамов считается в компайл тайме, если все его аргументы - константа...

            Капитан Очевидность?

            >единственная проблема в том куске кода это ;...

            сам кусок кода 😀
            Ответить
            • извини, я не привожу bool к инту неявно, и насколько я помню под GCC это warning, а я фанат чистой компиляции...
              Ответить
                • по моему, в стандарте не сказано о том что true это 1... поэтому я привел явно...
                  Ответить
                    • Может быть чтобы в какие-нибудь битовые поля впихнуть?
                      Ответить
                      • Название говорит о том, что она скорее bool, чем бит.
                        Ответить
                        • Иногда и bool как бит. За примером далеко ходить не надо. std::vector<bool>.
                          Ответить
                    • это же интовая константа... она должна быть вполне определенным интом... а вдруг я ее потом в умножении использую...
                      Ответить
                          • Ну, умножение на 1 особо смысла не имеет. Хотя это лучше, чем деление на 0 🙂
                            Для явного преобразования я вижу такие применения:
                            (актуально в Си, где еще не добавили bool)
                            for( int i=0; i<width; ++i )
                            {
                               char state = onoff[i] ? 0 : 1; 
                               mask|= state << i;
                            }


                            onoff - массив типа, ведущего себя как bool ( т.е. 0 - ложь, всё остальное - истина )
                            mask - по сути битовая маска, которую потом в явном виде скармливаешь какой-нибудь многоканальной железке ввода/вывода.

                            Или например так:

                            char* names[] = { "off", "on" };
                            int index =  func() ? 1 : 0; // func() возвращает что-то интерпретируемое как bool
                            printf( "%s", names[index] );


                            P.S. А вот в С++ bool'ы по стандарту преобразуются в 0/1, и такие пляски уже ни к чему.
                            4.7.4 If the source type is bool, the value false is converted to zero and the value true is converted to one.
                            Ответить
    • Проблема не в использовании енума, а в том, что две несопоставимые константы - в одном енуме.
      И я не говорю, что такой код неправилен в плане того, что создает какие-то ошибки. Он неправилен со стилистической точки зрения. Если уж надо использовать перечисление - то прямая дорога к двум различным енумам с одним определением.
      код на самом деле выглядит еще немного ужасней, примерно так:
      enum {PREFIX_size = 10, PREFIX_timeout = 50};

      Что кагбе намекает на то, что PREFIX_SIZE - он той же единицы измерения, что и PREFIX_TIMEOUT.
      Ответить
      • далеко не факт что они не сопоставимые, из контекста этого не видно
        основные претензии говнокодеров в том, что это енум, а не дефайн
        Ответить
        • >основные претензии говнокодеров в том, что это енум, а не дефайн
          Нет. Я тоже считаю, что нужно разносить логически не связанные константы по разным энумам.

          Или ты меня считаешь не говнокодером? Обижаешь... Я настоящий говнокодер и иду по непревзойдённому говнокодному пути.
          Ответить
        • >далеко не факт что они не сопоставимые, из контекста этого не видно
          timeout - промежуток времени, часами мерить надо
          size - размер, в килограммах/байтах/сантиметрах и т.д.
          по названию по-моему, явно видно.
          Ответить
          • рассуждаем о сферических конях в вакууме

            вот пример на C
            enum {
            size = 10,
            timeout = 20
            };
            char buf[size];
            ...
            read_data_with_timeout(&buf, size, timeout);

            константы логически связаны
            Ответить
            • Вообще enum - это по идее "перечисления" (весна-осень-зима-лето, январ-февраль-март-апрель), и дело тут не в логической связанности. Использование его для других целей -- хаки и говно по большому счёту. В том числе и в этом примере.

              Вот это я ещё понимаю:
              #define SIZE 10
              #define TIMEOUT 20
              
              enum
              {
                 CLOSE_ON_EXIT = 4 /* .. */,
                 DELETE_ON_EXIT =  8 /* .. */
              };
              
              read_data(&buf, SIZE, TIMEOUT, CLOSE_ON_EXIT | DELETE_ON_EXIT);
              Ответить
              • и при этом ты следишь за всеми файлами в проекте, не дай бог где-нибудь случайно появится еще один SIZE, не связанный с этим SIZE?

                У дефайна нет scope, да и вообще это препроцессор и к языку никак не относится
                Ответить
                • > У дефайна нет scope

                  А он, scope, зачем-то нужен?

                  > да и вообще это препроцессор и к языку никак не относится

                  Welcome to C.

                  > и при этом ты следишь за всеми файлами в проекте, не дай бог где-нибудь случайно появится еще один SIZE, не связанный с этим SIZE?

                  Это я для примера так написал. Сам-то я использую систему префиксов:

                  1) два символа, идентифицирующие проект
                  2) имя логического неймспейса
                  3) непосредственно значение

                  Напр.: CF_BUFFER_DEFSIZE

                  Легко, просто, вкусно.
                  Ответить
                • > и при этом ты следишь за всеми файлами в проекте, не дай бог где-нибудь случайно появится еще один SIZE, не связанный с этим SIZE?

                  Во-первых лично у меня имена так систематизированы, что пересечение крайне маловероятно. Во-вторых даже если будет пересечение, то компилятор ругнётся о переобъявлении.
                  Ответить
              • А вот у меня душа не лежит к логическим операциям над енумами.
                Это как январь|февраль, НЕХ какая-то.
                Но, может, это образование сказывается, кольца там, поля всякие. Воротит от непонятных, левых операций:)
                Поэтому у меня все битовые флаги — это не енумы.
                Но, наверное, это тараканы, никакой почвы под лапами не имеющие.
                Ответить
                • Хм, ну разные ситуации бывают. Если речь о флагах к какой-нибудь функции, то лично я не вижу почти ничего плохого в использовании enum. Всё-таки когда define-ов становится слишком много, лично меня это начинает раздражать 🙂
                  Ответить
            • "логически связаны" - это не "сопоставимы".
              размер и таймаут - это величины разного порядка, а следовательно, в одном енуме они выглядят говёно.
              Ответить
  • Кто назвал это говнокодом, тот сам говнокодер.
    Вполне нормальный код.
    Ответить
  • Есть подозрение, что это плюсовик портировал (или писал) код на Си. Ну либо код вообще плюсовый и товарищ ошибся разделом.
    Ответить
    • есть подозрение что товарищ считает говнокодом все чего не понимает...
      Ответить
  • Си развращает. В языках со строгой типизацией, например в Паскале, перечисление будет новым типом и придётся повсюду вставлять операцию приведения типа или move.
    Всё-таки перечисление — это набор однотипных сущностей, а здесь время и количество. Но данный код только выглядит ужасно, а работать он должен. Хотя написать #define было бы нагляднее, чем плодить новые сущности.
    Ответить
    • в данный момент enum состоит из констант которые могут быть безопасно приведены к int. в новом стандарте будет возможность создавать типизированный enum.
      Ответить
      • >могут быть безопасно приведены к int
        Да. Пожалуй никто не погибнет. Лишь при прилунении лунохода, последний разлетится на мелкие кусочки из-за того, что тип энумв и другой переменной случайно совпали и ошибки компиляции не последовало.
        Знаешь, сколько людей за эти деньги можно было вылечить от рака и спасти им жизнь?
        Ответить
        • шо за бред?? значения енамов приводятся к инту по стандарту, а вот обратное является ошибкой...
          Ответить
  • Это не совсем говнокод. В С++ условиях, это выгодно для реализации классов-стратегий. Хотя без этого можно обойтись... Это вопрос стиля.
    Ответить
    • > В С++ условиях, это выгодно для реализации классов-стратегий.

      Но раздел-то "си". Запостил бы автор сие в С++ - нареканий бы не было. Какими бы хаками с++-дитя не тешилось...
      Ответить
  • страйкер! готов перевести тебе 5 баксов за список всех плюсовавших и минусовавших в этой теме... жду письма с номером счета...
    Ответить
    • Вы так говорите, как будто анонимность в интернетах — это что-то плохое.
      Так зондеркоманда в Интернете всё-таки существует! А что нам за плюсы и минусы будет? Как в поисковике: мы вопрос, а Вы ссылку?
      Ответить
  • Здесь проблема только в том что две несвязанные константы объявленны в одном enum.
    Ответить

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

Переведи на "PHP", guest!

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


    8