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

    −17

    1. 1
    if(0){}else for (... тут всякий код...) и тут всякий код

    Из реализации foreach в Qt. Не ГК. Кто первый скажет почему не ГК получит пирожок с полочки.

    Запостил: bormand, 17 Мая 2012

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

    • Исправляет область видимости "всякого кода"? Гугл подсказывает о баге, с ней связанным, в старых версиях Visual Studio.
      Ответить
      • Да, именно так.
        Ответить
        • А почему не
          if (1) for ...

          или вообще не

          { for (...)
          {
          }}

          ?
          Ответить
          • Хотя да, 2е негья исправить дефайном, а 1е может иметь эффекты с другими условиями
            Ответить
    • Говнецо, однозначно!
      Ответить
      • Да ну ? )
        Ответить
      • Ненене, это не говнецо. Говнецо в VS, а это классическая подпорка, в простонародье именуемая "костылём" )
        Ответить
    • помнится BCB6 тоже таким грешил
      Ответить
    • Ну, так избитая классика жанра - в С++ исправление scope переменной, объявленной в заголовке цикла 'for'. Т.е. в

      for (int i = 0; ... )


      переменная 'i' не должна существовать после тела 'for'. А в старом VC++ она продолжала жить и далее.

      Только в явно выписанном коде подобный трюк с 'if;else' не имеет никакого смысла - можно было просто взять этот 'for' в дополнительные скобки '{}' и дело с концом. Из поста не ясно, было ли это в оригинале макросом, или все таки было выписано посередине обыкновенного кода. В последнем случае - есть элемент "говнокодовости".

      Так вот, этот трюк с 'if;else' применяется именно для написания макроса/макросов, решающего данную проблему. В частности, самым радикальным вариантом будет просто сделать

      #define for if (false); else for


      т.е. фактически нагло "переопределить" ключевое слово 'for' и вопрос решен.

      А сам трюк с 'if;else' (вне зависимости от проблемы с 'for') произрастает из техники правильного написания многострочных (т.е. много-stetement-ных) макросов. Правильно написанный многострочный макрос должен быть либо заооболочен в скобки 'do{ ... } while (false)', либо в скобки 'if (false); else { ... }'. Подобная "оболочка" вокруг макроса делает его поведение правильным при использовании в ветках внешних if-ов.
      Ответить
      • У Вас нет своего блога или статей по программированию? Я бы с большим удовольствием почитал. :)
        Ответить
      • > Из поста не ясно, было ли это в оригинале макросом, или все таки было выписано посередине обыкновенного кода.

        Да, код взят из макроса foreach.
        Ответить
      • А чем
        #define for if (true) for

        не угодил?
        Ответить
        • Надо чтобы макрос вел себя правильно во внешних if-ах, как я говорил выше. Если сделать по-вашему, то вот в таком коде

          if (условие)
             for (тра-ля-ля) {
               чего-то делаем;
             }
          else {
            чего-то делаем;
          }


          ветка 'else' будет проассоциирована с "невидимым" if-ом спрятанным внутри макроса 'for'. Это, разумеется, будет большой неожиданностью для автора кода и доставит ему массу счастливых часов недоуменной отладки.
          Ответить
          • Очень годно. Мужик! Уважаю!
            Ответить
          • ждем MacroGovno
            Ответить
          • Мне всегда было интересно: а вот наступающие на эти шутки с макросами люди -- они что, не могут прогнать препроцессор и поглядеть что получилось?
            Ответить
            • Могут, но об этом же ещё вспомнить надо...
              Ответить
    • Говно
      Ответить

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