Кресты / Говнокод #27022 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
#include <iostream>
#include <string>

using namespace std;

struct A
{
    uint16_t    n;

    uint8_t     a1:1;
    uint8_t     a2:1;
    uint8_t     a3:1;
    uint8_t     a4:1;
    uint8_t     a5:4;

    uint8_t     b;
} __attribute__((packed));

int main()
{
    char v[] = { 0x1, 0x1, 0b01010011, 0x9 };
    A *p = (A*)v;
    
    cout << (uint16_t)p->a1 << endl;
    cout << (uint16_t)p->a2 << endl;
    cout << (uint16_t)p->a3 << endl;
    cout << (uint16_t)p->a4 << endl;
    cout << (uint16_t)p->a5 << endl;
    cout << (uint16_t)p->b << endl;
}

http://cpp.sh/6e5myf

Битовые поля неправильно считываются.

Запостил: YpaHeLI_ YpaHeLI_, (Updated )

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

  • Переведи на "PHP". Здесь никто не обязан знать язык для "Arduino" и прочих игрушек для школьников, увлекающихся робототехникой, нанотехнологиями и мечтающих попасть в "Сколково" (на котором верхи, к слову, просто пилят деньги и ржут над сиволапым деревенским синим быдлом, отдающим детей в "крутые" кружки и классы).
    Ответить
      • Мне надо просто принять от клиента данные и сохранить их в базе данных; либо, напротив, выдать ему некую информацию. Нахуй мне какие-то битовые поля? В чём их прикол?
        Ответить
        • Ну вот потребует клиент сохранить половину бита — и что ты будешь со своим «PHP» делать?!
          Ответить
          • В какой ситуации это может понадобиться? Честно - я действительно не понимаю, что это и зачем оно нужно.
            Хотя, половина бита - это нечто невозможное.
            Ответить
            • Ну вот смотри: у Васи Пупкина есть тысяча воздушных шариков, из которых 707 — красные, а 293 — зелёные. Пётр Иванович Штольников — престарелый профессор философских наук — страдает лёгкой степенью протанопии. Опаздывая на встречу выпускников, Вася Пупкин не глядя схватил десяток шариков и выбежал на улицу. Однако в это же время совершенно случайно в городе была сильная буря, и девять из десяти шаров Васи унесло непогодой в соседний город. Примерно через три часа один из унесённых ветром шаров пролетел мимо окна Петра Ивановича Штольникова, который в этот момент любовался красивым закатом. К сожалению, из-за глазной болезни заслуженного профессора пролетающий воздушный шарик остался незамеченным Петром Ивановичем. Возможно, сложись всё иначе, и Пётр Иванович вспомнил бы, как, стоя на линейке с красивой лентой через плечо, он вместе со своей одноклассницей Людей — теперь уже, конечно, Людмилой Сергеевной — запускал в небо точно такие же воздушные шарики. Вспомнил бы — и позвонил своей старой знакомой, которая всю жизнь страшно любила поболтать. Проболтав (хотя, откровенно говоря, прослушав) с ней до темноты, Пётр Иванович раздосадованно стукнул бы себя по лбу — в магазин идти уже поздно. Поворчав для приличия, профессор щёлкнул бы выключателем ночника и спокойно заснул.
              К сожалению, пролетающий воздушный шар Пётр Иванович не заметил. С неохотой оторвавшись от окна он оделся, проверил плиту, взял ключи и вышел за дверь. Проезжающий по мокрому асфальту серебряный «Hyundai Solaris» не справился с управлением и не успел затормозить. Петра Ивановича не стало.


              Вот это и есть примерно половина бита.
              Ответить
          • > половину бита

            От половины бита и сишник взвоет. Хотя и такое бывает, конечно.
            Ответить
            • У меня есть идея: половина бита — это такое значение, которое не имеет смысла без его второй половинки.

              Вот у нас есть «половина бита» b1 (в памяти она занимает целый бит — будем считать это выравниванием) и «половинка бита» b2, а в программе везде используется только (b1 xor b2) или (b1 == b2). Тогда, зная только b1 или только b2, мы не сможем предугадать поведение программы, а зная значения обоих, будем знать результат.
              Ответить
              • комплексный бит, вещественная часть, мнимая часть

                при bitwise-операциях может стать отсутствием одного бита
                Ответить
              • Ну да, примерно так это и работает во всяком энтропийном кодировании. По значению b1 мы всегда можем предсказать значение b2. Т.е. мы упихали 2 значения в один бит. И можно сказать, что каждое из них занимает по половине.
                Ответить
                • > упихали 2 значения в один бит
                  Упихал два значения — 1 и 0 — в один бит, проверь.
                  Ответить
    • <?php
      
      class AFlags
      {
      	const A1 = 0b1;
      	const A2 = 0b10;
      	const A3 = 0b100;
      	const A4 = 0b1000;
      	const A5 = 0b11110000;
      };
      
      class A
      {
      	public $n;
      	public $a_flags;
      	public $b;
      };
      
      function main()
      {
      	$a = new A();
      	$a->n = 0b000000100000001;
      	$a->a_flags = 0b01010011;
      	$a->b = 0x9;
      	
      	echo ($a->a_flags & AFlags::A1) ? 1 : 0, "\n";
      	echo ($a->a_flags & AFlags::A2) ? 1 : 0, "\n";
      	echo ($a->a_flags & AFlags::A3) ? 1 : 0, "\n";
      	echo ($a->a_flags & AFlags::A4) ? 1 : 0, "\n";
      	echo ($a->a_flags & AFlags::A5) ? 1 : 0, "\n";
      }
      
      main();
      
      ?>


      Хз зачем я это сделал
      Ответить
      • > &

        Ну вот и на сишке так сделай и всё будет норм. Только сдвиг ещё добавить надо, если значение А5 интересно.
        Ответить
        • Да я так всегда и делал, тимлид сказал лучше битовые поля юзать.
          Чисто чтобы потом людям удобнее читать было, если нужно станет, видимо.
          Я уж не совсем новичок, лет 6-7 уже опыт на крестах.
          Ответить
          • > тимлид сказал лучше битовые поля юзать
            Ну если их не сериализовывать (или сериализовывать только в рамках одного приложения на одной машине) — действительно лучше же.
            Ответить
          • > лучше битовые поля юзать

            Если тебе пофиг на их внутреннее представление - да, они довольно удобны.

            Но тебе же не пофиг, раз ты полез байты разглядывать. Видимо пытаешься совместимость с чем-то запинать. В этом случае я бы не стал юзать битовые поля.

            Хотя подогнать порядок можно, конечно. И в пределах одного ABI он не уплывёт. Конпеляторы, соблюдающие одно ABI, всё-таки стараются чтобы сишные интерфейсы между ними не ломались.
            Ответить
            • Кастати, никогда не видел битовые поля в API.

              Все всегда хуячат байт или двубайт, и делают потом оры и энды. Даже в старых джаваапишках такое видел

              Чому?
              Ответить
    • Никогда раньше не видел такое стремление умереть в страшных муках
      Ответить
  • У кого последний MSVC стоит проверьте плиз, а я пойду на шланге скомпилю это.
    Видимо багрепорт придется писать.
    Ответить
    • 9.6 Bit-fields

      Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined.

      Удачного багрепорта.

      З.Ы. Именно поэтому я никогда не юзаю битфилды.
      Ответить
        • 0101 0 0 1 1
          Где хуйня? Просто порядок не совпадает с твоими ожиданиями. Или дока к конкретному конпелятору обещала другой порядок?
          Ответить
          • именно эта поебень заставила меня много лет тому назад делать на шаблонах битовые поля в структуре, чтобы не зависело от компилятора и, главное, бесплатно проходило через границу слова внутри структуры

            при этом чтобы на высоком уровне оставался доступ через foo.a = 100;
            Ответить
            • кстати, я помню, из-за того, что проффессия прогграммиста была типа илитарной, а должность крестуха уж тем более, а контора нанимала 1 крестоблядь в столетие, я после собесов на домашнее задание именно эту задачу и давал лол
              Ответить
          • Ну я понял, он на младший бит ссылается, так как биты у в x86 в big-endian.
            Значит он будет в конце байта.
            Ответить
                • Х.з., с фазой луны? Короче порядок байт и порядок бит - разные вещи.

                  Ну и x86 всё-таки little-endian, младшим байтом вперёд.
                  Ответить
                    • Не беспокойся, я не понимаю ни то, ни другое. Мне всё равно.
                      Ответить
                    • А порядок битов может зависеть от компилятора. Он не обязан совпадать с принятым для данного процессора.
                      Ответить
                      • Не порядок битов, а порядок упаковки битовых полей в структуру.

                        Порядок битов - это скорее о каком-нибудь последовательном порту, в который мы биты один за другим срём. А с точки зрения проца порядка битов обычно и нет. Он их все одновременно выгружает.
                        Ответить
                        • Я вспомнил, как компиляторы хранят локальные переменные функции (если на них брать указатели, чтобы он не смог их оптимизировать в регистр):
                          • Одни компиляторы пушат в стек переменные по очереди, так что последняя переменная находится ниже всех.
                          • Другие компиляторы сразу выделяют память в стеке (sub rsp, константа) и размещают переменные в порядке их объявления, так что последняя переменная оказывается выше всех.

                          И вроде оба способа имеют право на существование, потому что из хорошего кода есть доступ только к переменным по отдельности, по их имени, а доступа к локальным переменным как к массиву нет.

                          Значит, и тут в хорошем коде должен быть доступ только к битовым полям по отдельности, по их имени, чтобы не думать о порядке упаковки?
                          Ответить
                          • Ну тип того. Тут ведь между ними ещё и паддинг может быть.
                            uint8_t a: 1;
                            uint8_t b: 8;
                            uint8_t b: 7;
                            З.Ы. gcc вот даже ругается, что паддинг битовых полей был изменён в 4.4, если добавляешь packed.
                            Ответить
                              • Да не, в пределах одного ABI можно аккуратно запинать битовые поля. Самому битовые и байтовые паддинги расставить, типы правильно подобрать и т.п. Но стоит ли оно того?
                                Ответить
                          • А я вспомнил про юнионы.
                            Там вроде гарантируется, что у тебя работает только один член. Так что ты можешь пыжиться, и понимать внутренее устройство юниона, но стандарту на твое понимание пофиг.

                            Кто-то (чуть ли не Калиграфер?) говорил, что отличие нуба от настоящего крестовика в том, что нуб начинает рассуждать как конкретная фича реализована, и делает из этого выводы, что можно, а что нельзя.

                            А настоящий крестовик сразу идет в стандарт
                            Ответить
                            • В «Турбо Паскале» отказались от проверки дескриптора вариантных полей записи, чтобы они работали, как union в сишке (в популярных на тот момент реализациях сишки, а не в стандарте). Всё правильно сделали?
                              Ответить
                              • В смысле разрешили обращаться и как к члену1 и как к члену2?

                                Как-то не очень. Паскаль же строгим должен быть
                                Ответить
                                • Ну да. Поэтому записи с вариантными полями в наследниках «Турбо Паскаля» («Delphi», «Free Pascal») часто используют в качестве reinterpret cast.

                                  Проверил несколько реализаций «Паскаля» — дискриминант (поле, указывающее на то, какой из вариантов активен) проверяет только «Irie Pascal» (который сейчас никому не нужен, потому что он поддерживает только «Standard Pascal» без расширений).
                                  Ответить
            • >> биты у в x86 в big-endian

              Приведите реальные примеры инструкций x86, у которых есть доступ к битам по номеру.
              Ответить
        • https://gcc.godbolt.org/z/j85PvM
          mov     rax, qword ptr [rip + a]
          movzx   esi, byte ptr [rax + 2]
          and     esi, 1                        ; a1
          mov     edi, offset .L.str
          xor     eax, eax
          call    printf
          mov     rax, qword ptr [rip + a]
          movzx   esi, byte ptr [rax + 2]
          shr     esi
          and     esi, 1                        ; a2
          mov     edi, offset .L.str
          xor     eax, eax
          call    printf
          mov     rax, qword ptr [rip + a]
          movzx   esi, byte ptr [rax + 2]
          shr     esi, 2
          and     esi, 1                        ; a3
          mov     edi, offset .L.str
          xor     eax, eax
          call    printf

          Где здесь хуйня, YpaHeLI_?

          Берём 0b01010011, наименее значащий бит — первое битовое поле, следующий за наименее значащим — второе, потом третье, и так далее, и тому подобное. a5 получается простым сдвигом вправо на 4 бита.
          Ответить
          • Блядь, как всё сложно. Нахуй вы себе мозги ебёте этим говном?
            Ответить
            • Какого хуя ты приперся в ветку C++ и начал здесь доказывать что C++ это хуйня ебанная для собак и говноедов? Иди дальше оптимизировать хранение строчки в мускуле называя это достижением века
              Ответить
              • Нахуя? Он просто арендует сервер подороже.
                Ответить
                  • Существуют сервера с 512Гб памяти. Конарде должно хватить.
                    Ответить
                      • EC2 High Memory instances offer 6, 9, 12, 18, and 24 TB of memory in an instance.

                        https://aws.amazon.com/ec2/instance-types/high-memory/

                        Так что Ротоёб может вообще ничего не оптимизировать.

                        Стоимость месячной аренды будет примерно равна зарплате Ротоёба за 10 лет, но это технические детали уже

                        зы: интересно, как физически выглядит столько памяти? Это NUMA и охулион процессоров?
                        Ответить
                        • ебанись

                          ну это, походу, вот такой вариант
                          https://www.supermicro.com/en/products/bigtwin?pro=cpu%3D2%26cputype%3D3%26nodes%3D4%26dimm%3D24%26storageinterface%3D57

                          4 ноды по 2 цпу (= 8 цпу) и 24 слота памяти на ноду (=96 слотов)
                          если заебенить 256ГБ модули, как раз 24ТБ и выйдет

                          а зионы 28 ядерные (8*28*2), чтобы получить 448 vcpu
                          Ответить
                          • * CPU будут работать в режиме энергосбережения
                            Ответить
                              • Интиересная какая штукаа.

                                Выходит, DRAM контроллер управляет не чипами, а управляет он буфером, который эмулирует для него этакий виртуальный "ранк".

                                Получается, что контроллер может поддержать куда больше памяти, но наверныяка за счет некоторой латентности буфера.

                                Впрочем, там наверное такие кеши, что это и не важно.
                                Ответить
                • Но ведь действительно: оптимизация - это путь нищебродов, неспособных арендовать сервер подороже и вынужденных тщательно продумывать длину поля в БД, отказывающих себе в "mediumtext" и "bigint", тяжело вымучивающих каждый индекс, и так далее.
                  Ответить

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

Помни, guest, за тобой могут следить!

    А не использовать ли нам bbcode?


    8