1. Си / Говнокод #14174

    +139

    1. 1
    2. 2
    byteL = (length & (0x00ff));
    byteH = (length - byteL)>>BITS_IN_BYTE;

    Вдруг биты справа полезут прямо из компьютера, давайте вычтем!
    Макрос BITS_IN_BYTE особенно радует!

    Запостил: sermp, 04 Декабря 2013

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

    • #define AND_CONST (1<<BITS_IN_BYTE) - 1
      byteL = (length & (AND_CONST));
      byteH = (length - byteL)>>BITS_IN_BYTE;
      Исправил. Или даже так:
      byteH = (length & ~(AND_CONST))>>BITS_IN_BYTE;
      byteL = (length - byteH<<BITS_IN_BYTE)>>BITS_IN_BYTE;
      Так надёжнее.
      Ответить
      • Мой вариант:
        #define BYTE_MASK ((1 << (BITS_IN_BYTE)) - 1)
        byteH = (length >> (1*BITS_IN_BYTE)) & BYTE_MASK;
        byteL = (length >> (0*BITS_IN_BYTE)) & BYTE_MASK;
        Легко масштабируется для четырехбайтных чисел:
        byteHH = (length >> (3*BITS_IN_BYTE)) & BYTE_MASK;
        byteHL = (length >> (2*BITS_IN_BYTE)) & BYTE_MASK;
        byteLH = (length >> (1*BITS_IN_BYTE)) & BYTE_MASK;
        byteLL = (length >> (0*BITS_IN_BYTE)) & BYTE_MASK;
        Ответить
        • Вернее даже так:
          #define BYTE_MASK ((1 << (BITS_IN_BYTE)) - 1)
          #define GET_BYTE(x, pos) (((x) >> ((pos)*(BITS_IN_BYTE))) & (BYTE_MASK))
          
          byteH = GET_BYTE(length, 1);
          byteL = GET_BYTE(length, 0);
          
          byteHH = GET_BYTE(length, 3);
          byteHL = GET_BYTE(length, 2);
          byteLH = GET_BYTE(length, 1);
          byteLL = GET_BYTE(length, 0);
          Ответить
          • Ну и вместо BITS_IN_BYTE, наверное, стоит поюзать CHAR_BIT из limits.h.

            Кстати эту фигню гцц компилит в красивый код:
            movzbl  %al, %edx
            movzbl  %ah, %eax
            Ответить
          • Выдыхайте
            Ответить
    • > Макрос BITS_IN_BYTE особенно радует!

      А вдруг?
      Ответить
    • Баг на баге глюком погоняет.
      http://u.to/BZcyBQ
      Ответить
    • Что плохого в BITS_IN_BYTE? Пусть оно не меняется, зато сразу понятно, в отличии от какой-то там 8. Хотя 0х0ff конечно портит картину, inkanus-gray все правильно исправил.
      Ответить
      • > Что плохого в BITS_IN_BYTE?
        http://govnokod.ru/14174#comment203332
        Ответить
        • http://ru.wikipedia.org/wiki/Limits.h

          Многие ЦСП имеют CHAR_BIT равным 16 или более[1][2]
          Ответить
          • Тогда уж надо призывать автора кода и спрашивать, хотел ли он привязаться к размеру байта на исполняющей машине ради какой-нибудь оптимизации, или к размеру байта у потребителя.
            Ответить
            • Но суть в том что byte<>char. Поэтому независимо от CHAR_BIT никто не мешает ввести BYTE_BIT. А чему его присваивать - да, зависит от кода.
              Ответить
              • в С, byte == char. потому что в С char и есть байт.

                это только на кривых/нишевых платформах которым по барабану совместимость во всем остальным, char может быть более чем один байт.

                если проц не умеет байты, что уже случалось не раз, то компилер должен эмулировать.
                Ответить
                • > char может быть более чем один байт
                  Чем один октет? Не зря же во всяких RFC пишут именно "октет" а не "байт"...
                  Ответить
                  • в RFC так пишут потому что там полно старожилов из телекомуникации. (AT&T, создатель UNIX & C - телекомная контора.) это просто как бы отсылка на те времена когда байты разные были. и к слову на них, С компилеры 8ми битовый char симулировали.

                    я где-то видел флеймы с тех времен, где то ли Керниган то ли Риччи флеймил на чудаков на тему что char в С есть и останется 8 байт, и идите в Ж с вашими извращениями. это были как раз те времена когда все железо начало стандартизироватся на 8ми битном байте.
                    Ответить
                  • Страхуются, потому что на некоторых машинах нет байтов, размер слова не делится на 8, поэтому в эмулируемом byte больше 8 бит.

                    Процитирую http://www.parashift.com/c++-faq/intrinsic-types.html:

                    26.1. Can sizeof(char) be 2 on some machines? For example, what about double-byte characters?

                    No, sizeof(char) is always 1. Always. It is never 2. Never, never, never.

                    Even if you think of a "character" as a multi-byte thingy, char is not. sizeof(char) is always exactly 1. No exceptions, ever.

                    26.4. But, but, but what about machines where a char has more than 8 bits? Surely you're not saying a C++ byte might have more than 8 bits, are you?!?

                    Yep, that's right: a C++ byte might have more than 8 bits.

                    The C++ language guarantees a byte must always have at least 8 bits. But there are implementations of C++ that have more than 8 bits per byte.

                    26.5. Okay, I could imagine a machine with 9-bit bytes. But surely not 16-bit bytes or 32-bit bytes, right?

                    Wrong.

                    I have heard of one implementation of C++ that has 64-bit "bytes." You read that right: a byte on that implementation has 64 bits. 64 bits per byte. 64. As in 8 times 8.

                    And yes, you're right, combining with the above would mean that a char on that implementation would have 64 bits.

                    Ну и самое интересное в 26.6, где рассказывается про PDP-10 с 36-битовыми словами, где компилятор эмулирует 9-битовые байты.
                    Ответить
                    • Ну байт это же, насколько я помню, минимальная единица информации, с которой может работать данный проц. Поэтому если какое-то DSP умеет пережевывать только выровненные на 32 бита 32-битные числа, то для него байт будет 32 бита... Хотя с помощью масок можно сэмулировать и октет, но будет меедленно.
                      Ответить

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