реклама на сайте
подробности

 
 
> Гибкий размер типа данных
jcxz
сообщение Jul 29 2015, 05:33
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Не знаю в какой раздел форума написать, пишу сюда.
Хочется иметь тип данных гибкого размера, с размером, зависящим от значения некоего define.
Т.е. - например:
VAL_X_MAX - максимальное значение, которое может принимать некоторая переменная x.
если: 0 <= VAL_X_MAX < 256, то переменная x должна объявиться размером == байт;
если: 256 <= VAL_X_MAX < 32768, то переменная x должна объявиться размером == 16 бит;
и т.п.

Попытался сделать что-то типа:
Код
#define u8pVOID  u8
#define u16pVOID u16
#define u32pVOID u32
#define u64pVOID u64
#define s8pVOID  s8
#define s16pVOID s16
#define s32pVOID s32
#define s64pVOID s64
#define flexType_subst3(x) x
#define flexType_subst2(x) flexType_subst3(x)
#define flexType_subst(prefix, maxVal, suffix, ...) \
  flexType_subst2(                                  \
  ((maxVal) < B8) ? prefix##8##suffix:   \
  ((maxVal) < B16) ? prefix##16##suffix: \
  ((maxVal) < B32) ? prefix##32##suffix: prefix##64##suffix))
#define flexType(...) flexType_subst(__VA_ARGS__, pVOID)

чтобы можно было объявить переменную:
static flexType(u, 54) x;
где: 54 - макс. значение которое может принимать x
Но препроцессор упорно не хочет полностью вычислять выражение и доводить его до u8 crying.gif
останавливается на:
static ((54) < 0x00000100) ? u8: ((54) < 0x00010000) ? u16: ((54) < B32) ? u32: u64) x;

Интересно - есть-ли какие другие способы?
Конечно можно с помощью #if/#else/#endif, но эту конструкцию придётся городить для каждой такой переменной, а хотелось бы 1 раз определить макрос, а потом его использовать, записывая объявления кратко.

ЗЫ: Компилятор - IAR for ARM 7.20.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
scifi
сообщение Jul 29 2015, 05:48
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 29 2015, 08:33) *
чтобы можно было объявить переменную:
static flexType(u, 54) x;

Что за глупости? Только безумец не знает, что число 54 можно хранить в 8-битной переменной. Зачем для этого хитрый макрос?
Ну а если в порядке изучения языка Си в плане возможностей препроцессора, то нет, ничего не получится. Читайте книжки, в которых написано, как работает препроцессор. Там всё просто и понятно.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 29 2015, 07:05
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 29 2015, 11:48) *
Что за глупости? Только безумец не знает, что число 54 можно хранить в 8-битной переменной. Зачем для этого хитрый макрос?

Блин...
Код
#define MAX_EVENTS 54  //кол-во обрабатываемых событий
static flexType(u, MAX_EVENTS) x;
Так понятнее?
Чтобы потом, если вдруг потребуется изменить кол-во обрабатываемых событий, не потребовалось лазить по всему коду и менять размер всех переменных, размерность которых зависит от MAX_EVENTS.
И конечно имеются массивы типа flexType(u, MAX_EVENTS)
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 29 2015, 07:15
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 29 2015, 10:05) *
Чтобы потом, если вдруг потребуется изменить кол-во обрабатываемых событий, не потребовалось лазить по всему коду и менять размер всех переменных, размерность которых зависит от MAX_EVENTS.

Это всё достигается стандартными средствами. Для того чтобы не требовалось лазить по коду и менять, придуманы макросы и typedefы:
Код
typedef uint8_t event_type;

Если хочется минимальный размер типа, то достаточно добавить assert:
Код
assert_static(MAX_EVENT < (1UL << (8 * sizeof(event_type)))); // проверить, что размер типа достаточный
assert_static(MAX_EVENT >= (1UL << (8 * (sizeof(event_type) / 2)))); // проверить, что размер не избыточный

Если сработает assert, то достаточно будет скорректировать код в одном месте (typedef). Ничего страшного, руки не отвалятся.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 29 2015, 08:05
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 29 2015, 13:15) *
Если хочется минимальный размер типа, то достаточно добавить assert:
Код
assert_static(MAX_EVENT < (1UL << (8 * sizeof(event_type)))); // проверить, что размер типа достаточный
assert_static(MAX_EVENT >= (1UL << (8 * (sizeof(event_type) / 2)))); // проверить, что размер не избыточный

Если сработает assert, то достаточно будет скорректировать код в одном месте (typedef). Ничего страшного, руки не отвалятся.

Ну да, можно так. Но хочется чтобы всё автоматом собиралось само. У меня есть сейчас массив структур, в котором несколько элементов могут хранить некие значения. Максимальное значение для
каждого из них задаётся соответствующим define. Все они около 100..200 сейчас. Но завтра возможно придётся один или несколько из них сделать больше.

PS: Из реальных вариантов пока вижу только кувалдой в лоб - прописать массив:
Код
#define FLEX0 u8
#define FLEX1 u8
#define FLEX2 u8
...
#define FLEX255 u8
#define FLEX256 u16
#define FLEX257 u16
...
#define FLEX65535 u16
#define flexType_subst(maxVal) FLEX##maxVal
#define flexType(maxVal) flexType_subst(maxVal)

biggrin.gif
На 8 и 16 бит хватит. Если компилятор потянет такое кол-во констант lol.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- jcxz   Гибкий размер типа данных   Jul 29 2015, 05:33
|- - AHTOXA   На c++ это делается просто. Вот ссылка по теме. (Т...   Jul 29 2015, 10:01
- - dxp   На плюсах можно копать в сторону templates и trait...   Jul 29 2015, 13:59
|- - jcxz   Цитата(dxp @ Jul 29 2015, 19:59) На плюса...   Jul 31 2015, 02:36
- - Golikov A.   напишите свой препроцессор, который перед билдом б...   Jul 31 2015, 05:36
|- - jcxz   Цитата(Golikov A. @ Jul 31 2015, 11:36) н...   Jul 31 2015, 10:14
- - SasaVitebsk   При написании меню мне понадобилось статически мен...   Jul 31 2015, 05:46
- - Golikov A.   А что кстати дает такой тип кроме путаницы и зоопа...   Jul 31 2015, 06:45
|- - SasaVitebsk   Цитата(Golikov A. @ Jul 31 2015, 09:45) ч...   Jul 31 2015, 07:51
|- - jcxz   Цитата(SasaVitebsk @ Jul 31 2015, 13:51) ...   Jul 31 2015, 11:17
- - Golikov A.   понятно, ну тогда можно и так char AbstractData[8...   Jul 31 2015, 08:22
|- - Сергей Борщ   Цитата(Golikov A. @ Jul 31 2015, 11:22) п...   Jul 31 2015, 10:28
|- - jcxz   Цитата(Golikov A. @ Jul 31 2015, 14:22) к...   Jul 31 2015, 10:45
- - Golikov A.   ЦитатаТяжелое ассемблерное детство... Union будет ...   Jul 31 2015, 11:05
- - Golikov A.   а... ну теперь понятно ну тогда вам надо просто ...   Jul 31 2015, 11:45
|- - scifi   Цитата(Golikov A. @ Jul 31 2015, 14:45) и...   Jul 31 2015, 12:42
|- - jcxz   Цитата(Golikov A. @ Jul 31 2015, 17:45) и...   Aug 1 2015, 06:03
- - Golikov A.   тогда ну это не очень понятно , макроса то никаког...   Aug 1 2015, 07:09


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 01:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016