Перейти к содержанию
    

17 минут назад, jcxz сказал:

Спасибо. Буду иметь в виду.

в с11++ много вкусного.... тот же For-цикл по коллекции. вам такому специалисту как вы, должно быть стыдно не знать на пороге 2019 про тип auto. Может пора начать учить с11++ ознакомиться с С++11, хотя бы на вики.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Господа, давайте без перехода на личности :(

А для решения проблемы разрядности целочисленных типов люди собрались и ввели в стандарт stdint.h Кто этим не пользуется, тот ССЗБ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 минут назад, juvf сказал:

в с11++ много вкусного.... тот же For-цикл по коллекции. вам такому специалисту как вы, должно быть стыдно не знать на пороге 2019 про тип auto. Может пора начать учить с11++ ознакомиться с С++11, хотя бы на вики.

Я вроде вообще к вам не обращался. Своё мнение о вас я уже составил. И о вашем уровне "компетенции".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

8 часов назад, jcxz сказал:

В указанных случаях, например на ARM (и на других архитектурах) следует использовать int (или unsigned int). всякие uint8_t будут приводить к неоптимальному коду.

каким образом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, razrab83 сказал:

каким образом?

Дополнительными командами приведения типа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как бы очевидно, что использование типов данных по разрядности совпадающих с разрядностью процессора ведёт к исключению накладных расходов на приведение типов. Для 8-биток это (u)int8_t, так как int будет 16-битный.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

Дополнительными командами приведения типа.

что, где и к чему должно быть приведено?

 

собрал for( int/uint8_t  i = 0; i< 10; i++) с int и c uint8_t. На разных архитектурах (8 и 32 бита), разными компиляторами для каждой архитектуры, без оптимизации, с оптимизацией..... глянул дизасм.... пошагал.... код что с int, что с uint8_t получился одинаковый.... не то что по размеру или по скорости... получился одинаковый в точности до каждой машинной команды.

Изменено пользователем razrab83

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проще всего эти команды обнаружить передавая в функцию и возвращая из функции на ARM int8_t и int32_t в разных сочетаниях. 

 

Вот смотри, простейший пример. Всё чисто.

//    int32_t foo(int32_t x)
//    {
//        return x*2;
        LSLS     R0,R0,#+1
        BX       LR               ;; return
//    }

//        volatile uint32_t a=10;
        MOVS     R0,#+10
        STR      R0,[SP, #+0]
//        volatile uint32_t b = foo(a);
        LDR      R1,[SP, #+0]
        LSLS     R1,R1,#+1
        STR      R1,[SP, #+0]

А теперь поменяем возвращаемый тип.

//     int8_t foo(int32_t x)
//     {
//        return x*2;
        LSLS     R0,R0,#+25
        ASRS     R0,R0,#+24
        BX       LR               ;; return
//     }

//        volatile uint32_t a=10;
        MOVS     R0,#+10
        STR      R0,[SP, #+0]
//        volatile uint32_t b = foo(a);
        LDR      R1,[SP, #+0]
        LSLS     R0,R1,#+1
        SXTB     R0,R0
        STR      R0,[SP, #+0]

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, razrab83 сказал:

что, где и к чему должно быть приведено?

for (uint8_t i = 0; i < 10; i++) {...}

10 - по дефолту тип int, i - uint8_t (меньшего размера). Соответственно один операнд (меньшего размера) будет приведён к типу другого (большего размера и другой разрядности).

См. описание языка си, раздел правил приведения типов операндов внутри выражений.

Цитата

собрал for( int/uint8_t  i = 0; i< 10; i++) с int и c uint8_t. На разных архитектурах (8 и 32 бита), разными компиляторами для каждой архитектуры, без оптимизации, с оптимизацией..... глянул дизасм.... пошагал.... код что с int, что с uint8_t получился одинаковый.... не то что по размеру или по скорости... получился одинаковый в точности до каждой машинной команды.

Значит - данный компилятор в данном конкретном случае (с данными ключами) данный конкретный пример уже оптимизирует, приводя сразу типы операндов.

Вот что сказал IAR_7.80.4 for ARM (оптимизация - LOW):

 

Спойлер

    428          void zf(void const *data, uint)
    429          {
    430            u8 const *p = (u8 const *)data;
    431            for (u8 i = 0; i < 10; i++) *(u8 *)&CRC.DR = *p++;
   \                     _Z2zfPKvj: (+1)
   \   00000000   0x2100             MOVS     R1,#+0
   \   00000002   0xE004             B.N      ??zf_0
   \                     ??zf_1: (+1)
   \   00000004   0x7802             LDRB     R2,[R0, #+0]
   \   00000006   0x....             LDR.N    R3,??DataTable14_39  ;; 0x40023000
   \   00000008   0x701A             STRB     R2,[R3, #+0]
   \   0000000A   0x1C40             ADDS     R0,R0,#+1
   \   0000000C   0x1C49             ADDS     R1,R1,#+1
   \                     ??zf_0: (+1)
   \   0000000E   0xB2C9             UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
   \   00000010   0x290A             CMP      R1,#+10
   \   00000012   0xDBF7             BLT.N    ??zf_1
    432          }
   \   00000014   0x4770             BX       LR               ;; return

 

Команда UXTB - это как раз и есть команда беззнакового расширения. Без которой можно обойтись, применив uint i.

Как справедливо заметил VladislavS приведения типа чаще можно увидеть при передаче аргументов функций не основной разрядности (разрядность != разрядности регистров CPU). Возьмите любой код, насыщенный всякими uint8_t/uint16_t в аргументах и локальных переменных функций, скомпилируйте его на 32-битной архитектуре, и увидите кучу UXTB/UXTH/SXTB/SXTH. Например этим сильно грешат исходники uCOS-II - всяких INT8U/INT16U в аргументах там полно.

То же самое касается и других архитектур (STM8 - в том числе), когда передаются аргументы в функцию или используются как локальные, переменные не основной разрядности. В STM8 предпочтительно использовать 8бит, если не лезет - 16бит, и только потом уже - 32бита.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

9 часов назад, VladislavS сказал:

Вот смотри, простейший пример. Всё чисто. 


     int8_t foo(int32_t x)
     {
        return x*2;
     }

 

Где же тут чисто? У вас foo возвращает int8_t, а вы в ретурн суёте int32_t. Тут неявное преобразование на уровне си/с++

return (int8_t)(x*2);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы хотели посмотреть команды приведения типов - я вам их показал. Они будут неизбежно появляться там где разрядность данных не совпадает с разрядностью процессора. 

 

Вот функция без приведения типов

//     int8_t foo(int8_t x)
//     {
//         return x-20;
         SUBS     R0,R0,#+20
         SXTB     R0,R0
         BX       LR               ;; return
//     }

Если бы разрядность процессора совпадала с данными, то всё было бы проще

//     int32_t foo(int32_t x)
//     {
//        return x-20;
        SUBS     R0,R0,#+20
        BX       LR               ;; return
//     }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

uint_fast8_t

 

//     uint_fast8_t foo(uint_fast8_t x)
//     {
//        return x-20;
        SUBS     R0,R0,#+20
        BX       LR               ;; return
//     }

ps акказываица, не я один до такого дожил. вот что думают об этом в Micrium руководстве по портированию uc/os

Цитата

Поскольку различные микропроцессоры имеют различную длину слова, портация
μC/OS-II включает ряд определений типов для гарантии переносимости. В
особенности, коды μC/OS-II никогда не используют типы данных С short, int и long,
потому что они не переносимые. Вместо этого, определены целочисленные типы
данных, которые и переносимы, и интуитивно понятны

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да ну на. Даже боюсь сравнить результат

int8_t foo(int8_t x)
{
  if((x+127)>0) return 1; else return 0;
}

или 

int_fast8_t foo(int_fast8_t x)
{
  if((x+127)>0) return 1; else return 0;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 90       int_fast8_t foo(int_fast8_t x)
          foo:
08004cb4:   foo:
            MOVS      R1, R0
 92         if((x+127)>0) return 1; else return 0;
08004cb6:   ADDS.W    R0, R1, #127            ; 0x7f
08004cba:   CMP       R0, #1
08004cbc:   BLT.N     0x8004cc2
08004cbe:   MOVS      R0, #1
08004cc0:   B.N       0x8004cc4
08004cc2:   MOVS      R0, #0
08004cc4:   BX        LR

 

90       int foo(int x)
          foo:
08004cb4:   foo:
            MOVS      R1, R0
 92         if((x+127)>0) return 1; else return 0;
08004cb6:   ADDS.W    R0, R1, #127            ; 0x7f
08004cba:   CMP       R0, #1
08004cbc:   BLT.N     0x8004cc2
08004cbe:   MOVS      R0, #1
08004cc0:   B.N       0x8004cc4
08004cc2:   MOVS      R0, #0
08004cc4:   BX        LR

ARM, IAR, без оптимизации.

Я тоже считаю, что лучше применять типы данных соответствующие описываемым ими сущностям. Код должен быть понятный и наглядный (а часто ещё и легко переносимый). Что касательно избыточности - современные компиляторы хорошо умеют справляются с "чужой" разрядностью. всякие оптимизаторы, int_fastN_t, intN_t, int_leastN_t ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, razrab83 сказал:

ARM, IAR, без оптимизации.

Как и где определён этот самый uint_fast8_t? Мой IAR_7.80.4 его не знает. И в uCOS-II его тоже нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...