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

    −18

    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
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    int func() {
      try {
        throw 1;
      } catch (int i) {
        return i;
      }
    }
    
    asm:
    
    func():
            push    rbp
            mov     rbp, rsp
            push    rbx
            sub     rsp, 24
            mov     edi, 4
            call    __cxa_allocate_exception
            mov     DWORD PTR [rax], 1
            mov     edx, 0
            mov     esi, OFFSET FLAT:typeinfo for int
            mov     rdi, rax
            call    __cxa_throw
            cmp     rdx, 1
            je      .L5
            mov     rdi, rax
            call    _Unwind_Resume
    .L5:
            mov     rdi, rax
            call    __cxa_begin_catch
            mov     eax, DWORD PTR [rax]
            mov     DWORD PTR [rbp-20], eax
            mov     ebx, DWORD PTR [rbp-20]
            call    __cxa_end_catch
            mov     eax, ebx
            add     rsp, 24
            pop     rbx
            pop     rbp
            ret

    gcc 6.2. Ицц/шланг туда же. But why?

    Запостил: Antervis, 21 Декабря 2016

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

    • А что не так-то?
      Ответить
      • Видимо антервис негодует, что конпилятор не выкинул его трайкетч и не сделал просто return 1.
        Ответить
        • Дык наверное у __cxa_throw есть куча сайд-эффектов вплоть до std::terminate -> SIGABRT себе, вот и не выкинул. И вообще -- экзепшены -- штука рантаймовая, нам срочно нужны constexpr-try-блоки!
          Ответить
          • __cxa_throw - это детали реализации исключений. Его не надо выкидывать, потому что его можно было не вставлять прежде всего. Да и конпилятор знает про сайдэффекты собственного рантайма.

            PS: Я не знаю и не утверждаю, может ли конпилятор позволить себе такие оптимизации. Возможно там есть какие-то нюансы у throw.
            Ответить
            • Рантайм (libstdc++.so) обычно уже есть в собранном виде, и полноценный оптимизатор по нему уже не проходится.

              P.S. Lol: http://i.imgur.com/vTIeJhf.png
              Ответить
              • strlen тоже во внешней libc, что не мешает компилятору не вызывать ее лишний раз в цикле for (i = 0; i < strlen(blah); ++i).
                Ответить
                • ... только если присутствует мутабельное обращение к blah.
                  Ответить
                  • Суть комента не в этом была, так что зря ты пришел и сумничал.
                    Ответить
            • > constexpr-try-блоки
              Дайте Бросьте два!
              Ответить
    • А тебе зачем такое? Обычно исключения бросают в одном месте, а ловят в другом. А еще хорошие программисты не бросаются исключениями по пустякам. Я бы на их месте тоже забил на такие оптимизации.
      Ответить
      • допустим, у меня внутри try 10 вызовов, кидающих исключения, и один не кидающий, но если оный возвращает false, надо перейти в catch блок. Что делать, как быть?
        Ответить
        • Найти автора последнего вызова и отпиздить?
          Ответить
    • С какими ключами конпилировал? Шо за люди...
      Ответить
      • Так и с -О2, и с -О3. Прежде чем пиздеть, сам бы проверил.
        Ответить

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