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

    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
    14. 14
    15. 15
    16. 16
    #include <stdio.h>
     
    #define BIG_ENDIAN 0
    #define LITTLE_ENDIAN 1
     
    int TestByteOrder() {
            short int word = 0x0001;
            char *b = (char *)&word;
            return (b[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
    }
     
    int main() {
            int r = TestByteOrder();
            printf("%s\n", r == LITTLE_ENDIAN ? "Little Endian" : "Big Endian");
            return r;
    }

    Игрушечная программа, проверяет порядковость байтов процессора ("endianness"); хотя изначально понятно что WinNT всегда "от младшего к старшему".
    Она безупречно правильная, но меня не устраивает ее размер. Ведь всё можно было бы уместить в две строки. (А еще лучше перевести на АСМ). Прошу знатоков поупражняться.

    Запостил: tmayh, 06 Октября 2019

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

    • показать все, что скрытоvanished
      Ответить
    • Уместил в две строки, проверь.
      #include <inttypes.h>
      int main() { volatile uint32_t i=0x01234567; printf("%s\n", (*((uint8_t*)(&i)) == 0x67) ? "Little Endian" : "Big Endian"); }

      http://ideone.com/doXV49

      Код не мой, я просто разместил объяву минифицировал.
      Ответить
    • >> хотя изначально понятно что WinNT всегда "от младшего к старшему"

      А давайте проверим это утверждение. Новые версии существуют под Intel x86 и под ARM (Windows RT). Старые версии ещё были под MIPS, PowerPC, DEC Alpha AXP, Intel Itanium.

      Процессоры MIPS, PowerPC, Alpha, Itanium, ARM могли работать в обоих режимах.

      «OS/2 and Windows NT for PowerPC ran the processor in little-endian mode while Solaris, AIX and Linux ran in big endian». Хотя был и порт «Дебиана» для режима little-endian.

      В Power PC 970, известном как G5, режим little-endian не реализовали.

      Итак, Windows NT реализовали для процессоров, которые либо little-endian (x86), а также для процессоров, которые умеют работать в обоих режимах (у ARM ещё бывают смешанные режимы). Есть подозрение, что компания Microsoft для упрощения разработки на всех платформах использовала один и тот же порядок байтов.

      Возможно, Вы правы, хотя официального подтверждения я не нашёл.

      Кстати, исходник не привязан к Windows NT, его можно скомпилировать и под другие операционные системы.
      Ответить
      • показать все, что скрытоvanished
        Ответить
        • Пользуюсь вроутером на MIPS под управлением микро-Linux.
          Пользуюсь мобильными устройствами на ARM под управлением разных систем.
          Пользуюсь устройствами на x86 под управлением Windows NT и иногда Linux.

          Я не знаю, приходилось ли сталкиваться с чем-то ещё, потому что не знаю, из чего сделаны другие электронные устройства.
          Ответить
    • > Она безупречно правильная
      Под PDP-11 будет неправильно работать.
      Ответить
      • Не только. У ARM до ARMv7 ещё был смешанный режим.
        Ответить
        • P.S. Кстати, разработчики «Андроида» хитрые: чтобы можно было одну и ту же нативную программу запускать на ARMv8, ARMv7, ARMv6, они выбрали little-endian, а little-endian у всех ARM один.
          Ответить
    • #include <stdint.h>
      #include <stdio.h>
      #include <malloc.h>
      
      enum {
          BIG_ENDIAN = 0x00010203,
          LITTLE_ENDIAN = 0x03020100,
          PDP_ENDIAN = 0x01000302
      };
      
      int get_byteorder(void)
      {
          const uint32_t i = 0x00010203;
          const uint8_t * const a = (uint8_t*)&i;
          return a[0] << 24 | a[1] << 16 | a[2] << 8 | a[3];
      }
      
      const char *get_byteorder_name(int byteorder)
      {
          static char s[sizeof("Unknow Endian: xxxxxxxx") + 1]; 
          switch (byteorder) {
              case BIG_ENDIAN: return "Big Endian";
              case LITTLE_ENDIAN: return "Little Endian";
              case PDP_ENDIAN: return "PDP Endian";
          }
          snprintf(s, sizeof(s), "Unknown Endian: %8x", byteorder);
          return s;
      }
      
      int main(void)
      {
          puts(get_byteorder_name(get_byteorder()));
          return 0;
      }
      Ответить
      • Кстати, если 18-ю строчку заменить на
        static char s[sizeof("Unknow Endian: xxxxxxxx")];
        то гцц ругается
        note: ‘snprintf’ output 25 bytes into a destination of size 24
             snprintf(s, sizeof(s), "Unknown Endian: %8x", byteorder);
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        а шлагнг молчит, хотя -Стена и -педантичные-ошибки.

        Именно поэтому я за "GCC".
        Ответить
      • В ARM BE-32 тоже какая-то запутанная питушня.
        Ответить
    • #include <stdio.h>
      #include <stdint.h>
      
      void main() {
      	uint16_t w = 255;
      	unsigned char *c = (unsigned char*)&w;
      	printf((c[0] == 255) ? "LE" : "BE");
      }


      мартышка так проверяет
      Ответить
      • Тебя, видимо, воспитали мартышки, и ты не знаешь, что ты шимпанзе?
        Ответить
    • https://govnokod.ru/15707
      Ответить
    • показать все, что скрытоКуд-куда-ат!-Куд-куда-ат! Куд-куда-ат!-Куд-куда-ат! Куд-куда-ат!-Куд-куда-ат!
      Ответить

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