|
Локальные переменные. |
|
|
|
Jan 20 2015, 11:33
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Прочитал следующее в ARM System Developer's Guide. Цитата ARMv4-based processors can efficiently load and store 8-, 16-, and 32-bit data. However, most ARM data processing operations are 32-bit only. For this reason, you should use a 32-bit datatype, int or long, for local variables wherever possible. Avoid using char and short as local variable types, even if you are manipulating an 8- or 16-bit value. The one exception is when you want wrap-around to occur. И переделал все локальные переменные на uint32_t. Вопрос - как я понимаю это касается и аргументов передаваемых в функцию?
|
|
|
|
|
 |
Ответов
|
Jan 20 2015, 11:50
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(ViKo @ Jan 20 2015, 17:36)  Да. И возвращаемых значений тоже. Не касается это лишь управляющих структур, массивов, которые используются в программе. Чтобы место экономить. Ну а вот например Код uint32_t MessageChecksum(unsigned char *p, uint32_t len) { uint32_t csum = 0; while (len) { csum+=(*p)&0xFF; p++; len--; } return csum; } тут у меня unsigned char потому что это касается UART я передаю данные 8 бит. или все равно привести к uint32_t? uint_fastXX_t это если я захочу перенести код на AVR
|
|
|
|
|
Jan 20 2015, 17:26
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Jenya7 @ Jan 20 2015, 13:50)  тут у меня unsigned char потому что это касается UART я передаю данные 8 бит. А складываете вы их всегда в массив unsigned char? И берете всегда из массива unsigned char? Эта функция по идее считает CRC чего угодно. Вот и передавать ей надо "указатель на что угодно", т.е void const *, а внутри заводите уже временную переменную типа "указатель на байт" и присваивайте ей переданный указатель с явным приведением типа. Это позволит написать Код typedef struct { ...... } message_t;
message_t Message = {.....}; Checksum = MessageChecksum(&Message, sizeof(Message)); избежав явного приведения типа (unsigned char const *)&Message в большинстве точек вызова. А это разгружает исходник, делая его более легкочитаемым. Цитата(Jenya7 @ Jan 20 2015, 13:50)  или все равно привести к uint32_t? Привести к uint32_t что? Вы передает указатель. От того, на какой тип этот указатель указывает его размер не изменится. А вот если размер ваших сообщений по спецификации протокола не может превышать 255 или 65535 байт, то параметр len имеет смысл делать uint_fast8_t или uint_fast16_t. Цитата(Jenya7 @ Jan 20 2015, 13:50)  uint_fastXX_t это если я захочу перенести код на AVR  Не обязательно AVR. Вы можете захотеть его перенести на 16- 32- или 64-битную архитектуру, которая умеет делать арифметику с числами 8- или 16-битной разрядности (MSP430 или персоналку). И чтобы этот код и на другой архитектуре тоже был оптимальным без перелопачивания тысяч строк кода, имеет смысл сразу писать его грамотно (или хотя бы стараться писать грамотно).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 20 2015, 19:05
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Сергей Борщ @ Jan 20 2015, 23:26)  А складываете вы их всегда в массив unsigned char? И берете всегда из массива unsigned char? Эта функция по идее считает CRC чего угодно. Вот и передавать ей надо "указатель на что угодно", т.е void const *, а внутри заводите уже временную переменную типа "указатель на байт" и присваивайте ей переданный указатель с явным приведением типа. Это позволит написать Код typedef struct { ...... } message_t;
message_t Message = {.....}; Checksum = MessageChecksum(&Message, sizeof(Message)); избежав явного приведения типа (unsigned char const *)&Message в большинстве точек вызова. А это разгружает исходник, делая его более легкочитаемым. а struct как определить? typedef struct {unsigned char paket[BUF_SIZE]} message_t; ?
|
|
|
|
|
Jan 20 2015, 19:25
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Jenya7 @ Jan 21 2015, 00:05)  а struct как определить? typedef struct {unsigned char paket[BUF_SIZE]} message_t; ? Да как вам надо, так и определите. Суть в том, что если функция подсчёта crc принимает в качестве аргумента указатель на void, то при передаче любого другого указателя в эту функцию к нему не надо применять приведение типа. Поясню. Пусть у нас есть две функции подсчёта crc: Код uint32_t crc1(const void * buf, size_t size); uint32_t crc2(const uint8_t * buf, size_t size); И пусть мы хотим посчитать crc следующих объектов: Код int intArray[10]; uint8_t byteBuf[20]; struct config_t { uint32_t serial; uint32_t baudrate; }config; Так вот. Используя первую функцию, мы можем написать: Код crc1(intArray, 10*sizeof(int)); crc1(byteBuf, 20); crc1(&config, sizeof(config)); Для второй функции нам в двух случаях придётся делать приведение типа: Код crc2((const uint8_t *)intArray, 10*sizeof(int)); crc2((const uint8_t *)&config, sizeof(config)); Что касаемо добавления const к неизменяемым параметрам. Это очень полезное правило. Во-первых, это помогает компилятору в плане оптимизации. (Он имеет право не перечитывать такие объекты после вызова функции) И, во-вторых, это помогает использующему эту функцию программисту быстрее понять логику работы функции. (И не надо думать об этом программисте, как о каком-то абстрактном человеке (и пусть это будет "его ответственность"). В подавляющем большинстве случаев этим программистом будете вы  ) Пример: void * memcpy (void * destination, const void * source, size_t num); (Если вы случайно перепутаете параметры, то есть шанс, что компилятор вас поправит).
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 20 2015, 21:12
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(AHTOXA @ Jan 20 2015, 22:25)  Используя первую функцию, мы можем написать: Код crc1(intArray, 10*sizeof(int)); crc1(byteBuf, 20); crc1(&config, sizeof(config)); Можем написать проще. Код crc1(intArray, sizeof(intArray); crc1(byteBuf, sizeof(byteBuf); crc1(&config, sizeof(config);
|
|
|
|
Сообщений в этой теме
Jenya7 Локальные переменные. Jan 20 2015, 11:33 Сергей Борщ А чтобы код оставался более-менее оптимальным при ... Jan 20 2015, 11:42  ViKo Цитата(Jenya7 @ Jan 20 2015, 14:50) тут у... Jan 20 2015, 11:56  CrimsonPig Цитата(Jenya7 @ Jan 20 2015, 11:50) Ну а ... Jan 20 2015, 12:08   Jenya7 Цитата(CrimsonPig @ Jan 20 2015, 18:08) Е... Jan 20 2015, 12:15    CrimsonPig Цитата(Jenya7 @ Jan 20 2015, 12:15) это p... Jan 20 2015, 12:28     Jenya7 Цитата(CrimsonPig @ Jan 20 2015, 18:28) 1... Jan 20 2015, 12:39      CrimsonPig Цитата(Jenya7 @ Jan 20 2015, 12:39) обрат... Jan 20 2015, 12:47       Jenya7 Цитата(CrimsonPig @ Jan 20 2015, 18:47) К... Jan 20 2015, 12:58        CrimsonPig Цитата(Jenya7 @ Jan 20 2015, 12:58) нет и... Jan 20 2015, 13:39   CrimsonPig Цитата(Сергей Борщ @ Jan 20 2015, 17:26) ... Jan 20 2015, 17:40    AHTOXA Цитата(CrimsonPig @ Jan 20 2015, 22:40) v... Jan 20 2015, 18:19     CrimsonPig Цитата(AHTOXA @ Jan 20 2015, 18:19) У Се... Jan 20 2015, 18:27    Сергей Борщ Цитата(Jenya7 @ Jan 20 2015, 21:05) а str... Jan 21 2015, 07:10 Jenya7 спасибо. придется засучить рукава. этож тысячи стр... Jan 20 2015, 12:06 Jenya7 спасибо. узнал много интересного. только вот Серг... Jan 21 2015, 07:24 Сергей Борщ Цитата(Jenya7 @ Jan 21 2015, 09:24) а в т... Jan 21 2015, 07:56
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|