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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Гибкий размер типа данных
jcxz
сообщение Jul 31 2015, 10:45
Сообщение #16


Гуру
******

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



Цитата(Golikov A. @ Jul 31 2015, 14:22) *
как я понимаю все метания автора не выделить памяти больше чем надо, А то так все можно было лонгами покрыть и всех делов....

Да, именно так. Имеется программа, в которой множество массивов структур, и массивов массивов структур. Многие члены этих структур - счётчики количества неких событий
(разного типа событий, для каждого определён максимальный диапазон счётчика). Другие члены этих структур - индексы, указывающие на элементы других массивов
(перекрёстные ссылки между массивами). Также есть ещё связные списки, в членах которых тоже есть индексы для перекрёстного связывания.
Заранее точно не известны максимальные размерности для каждого из этих счётчиков (и соответственно индексов).
Есть ещё кольцевые буфера, сложные, с многопозиционными указателями записи, позиции обработчика1 кольца, ..., позиции обработчикаN кольца, чтения (указатели - тоже индексы,
не указатели на память (для экономии размера)). Макс. кол-во элементов кольцевых очередей тоже задаётся дефайнами. И тоже потом может быть изменено.
Соответственно - размер этих массивов и кольцевых буферов будет сильно зависеть от размерности типов, хранящих эти счётчики и индексы.
И если потом вдруг потребуется поменять пару дефайнов, неохота лазить по всему коду и править.

Да в принципе подобные типы данных встречаются частенько и в других программах, только не в таком количестве wink.gif И мне всегда хотелось придумать какой-то способ объявления.
Пока вижу два варианта решения:
1. Для каждого дефайна, задающего макс. значение счётчика событий, городить конструкцию из #if/#elif/#else/#endif
Но получается очень громоздко и трудночитаемо.
2. Реализовать средствами с++. Такое уже делал. Объявлял что-то типа:
#define flexType_subst(prefix, maxVal) class flex##prefix { \
u8 [(maxVal < 256) ? 1: (maxVal < 65536) ? 2: ... ]; };
#define flexType(maxVal) flexType_subst(#maxVal, maxVal)
Объявление переменной:
#define MAX_EVENTS 54
static flexType(MAX_EVENTS) x;
Перегружал в конструируемом классе операторы приведения к типу int и оператор присваивания типа int.
Всё работало.
Но при отладке оптимизация выключена и очень напрягает, что компилятор не хочет инлайнить операторы приведения типа/присваивания, даже когда указываешь явно inline.
С типом, созданным посредством препроцессора, ассемблерный код выглядит гораздо красивее wink.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 31 2015, 11:05
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Тяжелое ассемблерное детство...

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

Цитата
Почему именно так? Чем это лучше варианта с union

по мне как раз
Цитата
загаживание исходников явными приведениями

которое здорово дисциплинирует и лишний раз подтверждает что вы знаете к какому типу вы обращаетесь....


Цитата
А если надо хранить uint64_t, когда указатель на void занимает 32 бита?

ну так он указатель на данные, а не данные. Они должны лежать отдельно и правильно оформленными, ИМХО... но это вопрос архитектуры, для абстрактных задач часто можно подобрать пример, когда любая идея становиться злой утопией и наоборот....

Цитата
Объявление переменной:
#define MAX_EVENTS 54
static flexType(MAX_EVENTS) x;


хоть убейте не понимаю я разницы с объявлением

Код
typdef int8_t  Array1Type; // это в отдельном заголовке
Array1Type x;   // это в коде


меняется также в 1 месте, там где вы бы
54 заменили на 1000, смените
typdef int8_t Array1Type
на
typdef int16_t Array1Type.

только вы сохраните работающей функцию sizeof(Array1Type) в отличии от sizeof( flexType(MAX_EVENTS) );
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 31 2015, 11:17
Сообщение #18


Гуру
******

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



Цитата(SasaVitebsk @ Jul 31 2015, 13:51) *
typedef union
{
int8_t i8;
int16_t i16;
int32_t i32;
float f;
} variant_t;
Сколько будет выделено памяти?
Скорее всего будет выделено по максимуму.

Выделено будет конечно по максимальному члену. А моя цель - экономия ОЗУ.

Цитата(Golikov A. @ Jul 31 2015, 17:05) *
Код
typdef int8_t  Array1Type; // это в отдельном заголовке
Array1Type x;   // это в коде

меняется также в 1 месте, там где вы бы
54 заменили на 1000, смените
typdef int8_t Array1Type
на
typdef int16_t Array1Type.

Вот именно, что в двух местах: отдельно 54 на 1000 и отдельно потом int8_t на int16_t.
Я стараюсь строить код так, чтобы, если есть зависимые значения (b=f(a)), то чтобы при изменении #define a, значение b пересчитывалось компилятором по заданному выражению и не мной вручную.
Так же хотелось бы делать и для типов: я указываю его максимальный размер, а компилятор по этому размеру считает в переменной какого размера его выгоднее всего хранить.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 31 2015, 11:45
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а... ну теперь понятно

ну тогда вам надо просто написать 4 #if else и все
типов то всего
8, 16, 32, 64 бита

определяете
#define MAX_EVENTS 54

и через #if ....#else от значения MAX_EVENTS
определяете typdef или #define если тот закривляется

Код
#if MAX_EVENTS > 0x0FFFFFFFF
  #define my_type uint64_t
#else if MAX_EVENTS > 0x0FFFF
  #define my_type uint32_t
#else if MAX_EVENTS > 0x0FF
  #define my_type uint16_t
#else
  #define my_type uint8_t



этот громоздкий файл можно положить отдельно, он автоматом переобъявит типы и все получится как вы хотели, в программе тип будет всегда один и не изменный

my_type x;
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 31 2015, 12:42
Сообщение #20


Гуру
******

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



Цитата(Golikov A. @ Jul 31 2015, 14:45) *
и через #if ....#else от значения MAX_EVENTS
определяете typdef или #define если тот закривляется

Семён Семёныч! Почему-то мне это в голову не пришло. Респект a14.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2015, 06:03
Сообщение #21


Гуру
******

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



Цитата(Golikov A. @ Jul 31 2015, 17:45) *
и через #if ....#else от значения MAX_EVENTS
определяете typdef или #define если тот закривляется

Ну это понятно. Я о таком ещё в 16-м сообщении писал (вариант 1).
Вот если-бы си позволял конструкцию #if/#endif в макрос запихнуть! sad.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 1 2015, 07:09
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



тогда ну это не очень понятно wink.gif, макроса то никакого нет, в этом смысл....

более подробно
вам надо чтобы вы в 1 месте сменили MAX_EVENTS, а у вас все счетчики для его подсчета сами бы поменяли размерность.

делается через промежуточный дефайн

объявляете базовый дефайн
#define MAX_EVENTS 54


от этого дефайна объявляете тип

#if MAX_EVENTS ....
#define MyType int8_t
#else
#define MyType int16_t
и так далее...


а уже от этого типа объявляете счетчики
MyType Counter;


в результате, сменив MAX_EVENTS у вас автоматом смениться тип, то есть будет все как вы хотите, смена в одном месте, поменялись все типы...



эти подмены работают автоматически, вам их надо написать один раз, и запаковать в файл. Громоздко на самом деле не будет, там всего то 4 строчки по числу типов, просто надо сравнивать в нужном направлении, чтобы проверять одну границу. Ну в общем делайте как хотите sm.gif это реально решение и методами языка С
Go to the top of the page
 
+Quote Post

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

 


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


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