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

    +22

    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
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    /* macro is a way faster than inline */
    #define Compare(offsetx, offsety)                                              \
    do {                                                                           \
        int add;                                                                   \
        Point other = Get(g, x + offsetx, y + offsety);                            \
        if(offsety == 0) {                                                         \
            add = 2 * other.dx + 1;                                                \
        }                                                                          \
        else if(offsetx == 0) {                                                    \
            add = 2 * other.dy + 1;                                                \
        }                                                                          \
        else {                                                                     \
            add = 2 * (other.dy + other.dx + 1);                                   \
        }                                                                          \
        other.f += add;                                                            \
        if (other.f < p.f)                                                         \
        {                                                                          \
            p.f = other.f;                                                         \
            if(offsety == 0) {                                                     \
                p.dx = other.dx + 1;                                               \
                p.dy = other.dy;                                                   \
            }                                                                      \
            else if(offsetx == 0) {                                                \
                p.dy = other.dy + 1;                                               \
                p.dx = other.dx;                                                   \
            }                                                                      \
            else {                                                                 \
                p.dy = other.dy + 1;                                               \
                p.dx = other.dx + 1;                                               \
            }                                                                      \
        }                                                                          \
    } while(0)

    Нужно делать макросы ЕЩЕ больше!
    http://habrahabr.ru/post/215905/

    Запостил: gost, 02 Апреля 2014

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

    • >macro is a way faster than inline
      Просматривая асмовыхлопы компилятора, никаких убыстрений от макросов по сравнению с инлайном я не обнаружил (хотя компиляторы разные бывают)
      Ответить
      • Конкретно для этого случая?

        Тут кода прилично, компилятор мог забить на инлайнинг. Ну и не факт, что автор кода в топике не забыл включить оптимизацию :)
        Ответить
        • Автор признался, ему просто показалось.
          http://www.gamedev.ru/projects/forum/?id=152527&page=28#m414
          Ответить
    • А результат упихивается в переменную p?
      Ответить
    • С++ - говно, не то, что php
      Ответить
    • while(0) тоже хорошо смотрится )
      Ответить
      • do {/*...*/} while(0) — стандартная идиома чтобы избежать многих проблем при использовании макросов и сделать их малоотличимыми от void-функции.
        Ответить
        • и без ругани?

          в Java еще веселей:
          if(false){} - компилируется, а while(false){} - нет
          Ответить
        • {/*...*/}
          Ответить
          • Не, так упростить эту конструкцию нельзя ;)

            Дело в точке с запятой. do { ... } while (0) ее требует, и без нее не компилится. И вызов макро выглядит как вызов функции. А без do/while - вызов макро будет выглядеть как говно или вообще забагуется:
            #define MACRO() { ... }
            
            if (some)
                MACRO();
            else // ошибка, неожиданное else
                ...
            
            if (some)
                MACRO() // работает, но надо постоянно думать надо ли ставить ;
            else
                ...
            
            #define MACRO2() do { ... } while (0);
            
            if (some)
                MACRO2(); // все ок, привычный синтаксис
            else
                ...
            
            if (some)
                MACRO2() // не компилится, требуется ;
            else
                ...
            Ответить
            • P.S. Все заповеди макроёбства выстраданы годами... не надо пытаться их упрощать не разобравшись в том, почему они пишутся именно так...

              Вот еще задачка для юных макроёбов:
              // почему надо писать так
              #define FOREACH() if (0) {} else for (что-то там)
              // а не так
              #define FOREACH() if (1) for (что-то там)
              // и не так
              #define FOREACH() for (что-то там)
              Ответить
              • Во втором случае получим неожиданное поведение если макрос окажется между if и else в коде.

                Третий ЕМНИП фиксит баг со скоупом переменных цикла в старых версиях визуалки стандарта С. В противном случае будет ругаться на повторное объявление служебных переменных макроса.
                Ответить
            • > Не, так упростить эту конструкцию нельзя ;)
              Эта штука на смайлик похожа, я сначала хотел написать, что она похожа, но потом подумал, что это очевидно и достаточно просто её выделить.
              Ответить
      • Это не while (0) { ... } а do { ... } while (0). Не надо их путать :)

        В while (0) { ... } блок никогда не выполнится.
        В do { ... } while (0) блок выполнится 1 раз.
        Ответить
      • Люр, этот трюк с do{}while(0), для макросов в сишке обсуждался несколько раз.
        Еще вроде тред про if() ~ else {} был, тоже макро-нюансы.
        Ответить
    • Люди - ну не делайте так, отладчики об такие макросы спотыкаются.
      Ответить
      • И даже если отладчик не юзаешь - один хрен лучше так не делать ;)
        Ответить
    • пфффф...
      Вот это - макрос.
      https://github.com/attractivechaos/klib/blob/master/khash.h#L184
      А тут так, игрушки.
      Ответить

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