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

    +1

    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
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    // https://github.com/CVC4/CVC4/blob/14b9dbaa0c9e8dce52d1a28595dc1cc80756abed/src/expr/pickler.cpp
    
    
    static Block mkBlockBody4Chars(char a, char b, char c, char d) {
      Block newBody;
      newBody.d_body.d_data = (a << 24) | (b << 16) | (c << 8) | d;
      return newBody;
    }
    
    static char getCharBlockBody(BlockBody body, int i) {
      Assert(0 <= i && i <= 3);
    
      switch(i) {
      case 0: return (body.d_data & 0xff000000) >> 24;
      case 1: return (body.d_data & 0x00ff0000) >> 16;
      case 2: return (body.d_data & 0x0000ff00) >> 8;
      case 3: return (body.d_data & 0x000000ff);
      default:
        Unreachable();
      }
      return '\0';
    }
    
    // ...
    
    void PicklerPrivate::toCaseString(Kind k, const std::string& s) {
      d_current << mkConstantHeader(k, s.size());
    
      unsigned size = s.size();
      unsigned i;
      for(i = 0; i + 4 <= size; i += 4) {
        d_current << mkBlockBody4Chars(s[i + 0], s[i + 1],s[i + 2], s[i + 3]);
      }
      switch(size % 4) {
      case 0: break;
      case 1: d_current << mkBlockBody4Chars(s[i + 0], '\0','\0', '\0'); break;
      case 2: d_current << mkBlockBody4Chars(s[i + 0], s[i + 1], '\0', '\0'); break;
      case 3: d_current << mkBlockBody4Chars(s[i + 0], s[i + 1],s[i + 2], '\0'); break;
      default:
        Unreachable();
      }
    
    }

    Очередное переизобретение какой-то байтоебской поеботы типа ntohl(). И вообще, тут UB.

    Запостил: j123123, 21 Февраля 2019

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

    • Hakuna matata! В программах на "Си" или "C++" всегда есть какой-нибудь UB.
      Ответить
    • А где, собственно , UB?

      P.S. s.size() >= std::numeric_limits<unsigned>::max() - 4 наверняка вылетит по памяти значительно раньше. Но "cover my ass" assert можно и вставить.
      Ответить
      • Ну, к примеру, на шестой строке.
        Ответить
        • Надо заранее указать тип контейнера для результата, чтобы не было переполнения, иначе тупой компилятор может попытаться сдвинуть char на 24 разряда?

          Что-то типа (uint32_t)a << 24 или static_cast?
          Ответить
          • Не, char он таки превратит в int перед сдвигом.

            Но int во-первых хуй знает какого размера. А во-вторых сдвиг знакового числа влево до упора ничем хорошим не закончится (даже при 32-битном инте).
            Ответить
    • > UB
      Да похуй на UB, оно вообще не работает (отрицательное d засрёт своим знаковым битом всё остальное). Или у автора там беззнаковый чар?
      Ответить
      • То есть ещё во время каста будет так называемое расширение знака?

        Кстати, у некоторых кококомпиляторов есть переключатель «signed char/unsigned char».
        Ответить
        • А я думал, что chad всегда singed.
          Ответить
          • Он же вроде хрен знает какigned, если не специфицировать signed/unsigned.
            Ответить
        • > переключатель «signed char/unsigned char»
          Т.е. это на случай, когда пишут не signed char, не unsigned char, а просто char?
          Ответить

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