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

 
 
> Поиск по массиву в compile time на С
amaora
сообщение May 3 2018, 11:54
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Есть массив регистров, ссылки на переменные с именами и некоторыми параметрами, для удобного доступа по разным интерфейсам и конфигурирования устройства. Допустим вот так объявленный,

Код
typedef struct {

    const char        *sym;

    const char        *fmt;
    int            mode;

    union {

        float        *f;
        int        *i;
    }
    link;

    void            (* proc) (const void *reg, void *lval, const void *rval);
}
reg_t;

#define REG_E(link, extra, unit, fmt, mode, proc)    { #link extra "\0" unit, fmt, mode, \
                            { (void *) &link }, (void *) proc }

#define REG(link, unit, fmt, mode, proc)    REG_E(link, "", unit, fmt, mode, proc)

const reg_t        regfile[] = {

    REG(hal.USART_baud_rate,        "",    "%i",    REG_CONFIG, NULL),
    REG(hal.PWM_freq_hz,            "Hz",    "%i",    REG_CONFIG, NULL),
    REG(hal.PWM_dead_time_ns,        "ns",    "%i",    REG_CONFIG, NULL),
    REG(hal.ADC_reference_voltage,        "V",    "%3f",    REG_CONFIG, NULL),
    REG(hal.ADC_current_shunt_resistance,    "Ohm",    "%4e",    REG_CONFIG, NULL),
...
    REG(pm.probe_speed_ramp,    "rad/s",    "%2f",    REG_CONFIG, NULL),
    REG_E(pm.probe_speed_ramp, "_rpm",    "rpm",    "%2f",    REG_NORMAL, &reg_proc_rpm),
...


Регистры адресуются по именам или по номерам. Имена достаточно постоянны, а номера могут изменяться в следующих версиях. В этом проблема, нельзя в коде просто взять ссылку на регистр по номеру regfile[n], номер может измениться. Искать по имени в compile time слишком сложно, средствами C и препроцессора не обойтись. По адресам переменных нельзя, они могут повторятся. Какие еще варианты?

Сейчас думаю, генерировать из объявления массив макросов вида #define REG_hal_USART_baud_rate 0, но здесь тоже много проблем, надо как-то "спасать" недопустимые символы (точка и др.).

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

Спасибо.


Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
DASM
сообщение Aug 13 2018, 17:36
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Вот чтобы не плодить тем, возник вопрос. Есть структура в вижуал студио. Ее поля имеют тип enum. Эта структура необходима для сериализации по юарту. Заниматься разборкой каждого поля, или, особо извращённым способом, делать каждое поле методом, пишущим себя в выходной поток нет ни желания, ни необходимости. Поэтому аккуратно подставив pragma pack попробовал. Все замечательно, но вот студия считает, что поля типа моего enum имеют тип int, обьявление у меня простое, по шариковски, typedef emum {Eins ,Zwei, Polizei} eMytype; А вот GCC решил, что такой тип прекрасно ложится в чар, на что имеет право
Цитата
Each enumeration defines a type that is different from all other types. Each enumeration also has an underlying type. The underlying type can be explicitly specified using enum-base; if not explicitly specified, the underlying type of a scoped enumeration type is int. In these cases, the underlying type is said to be fixed. Following the closing brace of an num-specifier, each enumerator has the type of its enumeration.
(хотя мой инглиш слаб, и может и не имеет). Теперь мысли что делать. В с++ с типами строже, отказываться от типа энум не хочу, там это ошибка, причем полезная. Можно сделать как typedef emum {Eins ,Zwei, Polizei, empty = 0xffffff}, в Гцц, тогда он сделает энумы интом, но это тоже так себе идея, тем более скорее хотелось бы пыл студии усмирить на предмет делать все это интом. Третий вариант в студии enum class eMytype : char {Eins ,Zwei, Polizei} сделать, но тогда не совсем понял как юзать старый трюк в С с " {Eins ,Zwei, Polize, max_enum_elents}, max_enum_elents будет строго типизировано и пробежаться по его его варинтам вплоть до него "по индексу" не выйдет.

Цитата(Nixon @ Aug 13 2018, 16:58) *
Для доступа по индексу можно так сделать
Код
enum VARIABLES {
    VAR1,
    VAR2,
    ...
    VARN,
    VAR_MAX
};
описание списка переменных
Код
const TVAR VarArray[VAR_MAX] = {
    [VAR1] = <тут ваша реализация>,
    [VAR2] = <тут ваша реализация>,
    ...
    [VARN] = <тут ваша реализация>
};
собственно ваш реестр инициализации.
Обращение к реестру можно делать по индексу (0-N) или по имени (VAR1-VARN).

Симпатично, жаль это since C99, поэтому не так много где описано и использовано. Буду знать.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 13 2018, 18:31
Сообщение #3


Гуру
******

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



QUOTE (DASM @ Aug 13 2018, 20:36) *
max_enum_elents будет строго типизировано и пробежаться по его его варинтам вплоть до него "по индексу" не выйдет.
Явное приведение типа все еще работает. for(uint_fast8_t i = 0;i < uint_fast8_t(eMytype::max_enum_elents); ++i)/
QUOTE (DASM @ Aug 13 2018, 20:36) *
Симпатично, жаль это since C99
18 лет, уже не девочка...


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 13 2018, 18:37
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Сергей Борщ @ Aug 13 2018, 21:31) *
Явное приведение типа все еще работает. for(uint_fast8_t i = 0;i < uint_fast8_t(eMytype::max_enum_elents); ++i)/
18 лет, уже не девочка...

да оно и неявно сработает, и в этом случае без enum class "eMytype::max_enum_elents" будет лишним, но нехорошо. Ладно, пусть нехорошо, pragma pack тоже совсем нехорошо. Но как enum сделать гарантированно char ами?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 13 2018, 19:47
Сообщение #5


Гуру
******

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



QUOTE (DASM @ Aug 13 2018, 21:37) *
да оно и неявно сработает, и в этом случае без enum class "eMytype::max_enum_elents" будет лишним
Неявно сработает только в случае простого enum. В случае enum class нужно явное приведение и "eMytype::max_enum_elents" тоже будет нужно.
QUOTE (DASM @ Aug 13 2018, 21:37) *
Но как enum сделать гарантированно char ами?
enum class eMytype : uint8_t {}.

И еще: char, signed char и unsigned char - три разных типа, поэтому "голый" char нужно использовать только для хранения символов. Для чисел нужно использовать signed char и unsigned char, а еще лучше (u)uint8_t. Если бы у вас был enum eMytype { '1', '2', '3' } - вот тогда бы я к char не придирался.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 13 2018, 20:08
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Сергей Борщ @ Aug 13 2018, 22:47) *
Неявно сработает только в случае простого enum. В случае enum class нужно явное приведение и "eMytype::max_enum_elents" тоже будет нужно.
enum class eMytype : uint8_t {}.

И еще: char, signed char и unsigned char - три разных типа, поэтому "голый" char нужно использовать только для хранения символов. Для чисел нужно использовать signed char и unsigned char, а еще лучше (u)uint8_t. Если бы у вас был enum eMytype { '1', '2', '3' } - вот тогда бы я к char не придирался.

Какие придирки? Так я и спрашиваю, как сделать перечисление, где каждый элемент это char? Выше выяснили, что так вот просто через enum компиляторонезависимо не выйдет. Завтра поиграю с юнионом по совету.


Цитата(Forger @ Aug 13 2018, 22:49) *
Command - НЕ глобальная переменная, а статическая константа, которую, кстати, надо будет сделать constexpr....
Вообще, в данном примере показан бут-загручик (!) в одном из старых проектов, а эта структура Command используется прямо внутри соотв. cpp файла.
Сам набор эти команд (Command) имеет смысл делать видимым только внутри этого модуля (в данном случае он называется Communication).
Чтобы не загромождать соотв hpp файл никому не нужным снаружи этим набором команд, то они просто добавлены внутри соотв. cpp файла и им приписано static.
По сути эта const struct - замена enum, видимая только внутри cpp файла, но позволяющая более легко читать текст, благодаря разбиения на поля и подструктуры.

Впрочем, в данный момент, глядя на эти исходники, некоторые мелочи я бы сделал иначе. ...
Но суть не в этом, а в том, что пример я привел для того, чтобы показать как можно обойтись без enion вообще.

Да не замена это. Энум нигде не хранится, просто объявление. Можно сделать его на пару миилиардов элементов, а при использовании поле его займет 4 байта. С const struct несколько не то. Надо ещё подумать
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 13 2018, 22:49
Сообщение #7


Гуру
******

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



QUOTE (DASM @ Aug 13 2018, 23:08) *
Выше выяснили, что так вот просто через enum компиляторонезависимо не выйдет.
Я устал в который раз повторять: enum class eMyenum : char { t1, y2, t3}. В Стандарте с 11-го года. Можете не верить. Пробуйте черех union.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 14 2018, 02:53
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Сергей Борщ @ Aug 14 2018, 01:49) *
Я устал в который раз повторять: enum class eMyenum : char { t1, y2, t3}. В Стандарте с 11-го года. Можете не верить. Пробуйте черех union.

А я этот вариант написал в самом своем вопросе. Только вот малоудобность его покажу, когда доберусь компа часа через два
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- amaora   Поиск по массиву в compile time на С   May 3 2018, 11:54
- - Kabdim   А зачем так сделано? Выглядит как кусок для внешне...   May 3 2018, 12:09
- - Forger   Масло-масляное. Ваш некий реестр (я так понял по н...   May 3 2018, 12:15
|- - x736C   Цитата(Forger @ May 3 2018, 15:15) зы. А ...   May 3 2018, 14:01
||- - Forger   Цитата(x736C @ May 3 2018, 17:01) Как при...   May 3 2018, 14:42
|- - jcxz   Цитата(Forger @ May 3 2018, 15:15) В свои...   May 5 2018, 09:33
|- - Forger   Цитата(jcxz @ May 5 2018, 12:33) Лучше ра...   May 5 2018, 10:26
|- - jcxz   Цитата(Forger @ May 5 2018, 13:26) К тому...   May 5 2018, 11:02
|- - Forger   Цитата(jcxz @ May 5 2018, 14:02) Вобщем -...   May 5 2018, 14:50
- - amaora   Параметры не константные, все разные, есть настрой...   May 3 2018, 13:16
- - Kabdim   А точка в ваших определениях регистров всегда буде...   May 3 2018, 13:40
- - amaora   Функции доступа я тоже мог бы написать, но в этом ...   May 5 2018, 08:15
- - amaora   Вот так сделал Кодcat regfile.c | sed -n ...   Aug 11 2018, 18:54
|- - Arlleex   Цитата(amaora @ Aug 11 2018, 21:54) Вот т...   Aug 12 2018, 07:00
- - amaora   Ну, здесь я обычно не задаю вопросов по своей осно...   Aug 12 2018, 16:52
- - Nixon   Для доступа по индексу можно так сделать Кодenum V...   Aug 13 2018, 13:58
|- - Forger   Цитата(Nixon @ Aug 13 2018, 16:58) Для до...   Aug 13 2018, 14:51
|- - Forger   Цитата(DASM @ Aug 13 2018, 20:11) ... Пыт...   Aug 13 2018, 17:39
|- - Forger   Цитата(DASM @ Aug 13 2018, 21:37) Но как ...   Aug 13 2018, 18:39
|- - Forger   Цитата(DASM @ Aug 13 2018, 23:08) Можно с...   Aug 13 2018, 20:17
|- - Nixon   Цитата(Сергей Борщ @ Aug 14 2018, 01:49) ...   Aug 14 2018, 06:14
|- - DASM   Цитата(Nixon @ Aug 14 2018, 09:14) Не обя...   Aug 14 2018, 06:18
|- - Nixon   Цитата(DASM @ Aug 14 2018, 09:18) О, кста...   Aug 14 2018, 06:24
- - DASM   А наоборот как ? Кодtypedef enum {t1, t2, t3 = ...   Aug 13 2018, 18:15
|- - Forger   По-ходу я ошибся с явным указанием типа enum, у ме...   Aug 13 2018, 18:25
|- - DASM   Цитата(Forger @ Aug 13 2018, 21:25) По-хо...   Aug 13 2018, 18:43
|- - Forger   Цитата(DASM @ Aug 13 2018, 21:43) А вот т...   Aug 13 2018, 19:28
- - DASM   Гы, const struct а тут мы возвращаемся к вопросу и...   Aug 13 2018, 19:39
|- - Forger   Цитата(DASM @ Aug 13 2018, 22:39) Гы, con...   Aug 13 2018, 19:49
- - Nixon   Может ещё кому полезно будет: В анонимных структу...   Aug 13 2018, 20:31
|- - Forger   Цитата(Nixon @ Aug 13 2018, 23:31) Наприм...   Aug 13 2018, 20:37
- - Nixon   Я без привязки к вашему примеру. Просто довольно п...   Aug 13 2018, 20:49
|- - Forger   Цитата(Nixon @ Aug 13 2018, 23:49) Просто...   Aug 13 2018, 20:51
- - DASM   Вот нашел ответ, как удобно пользовать enum class....   Aug 14 2018, 05:53
- - Kabdim   По факту тип указанный в энуме, года 3 назад работ...   Aug 14 2018, 06:32
- - DASM   Да, лучше. Но пока не знал об этом - много писанин...   Aug 14 2018, 06:34
|- - Kabdim   Цитата(DASM @ Aug 14 2018, 09:34) "3...   Aug 14 2018, 06:49
- - Nixon   В стандарте то стандарте, но не совсем "С...   Aug 14 2018, 06:39
|- - DASM   Цитата(Nixon @ Aug 14 2018, 09:39) В стан...   Aug 14 2018, 07:10
|- - Kabdim   Цитата(DASM @ Aug 14 2018, 10:10) это как...   Aug 14 2018, 07:17
- - DASM   Цитатаtypedef enum { tst, tst2, tst3 } test; #pra...   Aug 16 2018, 06:32
|- - Kabdim   Цитата(DASM @ Aug 16 2018, 09:32) А что т...   Aug 16 2018, 14:29
|- - DASM   Цитата(Kabdim @ Aug 16 2018, 17:29) А чег...   Aug 16 2018, 14:41
|- - Forger   После sizeof ( некого enum ), недалеко и до sizeof...   Aug 16 2018, 14:56
||- - DASM   Цитата(Forger @ Aug 16 2018, 17:56) После...   Aug 16 2018, 15:09
||- - Forger   Цитата(DASM @ Aug 16 2018, 18:09) А все ж...   Aug 16 2018, 15:13
|- - Kabdim   Цитата(DASM @ Aug 16 2018, 17:41) Просто ...   Aug 17 2018, 10:39
|- - Arlleex   Цитата(Kabdim @ Aug 17 2018, 14:39) Как э...   Aug 17 2018, 10:54
|- - DASM   Цитата(Kabdim @ Aug 17 2018, 13:39) Как э...   Aug 17 2018, 12:04
|- - Forger   Цитата(DASM @ Aug 17 2018, 15:04) offseto...   Aug 17 2018, 12:23
|- - Kabdim   Применительно к этой ситуации, как раз Кейл - непр...   Aug 17 2018, 12:45
- - sigmaN   Извиняюсь, если это уже предлагали(не читал все со...   Aug 17 2018, 08:08
- - Kabdim   Я не вижу. Вопрос был DASM'у цитата к которой ...   Aug 17 2018, 11:51
- - sigmaN   From Standard C++ 7.2/5: ЦитатаThe underlying type...   Aug 19 2018, 06:25
- - DASM   Да ладно, фиг с ним.   Aug 19 2018, 20:41


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

 


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


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