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

    +2

    1. 1
    https://m.reddit.com/r/cpp/comments/4pmlpz/what_the_iso_c_committee_added_to_the_c17_working/

    Мне остаётся только спросить:

    Запостил: laMer007, 26 Июня 2016

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

    • Где здесь C++, комитет?
      Ответить
      • C++17 is based on C11 instead of C99

        Вот это главная новость, ибо крестопитушня нужна только анскиллябрам заедушным.
        Ответить
    • > if (init; condition) and switch (init; condition)

      пффф
      https://ideone.com/pglY9s

      auto в шаблонах вроде выглядит нормально

      про Forward progress guarantees чет не въехал

      С11 радует
      Ответить
      • > if (init; condition)

        Хех, так и знал, что это проталкивает какой-то гугловый гошник.

        > пффф

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

          (а еще, совершенно случайно, я недавно узнал, что в крестах можно использовать кейворды not and or not_eq...)
          Ответить
          • Это не шибко полезно потому, что легко заменяется на другие языковые конструкции. Просто по факту немного красивее и в некоторых случаях это прям зарешает

            Скажем, для scoped variable старая версия слегка жирная:
            {
              std::unique_lock<std::mutex> lock(_mutex);
              if (_data) {
                // ...
              }
            }

            Или, например, версия с ранним return'ом:
            int i = doSmth();
            if (i < 0)
              return i;

            Превратится в
            if (int i = doSmth(); i < 0) return i;

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

                "Ой всё, три строчки в одной, я заблудился." И похер что можно в стектрейс глянуть.

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

                Есть блядская тьма способов сделать эффективное логирование с кучей точек возврата. А вот способов сделать вложенные на 15 уровней if-ы читабельными - нет.

                > чтобы сделать написание компилятора максимально трудным.

                Конструкция имеет эквивалентную замену. Расскажи мне, насколько это усложнит компилятор...

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

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

                  > Есть блядская тьма способов
                  Можно хотя бы один пример?

                  > Расскажи мне, насколько это усложнит компилятор...
                  1. У нас нет специального правила только на два выражения разделенных ;, его нужно добавить.
                  2. Это правило нужно специально обработать, т.как оно внезапно становится равносильно блоку, со всемы вытекающими (следить за тем, чтобы переменную не использовали вне блока, например).
                  Если бы у Си компиляторов был уровень лексической трансформации исходников перед составлением АСТ, то эту проблему можно было бы избежать, но т.как нету...

                  > И вообще похер что комитет стандартизации и разработчики компиляторов это разные коллективы
                  Очевидно, это похер комитету по стандартизации, потому что им по всей видимости просто нечем занятся, как придумывать бесполезную херню.
                  Ответить
                  • > Правильно, лень, т.как занимает время: я его лучше проведу с большей пользой, например, другой баг исправлю.

                    Не так уж это долго

                    > Можно хотя бы один пример?

                    Возвращаем std::error_code, например

                    > Это правило нужно специально обработать, т.как оно внезапно становится равносильно блоку, со всемы вытекающими

                    так или иначе, подобное уже делали и неоднократно

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

                    имо не бесполезную. Не хочешь - не пользуйся
                    Ответить
                    • Все остальное - не важно, но это:
                      > Возвращаем std::error_code, например
                      Как это вообще логировать поможет? Лог, это когда мы записываем какую-то информацию о переменных выполняемой функции. Что мне даст это число, если мне нужно узнать какие значения были в полях нескольких структур с которыми эта функция работала.

                      Просто у мудаков, которые пишут
                      if x return;
                      if y return;
                      if z return;

                      Логи выглядят так:

                      log(before x);
                      if x return;
                      log(before y);
                      if y return;
                      log(before z);
                      if z return;
                      log(after z);

                      вместо
                      log(start)
                      do something with x, y, z
                      log(before return)
                      Ответить
                      • чтобы сделать что-то вроде "log(before return)" можно пользоваться либо scoped exit'ом (пишется легко и просто), либо можно сделать класс-обертку типа lock_guard

                        И да, когда "do something with x, y, z" выглядит как:
                        if (...) {
                          if (...) {
                            if (...) {
                              if (...) {
                                if (...) {
                                  if (...) {
                                    if (...) {
                                      // две строчки кода
                                      // закрывающие скобки

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

                                    а если нельзя, то не имеет
                                    Ответить
                                  • Вот у меня есть функция: bool Generator::start() (включить генератор, офк). Или QVector<double> SA::measure(...) (измерить спектроанализатором). Такого рода шагов в сценарии обмера 50+ и они не группируются (осмысленно, по кр мере). Как делаю я:
                                    if (!gen->start())
                                      return ErrorGenerator;
                                    v = sa->measure(...);
                                    if (v.empty())
                                      return ErrorSA;

                                    Успешный сценарий возвращает success.

                                    А теперь вопрос на миллион: как ты бы реализовал подобную задачу?
                                    Ответить
                                    • vector<action_fn_t> actions{...};
                                      for (auto action : actions) {
                                          error_t error = action();
                                          if (error != NULL) break;
                                      }
                                      return error;

                                      Почему return а не throw - я не знаю, но оставил как было.
                                      Проблема разных типов аргументов решается замыканиями.
                                      Ответить
                                      • ты только забыл учесть что аргументы следующих шагов могут зависеть от результата предыдущих. И учитывая это весь код получится в разы больше изначального варианта. Плюс, ты не учел откат состояний.
                                        Ответить
                                        • > что аргументы следующих шагов могут зависеть от результата предыдущих
                                          1. Никто не запрещает переменные захватывать по ссылке.
                                          2. Можно сделать так, чтобы action_fn_t возвращал состояние (StateMonad, да простят меня грешного).

                                          В изначальном коде я не вижу отката, но, опять же, это не сложно реализовать: состояние возвращаемое экшнами содержит в себе ссылку на функцию откатывающую состояние. Тут недавно форсили мое тестовое задание, там это реализовано:
                                          https://github.com/wvxvw/drawpad-assignment/blob/master/src/tld/wvxvw/drawpad/bus/Command.as

                                          class State ... {
                                              State perform(StateArgs args);
                                              State undo();
                                              bool failed();
                                              ...
                                          }
                                          /* override operator () to call perform() */
                                          ...
                                          ::list<State> states{...}
                                          for (::list<int>::iterator it = states.begin(); it != state.end(); it++) {
                                              if (it->failed())
                                                  it->undo();
                                                  break;
                                              }
                                          }

                                          За синтаксис я не уверен, т.как не пишу на крестах, но идея должна быть понятной.
                                          Ответить
                                          • ты мне скажи: ты всерьез думаешь, что обернув каждый (около) тривиальный вызов в бинд ты получишь намного более простой код?
                                            Ответить
                                            • Мне анальная боль кресторазработчика знакома только по воплям с говнокода: я не знаю насколько это плохо работает в крестах. В нормальном языке это не сложно, и существенно уменьшает объем кода / улучшает понимание.
                                              Ответить
                                    • >
                                      if (!gen->start())
                                        return ErrorGenerator;
                                      v = sa->measure(...);
                                      if (v.empty())
                                        return ErrorSA;


                                      Так это ж go!
                                      Ответить
                                      • Кашицин обнаружил это еще в начале ветки.
                                        Ответить
                                        • Чего плохого, если это Го стайл? Го задумывался гуглом как очень простой, понятный и надежный яп. Ну и плюс я стараюсь не злоупотреблять потенциально сложными для понимания фичами
                                          Ответить
                                          • Бывают разные виды простоты:
                                            1. Как числа.
                                            2. Как два пальца.
                                            3. Как все гениальное.

                                            Го - простой потому что плохо продуман. Если не умрет на зачаточных стадиях - повторит историю С++: обрастет кучей костылей, нестыкующихся и недоделаных фич.

                                            Его реальная привлекательность порстоена на одной единственной фиче: сорок лет спустя они реализовали идею из книжки Concurrent C. Там тоже не обошлось без лажи, но она там минимальная.
                                            Все остальное в Го задумано и сделано популистами, которые хотели сыграть на надеждах сишников о том как ничего не меняя сделать сишку лучше. Ну и получилось, соответственно, чуть-чуть лучше, но суть та же говнистая осталась.
                                            Есть языки, на которых - чем больше пишешь, тем больше проникаешься. Го - это наоборот, чем больше пишешь, тем больше разочаровываешься.
                                            Ответить
                                            • > Го - простой потому что плохо продуман
                                              Он продумывался тысячелетиями. Ты просто не умеешь в него играть
                                              Ответить
                      • > вместо
                        > log(start)
                        > do something with x, y, z
                        > log(before return)

                        "И тут мы бросаем исключение!" ⓒ
                        https://habrahabr.ru/company/infopulse/blog/279927/#comment_8817929
                        Ответить
                        • Если бросят исключение то в логе будет указано где, на какой строчке это произошло, и все будут довольны.
                          Проблема в том, что мудаки которы используют "ранний выход" - они ж ленивые, и не пишут логи везде где они нужны, (их же еще и поддерживать потом нужно). И поэтому нужная информация пропадает / устаревает.
                          Ответить
                          • Я думаю что-то вроде
                            #define fatal(message) throw my_exception(message,__FILE__,__LINE__)

                            удовлетворит вашу беспокойную душу. Но с точки зрения скоупа функции, ранний возврат от выброса исключения не отличается ничем
                            Ответить
                • > "Ой всё, три строчки в одной, я заблудился." И похер что можно в стектрейс глянуть.
                  > стектрейс глянуть
                  Компилятора?)))) Ошибка 00000000 в строке 100500 invalid token
                  Ответить
                  • Я бы предложил YYERROR_CALL по-умолчанию: "syntax error", даже без намека на причины.
                    Ответить
                  • отладчика
                    Ответить
            • мьютекс да, согласен, годный юзкейс
              а вот такое
              > if (int i = doSmth(); i < 0) return i;
              выглядит в лучших традициях труЪ сишников
              Ответить
              • в лучших традициях сишников выглядит вызов типа
                if (int i = doSmth(); i < 0) goto before_exit;
                Ответить
              • Так-то конструкция подобного рода уже давно в языке. Теперь ее просто расширить хотят.
                if(int i = doSmth()) // всегда работало, i в scope`е If.
                return i;
                Ответить
                • но if ((int i = doSmth()) < 5) return i; не напишешь
                  Ответить
                  • > не напишешь
                    > Теперь ее просто расширить хотят.
                    Твой коммент - лишний.
                    Ответить
                • да я не про конструкцию, а про то что это выглядит как "о сморите, появился еще один способ написать однострочник"
                  Ответить
          • >совершенно случайно <...> not and or not_eq
            Когда не понимаешь, почему не компилируется.
            Ответить
      • > if (init; condition)

        Напоминает ECMAScript, в котором составной оператор возвращает значение, вычисленное в последнем операторе.
        Ответить
        • Да в сишке испокон веку была запятая.
          Ответить
    • Лично мне не хватает чего-нибудь такого:
      class T
      {
        auto f(auto a)
        {
          return a;
        }
        auto member=f(42u);
      };
      Ответить
      • и нахуй оно надо?
        Ответить
      • // когда жопа так и норовит слипнуться
        auto f(auto a) {
            return a;
        }
        
        // используй c++98
        template<typename T> 
        T f(T a) {
            return a;
        }
        Ответить
        • > template<typename T>
          Почему нормальная конструкция выглядит как днище? Потому что старперу, привыкшему к днищу - спокойнее всегда видеть его перед собой
          Ответить
        • .
          Ответить
    • > new auto(2.0)
      Вернет новый фольцваген жук версии 2.0.
      Ответить
    • struct S { int x; volatile double y; };
      S f();
      const auto [ x, y ] = f();

      а почему не доделали до кошерного
      struct { int x; volatile double y; } f();
      const auto [ x, y ] = f();
      Ответить
      • а еще лучше бы
        { int x; double y; } f();

        чтобы возвращаемое значение можно было кастить к чему угодно, преобразовываемому из {int,double}
        Ответить
        • В этом варианте на горизонте маячат километры кода без единого именованного типа.
          Ответить
          • Ну в шарпе же как-то с такой возможностью живут и никаких не именованных километров кода. Хотя признаю, там культура программистов получше обычно
            Ответить
            • > почти в каждом яп кроме С/C++ с такой возможностью живут
              fixed
              Ответить
          • Доброе утро, питонотуплы

            spam[4][17]
            Ответить
    • Постой, комите-е-ет, я ещё про-ошлые стандарты не вы-ы-ыучи-и-и-ы-ы-ы-л!!!один
      Ответить
      • Они щас раз в три года выходить начнут. Жизнь — боль.
        Ответить
      • Переходи на джаваскрипт. Там каждый месяц выходит новый, популярный фреймворк для решения задачи, которая в остальных языках уже 25 лет как решена.
        Ответить
        • Вот, ты сыронизировал, а я нет-нет да на жабу (без скрипт) посматриваю.
          Ответить
          • > на жабу (без скрипт) посматриваю

            С джавой будешь новых "стандартов" ждать с нетерпением.
            Ответить
            • да ладно

              каждые десять лет новая версия языка выходит, и в ней обычно две-три новые фичи!
              Ответить
              • > каждые десять лет новая версия языка выходит, и в ней обычно две-три новые фичи!
                А у меня больше!

                Фич в 5тилетку. Я Крестовик
                Ответить
          • на яп или на виртуалку?

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

            А вот JVM сама по себе не плоха: нормальная кросс-платформенность и виртуалки, и инструментов (профилировщики, дебаггеры итд)

            ЯПы под нее всякие разные, Kotlin вон, Scala, итд
            Ответить
            • Сам язык. Считаю его стабильность, переносимость и обширность инструментария критически важными характеристиками.
              Ответить
        • Пфф, популярный фреймворк. Раз в джве недели - выходит браузер с новыми фичами и багами.
          Ответить
      • век живи - век учи стандарт с++
        Ответить

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