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

    0

    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
    // https://git.zx2c4.com/BruteZip/tree/read.c?id=e4e9c17b99e0d108136b8a07632b1ebaa7d09d28#n26
    
    int main(int argc, char *argv[])
    {
    	union {
    		long int l;
    		char c[sizeof(long int)];
    	} u;
    	u.l = 1;
    	if (u.c[sizeof(long int) - 1] == 1) {
    		printf("This program only runs on little endian archs, because I'm lazy. Sorry.\n");
    		return -2;
    	}

    Хуйня какая-то. Ведь sizeof(long int) может быть равен sizeof(char).

    Но над такой питушней обычно никто не задумывается

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

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

    • https://govnokod.ru/15707 хуйню с определением endian я уже когда-то вбрасывал
      Ответить
    • Можно ли считать этот ыореант кросплатформиным?
      union {
              int16_t petyx;
              int8_t petyshki[2];
          } petyxu;
          petyxu.petyx = 1;
          if (petyxu.petyshki[0] != 1) {
              puts("TY PETIX!!!");
          }
      Ответить
      • Не работает на платформах без «int8_t» или «int16_t», проверь.
        Ответить
      • нет

        я могу допадить между петухом и питушками скока-то байт

        штандартнетфюррер говорит что играть в такие игры с юнионом не нужно
        Ответить
        • Разве петикс и петишки не будут занимать одну и ту же память?
          Ответить
          • могут да, а могут нет.
            ЕМНИП стаднарт говорит что ты должет юзать ИЛИ петикс или петушков, а если юзаешь оба (тн type punning) то можно получить странные вещи
            Ответить
            • Хотелось бы увидеть примеры самых странных вещей, которые получаются из-за «type punning».

              Перемешивание байтов из-за «big engian», «little endian», «middle endian» меня не интересует, это и так понятно.

              Коверкание чисел из-за копирования целого питуха в плавающего и обратно меня тоже не интересует. Видел я алгоритм с «обратным квадратным корнем» (0x5F3759DF), меня этим не запугать.

              Что ещё бывает?
              Ответить
              • представь что у тебя в юнионе структура внутри
                структуру можно алайнуть по всякому например
                Ответить
                • Допустим. Стандарт позволяет в целях выравнивания добавлять незначащие байты перед структурой?
                  Ответить
                  • Перед нет, а после да.

                    Ты не знаешь расстояние между членами струхтуры
                    Если ты явно не скажешь копулятору как ты её равняеш
                    Ответить
                    • Ну то есть можно гарантировать, что первые байты скалярных членов union'а и первые байты первых полей структур, также являющихся членами того же union'а, будут накладываться?
                      Ответить
                      • Я не уверен что стандарт дает такую гарантию, но думаю что реализации поступают именно так. То-есть носики у них из одного места растут

                        Ща читну стандартеца
                        Ответить
                      • 6.2.6 Representations of types
                        [квот]
                        When a value is stored in a member of an object of union type, the bytes of the object
                        representation that do not correspond to that member but do correspond to other members
                        take unspecified values
                        [/квот]

                        Я правильно понимаю что
                        union petux {
                          age char;
                          iq char;
                        };
                        union petux petookh = {0};
                        petookh.age = 42;
                        // может быть что iq у него стал 96. Или 33. Или 22. Хотя почти всегда он станет 42


                        или я что-то не понял?
                        Ответить
                        • То есть стандарт позволяет для реализации union'а использовать произвольный контейнер? Его члены можно упаковать в какой-нибудь архив (в TAR или в контейнер OLE2) или там есть ограничения на sizeof?
                          Ответить
                          • Можно вообще в разные углы памяти распихкать.
                            Изменение одного не обязано консистентно менять другой

                            Собссно, union нужно юзать как стракт, но в отличие от стракт работа гарантирувается только у одного поля, потому где-то рядом всегда должен ходить енум который говорит какое поле нужно юзать

                            юнион всегда можливо заменить структом, но юнион дает копулятору права экономить места
                            Ответить
                            • > в разные углы памяти распихкать
                              нахуй такой юнон, я всегда считал, что это чтоб память экономить для данных, которые не юзаются одновременно, и чтоб юзать как reinterpret_cast в крестах.
                              Ответить
                              • Вот кстати, существует ли в сишке адекватная замена reinterpret_cast? memcpy/memmove не предлагать. Про каст указателей я знаю, но от него у меня звёздочки в глазах.
                                Ответить
                                • reinterpret_cast и есть брат-блезнец каста через указатели
                                  Ответить
                                  • Но у него хотя бы синтаксис приличный.
                                    Сравни:
                                    rooster = reinterpret_cast<char>(chick);

                                    И вот этот ужас:
                                    rooster = *(char *)&chick;
                                    Ответить
                                    • #define REINTERPRET_CAST(From, To, value) ((union{From from; To to;}){.from = value}.to)
                                      printf("%x", REINTERPRET_CAST(float, int, 3.14));
                                      Ответить
                                      • Ну конкретно для printf каст не нужен, он же не знает о типе :)
                                        Ответить
                                        • знает, ты же ему сам сказал %x
                                          Ответить
                                          • Нет, он не знает что я ему передал, он знает только как это привести к внешнему представлению. Я мог написать %s или %lld или вообще %n и получить хуй-пойми-что.
                                            Ответить
                                    • плюсы сильнее и безопаснее сей, это факт

                                      В простых сях за кастом кроеца ДЖВА вида каста. Тот, который ты показал "просто посмотрев на те же данные по другому" и расширение/сужение (ну там long в int итд)

                                      А в C++ это РАЗНЫЕ касты: reinterprter и static
                                      Ответить
                                      • Нет, в си сделали не плохо, а ещё хуже:
                                        int x = (int)3.14;
                                        float y = (float)3;
                                        printf("%d\n", x);
                                        printf("%f\n", y);

                                        Вот тут, например, и не «посмотреть по-другому» (reinterpret_cast), и не «расширение/сужение», тут полноценное преобразование (с кучей арифметических действий).

                                        Я считаю, что (int) не нужен. Лучше явно использовать floor/ceil/round/что-то там ещё, чтобы показать, как именно ты хочешь округлить.
                                        Ответить
                            • Для сравнения: в стандартном «Паскале» не было отдельных union'ов, там были записи с вариантными полями. Самое последнее поле записи могло ветвиться (естественно, в это поле можно было упихать и сложные типы вроде вложенных записей и массивов), а перед ним должно было стоять специальное поле-дискриминант, которое показывает, какой из вариантов в настоящий момент используется:
                              type
                                Vorent = (eAge, eIq, eWeight); (* это enum *)
                                Petux = record
                                  what: Vorent; (* это дискриминант *)
                                  case what of (* а это начало того самого union'а *)
                                      eAge: (* если what = eAge, используем этот вариант *)
                                          age: byte;
                                      eIq: (* если what = eIq, используем этот вариант *)
                                          iq: byte;
                                      eWeight: (* если what = eWeight, используем этот вариант *)
                                          weight: byte;
                                end; (* end закрывает и case, и record *)

                              Теоретически компилятор или рантайм могли проверить текущее значение дискриминанта (what в нашем примере), чтобы разрешить доступ только к одному варианту.

                              Компания «Борланд» при реализации своего диалекта решила на дискриминант положить болт. В «Турбо Паскале» и в его наследниках можно в любой момент использовать любой вариант (как в «сишке» можно использовать любой член союза):
                              type
                                Petux = record
                                  case integer of (* можно написать любой идентификатор поля или типа *)
                                  (* всё равно он будет проигнорирован компилятором *)
                                      42: (* здесь можно написать любое значение *)
                                  (* всё равно его никто не проверит *)
                                          age: byte;
                                      'Q': (* можно даже указать константу другого типа *)
                                          iq: byte;
                                      false: (* эти константы просто разделяют варианты *)
                                          weight: byte;
                                end; (* end закрывает и case, и record *)

                              И в «Турбо Паскале» уже можно записать значение в petookh.age, а прочитать из petookh.iq, хотя «Standard Pascal» этого не позволял.
                              Ответить
                        • У меня появилась идея. А давайте второй член союза хранить циклически сдвинутым на один бит (ROR 1), чтобы при извлечении нужно было сдвигать обратно (ROL 1); у третьего члена уже делать сдвиг на два бита и так далее, каждый последующий член сдвигать ещё на один бит.

                          union petux {
                            age char;
                            iq char;
                            weight char;
                          };
                          union petux petookh = {0};
                          petookh.age = 42;
                          printf("%d\n", petookh.iq); // выведет 84
                          printf("%d\n", petookh.weight); // выведет 168


                          Стандарт я этим не нарушу?
                          Ответить
                          • А можно всё хранить в одном unit32_t
                            и при знании размера конца индейца можно битовомасочкой и & и | делать всё чево нужно

                            Я верно понил что для твоево варианта нужно 11 бит на petuxа?
                            Ответить
                            • Я предложил не простой сдвиг, а циклический:
                              00101010
                              01010100
                              10101000
                              01010001
                              10100010
                              01000101
                              10001010
                              00010101
                              Он не потребует лишней памяти.
                              Ответить
                              • вот я дебил слепошарый

                                тогда ты прав. Забавно что каждые восемь питухов будут совпадать
                                Ответить
                        • > может быть что iq у него стал 96. Или 33. Или 22. Хотя почти всегда он станет 42

                          Всегда 42.

                          http://eel.is/c++draft/class.union (в других стандартах примерно то же самое)
                          > If a standard-layout union contains several standard-layout structs that share a
                          > common initial sequence ([class.mem]), and if a non-static data member of an
                          > object of this standard-layout union type is active and is one of the standard-layout
                          > structs, it is permitted to inspect the common initial sequence of any of the
                          > standard-layout struct members

                          У тебя в юнионе оба члена одинакового типа и они полностью занимают common
                          initial sequence
                          . Это то же самое, что сделать мемсру из одного в другого.
                          Ответить
                          • Это плюсы
                            А у сишечки?

                            поясни тогда цытаткуо
                            [квот]
                            When a value is stored in a member of an object of union type, the bytes of the object
                            representation that do not correspond to that member but do correspond to other members
                            take unspecified values
                            [/квот]
                            Ответить
                            • это кресты, как в сишечке - не знаю
                              > поясни тогда цытаткуо
                              union { char8_t koko; char32_t kukarek; } u;
                              u.koko = 123;
                              char32_t kudah = u.kukarek; // в трёх битах u.kukarek что угодно,
                                                          // т.к. не common initial sequence.


                              UPD: бля, чёт я не посмотрел на то, что тут всё про си, но чует мой пушистый зад, что в си всё намного проще, ибо нет классов и связанного нетривиального говна
                              Ответить
                              • union petux {
                                  age char;
                                  iq short;
                                  weight int;
                                };


                                тогда так



                                спасибо)
                                Ответить
                            • Как всё сложно. Поэтому я за "HPH".
                              Ответить
          • Надо посмотреть, разрешает ли стандарт выравнивание элементов массива. Вроде бы элементы массива должны идти плотно, но я не уверен.

            Выравнивание полей структуры он разрешает, поэтому при описании структур приходится вставлять директивы компилятора (#pragma, __attribute__), чтобы не выравнивал. У некоторых ЯП даже было слово «packed» для этого.
            Ответить
            • Короче, мне кажется (но я могу спиздеть) что про дается гарантия:

              1) он равен размеру самого большого члена
              2) если ты писнул в какой-то член то ты можешь читнуть оттуда если ты не трогал другие члены

              union petuh{
                char a;
                WORD b;
                char c;
              }


              никто не гарантирует тебе что в b можа осмысленно писать через a и c. Как минимум ты можеш наибаться с байтордером.
              Ответить
              • > равен размеру самого большого члена
                Нет. Возьми юнион из uint64_t и uint8_t[9]. Его размер будет 16 а не 9.
                Ответить
                • выровнявовается?

                  ок, тогда так: не меньше самово большово члена
                  или даже так: достоанчцй для впихуевывания туда самого большого члена
                  Ответить
                  • Union должен быть разработан настолько, чтобы без труда мог вместить самый большой член.
                    Ответить
                    • Да, так в стандарте и написано
                      Ответить
                      • И поэтому его ждёт трудная ночь. Впрочем, как и все предыдущие ночи.
                        Ответить
            • > элементы массива должны идти плотно
              Да. Поэтому по-дефолту размеры всех типов достаточно выровнены.
              Ответить
        • Слишком много софта, привязанного к играм с юнионом. Юнионы используют для сериализации данных, отправляемых по сети или записываемых в файл. Если кококококой-нибудь кококококомпилятор будет что-то вставлять перед элементом юниона, то в нём нельзя будет скомпилировать заметную часть ПО.
          Ответить
    • именно поэтому я за Rust,
      i8,i16,i32,i64,i128
      u8,u16,u32,u64,u128
      isize,
      usize

      и никакой питушни с этими вашими sizeof
      Ответить
    • И вообще проверка рахит-тинктуры должна производиться в компайл-тайме.
      Ответить
      • В S" Forth" я могу включать/выключать компай тайм когда захочу. Именно поэтому я за S" Forth".
        Ответить
    • > Ведь sizeof(long int) может быть равен sizeof(char).

      Это где?
      И кому в хуй может такое упереться?
      Ответить
      • Кто о чём, а ты о хуях.

        На DSP, где один октет адресовать нельзя в принципе. У них в «байте» может быть 16, 32 или даже 64 бита, чего вполне хватает для того, чтобы вместить целый long int.

        Были ещё древние процессоры с 24-битными, 32-битными, 36-битными, 48-битными словами, не разбитыми на байты. У «PDP-10» известный компилятор «Си» разбивал 36-битное слово на 9-битные «байты» (нонеты), но другие компиляторы могли и не разбивать.
        Ответить
        • Забавно что с легкой руки интел понятие "слово" НЕ связано с размером миниально адресуемой едиицы, а связано (почему-то) с ширинкой шинки данунах в старых процах x86

          весь софт давно уже 64битный а слово "слово" означает два байта
          Ответить
          • Минимально адресуемая единица —– это байт, а мышыное слово –— это идинитса размером с регистр.
            Ответить
            • У x86 да. У других систем нет. Мы тут недавно обсудали DRAM, так вот там термином "слово" называется ширина интерфейса микросхемы.

              Да и регистры в Long Mode далеко не 16ти битные, правда?
              Тем не менее WORD в MSDN это 2 байта

              зы: а еще есть параграф, страница и пр

              это всё по 10 раз переиспользовано и везде значит разное
              эх
              Ответить
              • WORD, DWORD и пр. хуетень —– это просто названия типов, оставленные для отвратной совместимости, с термином "мышиное слово" они были связаны только на 16-битных процессорах.
                Ответить
                • Ты хочешь сказать что кто-то в мире x86 называет словом "WORD" кол-во инфрмации, отличное от 16 бит? можно пруфоф?
                  Ответить
                  • Как это следует из того что я нопейсал? В "x86" "словом" называют джва байта из-за анальной совместимости вот и всё, на других ракотектурах оно не зашкварено.
                    Ответить
                    • ах
                      ну я тя не понял

                      Короче, слово "машинное слово" крайне хуевое и ничего не значит в современном мире


                      Ложка – это ложка
                      Ею суп едят;
                      Кошка – это кошка,
                      У кошки пять котят.
                      Тряпка – это тряпка,
                      тряпкой вытру стол.
                      Шапка – это шапка,
                      Оделся и пошел.
                      А я придумал слово –
                      Смешное слово «ПЛИМ»,
                      И повторяю снова «плим, плим, плим».
                      Прыгает и скачет «плим, плим, плим»,
                      Ничего не значит «плим, плим, плим».
                      Ответить
        • Ты не ответил на второй вопрос.
          Кому в хуй это всё упёрлось?
          Кто-то будет заморачиваться с интом - не степенью двойки?
          Ответить
          • Опять ты о хуях.

            char бывает разным. Он не обязан быть восьмибитным. Точно так же long int не обязан вмещать несколько чаров.

            Тебе другой гость написал нестрогое неравенство, из которого следует, что long int может совпасть с чаром.

            Были какие-то реализации, авторы которых поняли слово «char» буквально и решили уместить в него юникодный символ.
            Ответить
            • Короче надо читать limits.h
              там всё написано
              и про CHAR_BIT (кокококококоокличество бит в чаре ахаха) в том числе

              В Java есть тип byte. Он равен одному байту. Всегда. Именно потому я за си
              Ответить
          • Инт может быть не степенью двойки на машинах с троичной логикой. Там, где вместо бита три состояния.
            Ответить
            • Ещё в BCD = binary-coded decimal. Это когда в каждом байте или в каждом ниббле байта (в каждой тетраде) хранится десятичная цифра.
              Ответить
              • Нибла достаточно для выражения 16 чисел, а 10 -- число не круглое
                В 3 бита не влезет, а 4 уже много

                Хочу
                binary-coded hexidecimal: BCH.

                Весь алфавит я знаю от 0 до F
                Ответить
                • Микрокалькуляторы прямо в BCD и считали, чтобы не заморачиваться с перекодированием чисел при выводе на экран.

                  Ещё у IEEE754 есть инструкции для двоично-десятичных данных.

                  А у IBM/370 был шестнадцатеричный плавающий питух:
                  https://en.wikipedia.org/wiki/IBM_hexadecimal_floating_point
                  Там порядок означал не на сколько битов нужно сдвинуть мантиссу, а на сколько шестнадцатеричных цифр.
                  Ответить
                  • Часто думаю как было бы клёво если бы у людей было 2 пальца
                    Детей бы учили двоичной арифметике с детства. Разве что пришлось бы развивать глаза чтобы легко читать 34х значные числа чтобы в ведомостях о зп
                    Ответить
                    • Джва пальца это слишком маленькая разрядность. Именно поэтому я за 64 пальца.
                      Ответить
                      • на 64 не хватит символов, если ты не китаец
                        Мне нравится 16 пальцев, вроде как хекс это кекс
                        Ответить
                        • Джва символа всего надо.
                          Ответить
                          • ты ошибся на 18446744073709551614 символов, но в целом верно

                            я, впрочем, про хекс тоже хуйню сказал
                            65 тыщ символов это эмодзи придется подключать
                            Ответить
                      • –— Я всех умней! —– кричит петух. –—
                        Умею я считать до двух!
                        —– Подумаешь! –— ворчит хорёк. —–
                        А я могу до четырёх!
                        –— Я —– до шести! –— воскликнул жук.
                        —– Я –— до восьми! —– шепнул паук.

                        Тут подползла сороконожка:
                        –— Я, кажется, умней немножко
                        Жука и даже паука —–
                        Считаю я до сорока!

                        —– Ах, ужас! –— ужаснулся уж. —–
                        Ведь я ж не глуп. Но почему ж
                        Нет у меня ни рук, ни ног,
                        А то и я считать бы мог!

                        А у меня есть карандаш.
                        Ему что хочешь, то задашь.
                        Одной ногой умножит, сложит.
                        Всё в мире сосчитать он может!
                        Ответить
            • Стондарт предусматривает недвоичные логики? Нихуя себе!
              Ответить
              • Возможно что да

                правда я не знаю как у него работает &, | и ~
                не знаешь?
                Ответить
                • Из курса дискретной мотематики, ЕМНИП
                  & - min
                  | - max
                  ~ - +1 по модулю

                  (побитово)
                  Ответить
                  • блядь
                    я хочу такой процессор

                    написать эмулячтор может?
                    Ответить
                  • Кстати, в троичной системе каждый трит может хранить (0; 1; 2), а может и хранить (-1; 0; 1). В последнем случае для отрицательных чисел не придётся изобретать никаких дополнительных представлений (правда, детектировать отрицательные числа будет очень трудно).
                    Ответить
                    • хочу чтобы скорость была сто мегатрит, винт один тетрайт а вас всех называли трайтоёбы
                      Ответить
              • Ты тут первый заговорил про «не степень двойки». Поясни свою мысль.
                Ответить
                • Гость выше написал "Инт может быть не степенью двойки на машинах с троичной логикой"

                  А я неправильно выразился. Имел в виду не степенью степени двойки.
                  Ответить
                • https://en.wikipedia.org/wiki/Ternary_computer
                  Ответить
                  • Вобщем на такие машины си не портируется
                    Си требует бита: CHAR_BIT

                    но! CHAR_BIT может бытьт 3

                    тоесть размер char может быть 3 бита тоесть jn 0 до 7
                    Ответить
                    • Вроде char должен как минимум вмещать весь набор символов, которыми набрана сама программа. Там меньше семи битов никак не получается (можно было бы уложиться в шесть, если бы сишка была регистронезависимой).
                      Ответить
                      • P.S. Это свойство окажется полезным для раскрутки компилятора: чтобы на сишке написать компилятор сишки. Без этого свойства парсинг будет выглядеть странновато...
                        Ответить
                      • > весь набор символов
                        Допустим, я заюзал юникодные смайлики в строковых литералах. В чар они не входят. ЧЯНТД?
                        Ответить
                        • A byte is at least large enough to contain any member of the basic execution
                          character set (5.3) and the eight-bit code units of the Unicode UTF-8 encoding form […]

                          § 4.4, 1

                          The basic source character set consists of 96 characters: the space character,
                          the control characters representing horizontal tab, vertical tab, form feed, and
                          new-line, plus the following 91 graphical characters […]

                          § 5.3, 1
                          Ответить
                      • Стандарт рассматривает source и execution наборы символов (5.2.1 Character sets). Каждый из них должен вместить как минимум basic набор (52 буквы, 10 цифр и 29 закорючек).

                        5.2.1.2 Multibyte characters
                        The basic character set shall be present and each character shall be encoded as a single byte.

                        Т.е. таки минимум 7 бит независимо от кодировок.
                        Ответить
                        • Значит, я могу использовать две десятичные цифры (96 < 100), но не могу обойтись четырьмя троичными (96 > 81)?
                          Ответить
              • bormand где-то в глубинах Стандарта раскапывал, что бит в крестах (и сишке) может иметь только два состояния, так что увы.
                Ответить
              • Ага, вот:
                [...] The representations of integral types shall define values by use of a pure binary numeration system. [...]

                § 6.9.1, 7

                A positional representation for integers that uses the binary digits 0 and 1, in which the values represented
                by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except
                perhaps for the bit with the highest position. (Adapted from the American National Dictionary for Information
                Processing Systems.)

                § 6.9.1, 7, сноска 52.
                Ответить
                • Хм, а в C99, если я правильно его читаю, было требование только на unsigned char и битовые поля. А всё остальное implementation defined.

                  Ну и bit - unit of data storage in the execution environment large enough to hold an object that may have one of two values.
                  Ответить
                  • То-есть бит может иметь и 23489723987 состояний, главное больше двух
                    Ответить
      • 1 == char <= short int <= int <= long int <= long long int
        так понятнее?
        Ответить
        • Нихуя не понял, "bormand" говорил, что это какое-то параллельное присваивание.
          Ответить
          • вах) Стандарт голосит:

            Сайзоф чар всегда равен один
            Сайзоф шорт всегда больше или равен сайзоф чар
            Сайзоф инт всегда больше или равен сайзоф шорт
            Сайзоф /\онг всегда больше или равен сайзоф инт

            итд
            Ответить
            • Угу, в некоторых компиляторах для 16-битных платформ sizeof(int) == sizeof(short int) == 2, а в некоторых компиляторах для 32-битных платформ sizeof(int) == sizeof(long int) == 4. То есть int с чем-нибудь по размеру совпадает, но нужно угадать, с чем именно на этот раз.

              По такой логике на 64-битной машине надо было вообще делать sizeof(int) == 8.
              Ответить
              • Хуйзнает кстати

                Это во времна 16битных 286х всем было очевидно что размер самого впопулярного типа долженг быть 2 байта потому что и регистр и шина данных были 2 байта

                То-есть и пересылались они за раз (то самое "слово") и операции с ними были быстрые (потому что в регистр влазили)

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

                К счастью, к момену повления 64битной машины уже давно вышел c99 и всем стало отчаянно похуй на лонги и инты.
                теперь есть stdint.h
                Ответить
              • Кстати заметь: в Microsoft были типы BYTE, WORD, DWORD, QWORD итд
                А юниксе не было типов явного размера до C99.

                Именно потому я за OS/2
                Ответить
                • Да, кстати, в «Юниксе», пытаясь абстрагироваться от железа, выдумали какую-то глупость с типами без явного размера.

                  Но ведь при сохранении данных в файл или при отправке по сети использовался явный размер. Допустим, у меня есть формат графического файла с плотностью 24 бита на пиксель (каналы R, G, B по 8 бит). Если я вместо 24 битов запишу 16, 32 или 64, аргументируя это тем, что такой размер инта на моей машине, то этот файл никто не сможет прочитать (точнее, смогут только те, кто компилировал вьюер тем же компилятором). Значит, мне придётся использовать низкоуровневую питушню, в которой я могу размер указать явно.

                  Почему они так сделали?
                  Ответить
                  • >какую-то глупость с типами без явного размера.
                    Ну не такую уж глупость учитывая разброс тогдашнего железа.
                    Если мне не важен размер я говорю int, и каждый копулятор берет оптимальный размер
                    Тогда это могло быть важно.

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

                    Для сети даже есть спец ntoh / hnton который правит байтордер чтобы SPARC и x86 могли пересылать друг другу порнокартинки
                    Ответить
                    • У формата «TIFF» может быть сигнатура «II» или «MM». Угадайте с одного раза, что она означает.

                      Так вот, «II» означает «Иинтел», т. е. числа, не помещающиеся в байт, записывали адепты маленького конца.

                      «MM» означает «Ммоторола», т. е. числа, не помещающиеся в байт, записывали адепты большого конца.

                      Естественно, как на машине с «little endian», так и на машине с «big endian» можно было посмотреть порнокартинки обоих форматов, просто при просмотре файлов с сигнатурой «MM» на машине с интеловским процессором теоретически чуть-чуть снижался пирфоманс из-за необходимости менять порядок байтов. Хотя какой к чёрту пирфоманс из-за порядка байтов, когда основное время съедает ввод-вывод или разжатие?
                      Ответить
                      • У юникодных файлов вначале есть так называемый BOM

                        Бом
                        Бом
                        Бом
                        Бобобобобомер

                        Угадайте, зачем он нужен
                        Ответить
                        • Чтобы добавить ёбли в парсерах.
                          Ответить
                          • Зато он оберегает от необходимости передавать кокококодировку отдельно или детектировать её хитрыми алгоритмами.
                            Ответить
                          • Напомню, во всём виноваты прыщи.
                            Ответить
                            • Microsoft это уникальная компания которая умудрилась породить ДВЕ несовместимые кодировки в рамках ОДНОЙ ОС которая находилась ПОЛНОСТЬЮ под ее контролем

                              я про cp866 и win1251
                              Ответить
                    • > мне не важен размер
                      Т.е. тебе вообще похуй на результат твоей проги?

                      Есть 3 стула:
                      1) Для корректной работы проги тип должен вместить нужные мне числа. И мне похуй, как конпелятор его реализует.
                      2) Для корректной работы проги тип должен иметь указанные мной размер и представление.
                      3) Мне нужен самый эффективный тип на данной платформе (для длинной арифметики, к примеру).

                      int описывает только третий вариант. А этот вариант в реальном коде встречается гораздо реже первого...

                      З.Ы. Разрабатывая код, я вообще не знаю что я могу засунуть в int т.к. минимальный размер инта описан в informative приложении к стандарту, которое никого ни к чему не обязывает.
                      Ответить
                      • >Т.е. тебе вообще похуй на результат твоей проги?


                        нет. Мой арканоид всегда работает. Я узнаю размеры через limits.h, и на старых компах просто будет поле чуть меньше

                        >> я вообще не знаю что я могу засунуть в int
                        INT_MAX
                        Ответить
                        • > INT_MAX
                          Ну я же пишу - во время разработки кода, а не во время копуляции.
                          Ответить
                          • я знаю что моя треббует минимум INT_MAX = 42
                            я пхаю assert и опуляция падает на сиситемах где это не так
                            и пишу спокойно считая что она 42

                            и ваще
                            разве аутолулз не может такое прврят
                            Ответить
                            • > автолулз
                              Т.е. язык оказался настолько непригоден для разработки, что почти сразу (лет через 8) пришлось к нему нагородить внешний конфигуратор из говна и палок. Ок.
                              Ответить
                              • Кстати, кто-нибудь может объяснить, зачем нужен скрипт libtool? Что он может сделать такого, чего не могут стандартные средства?
                                Ответить
                                • сделай-ка мне либу которая собирается одновременно под мак (clang), солярис и линукс (gcc)
                                  Ответить
                                  • > солярис

                                    а он кому всрался?
                                    Ответить
                                    • ВСРАЛСЯ ТЕБЕ В РОТ, ПРОВЕРЬ
                                      Ответить
                                      • 73 Года назад прессе показали ENIAC!
                                        ENIAC was formally dedicated at the University of Pennsylvania on February 15, 1946 and was heralded as a "Giant Brain" by the press
                                        Ответить
                                  • Под венду всё равно не соберёт.
                                    Ответить
                      • Ещё в эпоху «DOS» было немало случаев, когда случайно оказывалось, что программа не может прочитать половину файла, потому что компилятор по умолчанию использует «signed». Разработчикам приходилось оперативно добавлять квалификатор «unsigned» в 100500 мест, чтобы поднять лимит.

                        Это одно из следствий похуизма.
                        Ответить
                        • >100500
                          typedef is your friend
                          Ответить
                          • А может где-то нужен именно signed и ты своим typedef или #define всё поломаешь?
                            Ответить
                        • > похуизма
                          Не, с файлами другая история. Никто не верил, что появятся настолько огромные накопители и тем более файлы. Причём много раз подряд не верили. Да и сейчас не верят - диски перевели на унылое LBA48 вместо LBA64.
                          Ответить
                      • > должен вместить нужные мне числа

                        Если ты пользуешься обычной (+-*/) арифметикой. А если битоёбишь, то уже не похуй.
                        Ответить
                        • > А если битоёбишь, то уже не похуй.
                          Иди второй вариант дочитай, блджад.
                          Ответить
                        • Поэтому я за "PHP".
                          Ответить
                      • > 3) Мне нужен самый эффективный тип на данной платформе (для длинной арифметики, к примеру).

                        > int описывает только третий вариант.

                        Нет, не описывает. На x86-64 у тебя будет 32-битный int, но для эффективной длинной арифметике на данной платформе лучше взять 64-битный тип
                        Ответить
                      • > З.Ы. Разрабатывая код, я вообще не знаю что я могу засунуть в int т.к. минимальный размер инта описан в informative приложении к стандарту, которое никого ни к чему не обязывает.

                        Нет, это не в informative. Ну может в каких-то старых и так, но давай взглянем на C17 :

                        https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf#subsection.6.2.5


                        > 6.2.5 Types

                        > A "plain" int object has the natural size suggested by the architecture of the executionenvironment (large enough to contain any value in the range INT_MIN to INT_MAX as defined in the header <limits.h>).

                        https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf#subsection.5.2.4


                        > 5.2.4.2.1 Sizes of integer types <limits.h>

                        > Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greaterin magnitude (absolute value) to those shown, with the same sign.
                        Ответить
                        • Хм, и правда. А нахуя они в С99 джва раза эти размеры описали. Один раз в этом разделе и второй - в приложении.

                          Т.е. int это int16_least_t. Ок.
                          Ответить
                        • Кстати, раз UCHAR_MAX должен быть как минимум 255, то CHAR_BIT по этому стандарту менее чем 8-битным быть не может (потому что 255 тупо не влезет в 7-битный байт)
                          Ответить
                        • Вот что реально хотелось бы - набор интов с фиксированной длиной (одинаково работающих для всех платформ) и компайл-тайм флажки про emulated operations и emulated storage для этих типов.

                          Например на арме, если я не туплю, uint8 будет с флагом emulated operation но без emulated storage. А на какой-нибудь DSP'шке он получит и emulated storage.
                          Ответить
                          • З.Ы. Ну и возможно режимы unchecked/checked/saturated для знаковых чисел. Опять же с одинаковой реализацией для всех платформ и флажками про их нативную поддержку.
                            Ответить
                • почему "были"?
                  Ответить
                • Особенно красиво там смотрится DWORD64.
                  Ответить
                • Ой это пиздец какой-то. Какой долбоёб придумал понятие "WORD"?
                  Ответить
                  • Уже обсуждали же.
                    Во времена говен мамонта 2 байта являли собой минимальный пересылаемый размер данных а так же размер регистра, потому-то их и прозвали "машинными словом"
                    Ответить
    • смотри-ка
      https://www.google.com/.well-known/security.txt
      Ответить
    • > Ведь sizeof(long int) может быть равен sizeof(char).

      Тем, кто пишет под такие вот платформы, думаю, не стоит париться о кросс-платформенности.
      Ответить
    • Надо написать самый ебанутый компилятор
      который полностью соответствует стандарту
      но при этом реализует все как попало - 7 бит в байте, 3 байта в инте, поля структуры хранятся в случайном порядке с паддингом, нулевой указатель имеет представление 42.
      И заставить, чтобы все программы могли компилироваться под этот компилятор и работать.
      Ответить
      • Crazy C Compiler
        Ответить
        • Смотри, чувак написал ебанутый компилятор сишки, выхлоп которого содержит только инструкции MOV:
          https://github.com/Battelle/movfuscator
          Ответить
          • Статья о тьюринг-полноте инструкции «mov»:
            https://www.cl.cam.ac.uk/~sd601/papers/mov.pdf

            Автор даже изобрёл ветвление на mov'ах. Пример:
            mov [di], 0
            mov [si], 1
            mov ax, [di]

            В результате выполнения в ax будет лежать 1, если si=di, и ноль, если они не равны.
            Ответить
            • Автор реально крейзи: «Removing all but the mov instruction from future iterations of the x86 architecture would have many advantages: the instruction format would be greatly simplified, the expensive decode unit would become much cheaper, and silicon currently used for complex functional units could be repurposed as even more cache. As long as someone else implements the compiler».
              Ответить
          • Этот чувак реально крэйзи:https://github.com/Battelle/reductio/blob/master/README.md
            Ответить
            • Обобщённое программирование, устранение дублирования кода.
              Ответить
            • Я вот ещё что придумал: к сожалению, инструкцию MOV для x86 нельзя представить в ASCII-кодах, зато инструкции AND, SUB, XOR представить в ASCII-кодах можно, причём как с непосредственным аргументом, так и с байтом mod r/m.

              Надо придумать эффективный способ выражения MOV через комбинации этих трёх инструкций.

              На поверхности такой вариант: обнуляем регистр с помощью XOR или SUB самого с собой, потом с помощью XOR кладём в него новое значение.
              Ответить
              • Он меня опередил. У него есть постпроцессоры, умеющие заменять MOV на другие инструкции:
                ## XORfuscator
                
                x86 xor is Turing-complete, so the XORfuscator translates programs into XOR
                instructions, and only XOR instructions.
                
                ## SUBfuscator
                
                Translates programs into only SUB instructions.
                Ответить
            • я всегда знал что AES и минер это одно и тоже
              Ответить
      • > 3 байта в инте
        31 бит в инте. А то получается, что padding биты в стандарте зря описаны и нигде реально не встречаются...
        Ответить
        • З.Ы. А в padding битах будет лежать CRC4 от данных. И все операции будут убивать прогу если эти биты некорректны. Битоёбы должны страдать.
          Ответить
          • Отрицательные числа запишем в формате sign+magnitude. Причём magnitude поксорено с магической константой и провёрнуто циклическим сдвигом. Ибо нехуй кастовать.
            Ответить
      • Я бы ещё все символы basic execution set перемешал в случайном порядке. Стандарт не запрещает.
        Ответить
      • В указатели добавим случайные биты (равные для указателей на один объект). Ибо нельзя сравнивать указатели на разные объекты.
        Ответить
        • В моём тёмном царстве уныния и безнадёжности появился проблеск надежды. Запрещены ли по стандарту рекурсивные макросы?
          Ответить
          • Да, запрещены, к сожалению. Макросы раскрываются один раз и попадают в блеклист.

            Что не помешало в boost preprocessor замутить конечные но достаточно юзабельные циклы.
            Ответить
        • > Ибо нельзя сравнивать указатели на разные объекты.
          Т.е. вообще нельзя указатели сравнивать?
          Если объекты разные, сравнивать нельзя; если одинаковые, то всё очевидно - не нужно сравнивать. Если неясно, то есть шанс, что объекты разные - нельзя.
          Ответить
          • ЕМНИП указатели можно сравнивать если они указыват на объекты в одном массива

            ну то-есть есть

            petuh[10]. Указатель на первого питуха меньше указателя на второго

            а если есть

            int kurochka;
            char tsyplenochek;

            то сравнивать указатель на цыпленочка и на курочку это UB
            Ответить
            • Какой багор )))
              Но какой прок от этого? Разные массивы можно хранить в разных адресных пространствах?
              UB ради UB, ограничивают полезные возможности.
              Ответить
              • >Разные массивы можно хранить в разных адресных пространствах?
                В borland c в реальном режиме были такие указатели которые лежали в разных сегментах
                Сравнивание их не имело никакого смысла
                Ответить
              • Для поддержки gc. Чтобы он мог без палева двигать объекты.
                Ответить
                • Если в рантайме объекты будут перемещаться сами собой, почти весь царский сишный код вмиг перестанет работать.
                  Ответить
      • Ну и зависимость всех этих битностей и т.п. от фазы луны и положения звёзд - в полнолуние байт 13 бит, к примеру. Чтоб не хардкодили размеры.
        Ответить
        • …А всем недовольным комментаторы с Хабра будут писать, что это низкоуровневый язык и тут так принято, а кому это не нравится — тот быдло тупое!
          Ответить
          • Прикрывайся сковородочкой.
            Ответить
          • Надо ещё сделать процессор, на котором вся эта хуйня достаточно оптимально работает.
            Ответить
      • >> который полностью соответствует стандарту
        >> но при этом реализует все как попало

        Итальянская забастовка!

        https://ru.wikipedia.org/wiki/Итальянская_забастовка
        Ответить
      • > но при этом реализует все как попало - 7 бит в байте

        Не выйдет, UCHAR_MAX нельзя будет записать. Он должен быть минимум 255.
        Ответить
    • Kakou-mo_nemyx!!!!!!!!!!111
      Ответить

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