Alt.F4 0 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Здравствуйте. Написан конечный автомат на конструкции switch - case. Для перехода к последующему действию просто инкрементируется указатель: switch(i) { case 0: ... i++; case 1: ... i++; ... case N: ... i++; } Действий порядка 100 и возникла проблема с добавлением новых case-обработчиков в середину конструкции, т.к. приходится увеличивать все последующие номера case. Хочется перенести эту задачу на плечи препроцессора и оформить конструкцию таким образом, чтобы название макроопределения case было у всех одинаковым и, в тоже время, каждое последующее значение было на 1 больше предыдущего: switch(i) { case INCNAME: ... i++; case INCNAME: ... i++; ... case INCNAME: ... i++; } Подскажите, пожалуйста, возможно ли это как-то реализовать? Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Так получится? int j = 0; if(0){} else if((j++) && (i == j)) { // do 1 i++; } else if((j++) && (i == j)) { // do 2 i++; } ... else if((j++) && (i == j)) { // do N i++; } #define NEXT else if((j++) && (i==j)) if(0){} NEXT { } NEXT { } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба "В лоб" задача решается применением enum. typedef enum { IDLE, START, RUN, STOP } state_t; state_t State; switch (State) { case IDLE: ..... State = START; break; case START: .... В середину такого конечного автомата легко добавляется любое количество новых состояний. Конечно, придумать около 100 названий для сотояний и не сорваться на использование цифр в этих названиях - задача непростая. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Действий порядка 100 и возникла проблема с добавлением новых case-обработчиков в середину конструкции, т.к. приходится увеличивать все последующие номера case. Хочется перенести эту задачу на плечи препроцессора и оформить конструкцию таким образом, чтобы название макроопределения case было у всех одинаковым и, в тоже время, каждое последующее значение было на 1 больше предыдущего: Значения после case должны быть разными. Иначе компилятор просто не станет компилить. Я в подобных случаях использую enum. При добавлении хоть в середину хоть в конец нет проблем с перенумерацией. enum { //фазы автомата состояний INCNAME_SOST0, INCNAME_SOST1, INCNAME_SOST2, ...}; Так получится? else if((j++) && (i == j)) ... Не компилил, но почти уверен, что на такую конструкцию компилятор скажет: "Undefined behavior". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Не компилил, но почти уверен, что на такую конструкцию компилятор скажет: "Undefined behavior". Компилируется даже без предупреждений. Единственное, в {} не должно быть i++. Лучше new_i++, а в самом конце i = new_i. Иначе автомат выстрелит очередью. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Подскажите, пожалуйста, возможно ли это как-то реализовать? Спасибо. Создаете в Excel одну строку с одним макроопределением. Потом протягиваете ее до 100 строк и получаете идеальный инкремент. Если нужно вставить что-то в середину, то в вставляете в Excel-е и снова протягиваете, получите новый инкремент. Потом Copy-Paste из Excel-а А числа на макросы заменяются автоматически с использованием регулярного выражения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladivolt 0 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Подход с enum, несомненно, правилен. Однако, при добавлении состояний, потребуется редактировать в двух местах. #define INCNAME __COUNTER__ Только надо предусмотреть ловушку какую на случай если __COUNTER__ был ранее использован. https://gcc.gnu.org/onlinedocs/cpp/Common-P...edefined-Macros Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 60 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Есть такая реализация, сделана на swich/case и __LINE__ http://dunkels.com/adam/pt/index.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Действий порядка 100... Что говорит о том, что решение поставленной задачи только с помощью конечного автомата зашло в тупик :(. Думайте о комбинации методов. Более-менее типичный выход из такой ситуации это использование наряду с состоянием конечного автомата дополнительных битовых флагов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Что говорит о том, что решение поставленной задачи только с помощью конечного автомата зашло в тупик :(. Думайте о комбинации методов. Да нормально, есть прикладные протоколы с очень большими словарями. Только вот enum для этого негодное средство, поскольку при отладке невозможно узнать значение макроса и приходится все равно либо в комментариях либо прямым присваиванием вписывать числа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Да нормально, есть прикладные протоколы с очень большими словарями. Не путайте протоколы с их РЕАЛИЗАЦИЕЙ через анус. Сотня состояний конечного автомата это уже анус. Только вот enum для этого негодное средство, поскольку при отладке... Отладка сколь-нибудь серьезных ПРОТОКОЛОВ отладчиком есть абсолютно непригодное средство, ибо все проблемы взаимодействия оборудования раснообразных производителей начнутся не тогда, когда все лежит на столе. Так что логирование состояния конечного автомата обязательно, ну а при логировании разворачивание названий состояний в текст так же обязательно. Все это решается через общую функцию изменения состояния автомата. Например: void q921_set_state( LAPD_t *ldp, ulong new_state ) { ldp->state = new_state; dprintf( "\tL%1X:Set State`%s`(Cmd:%4X)\r", ldp->ch, q2_states[ldp->state], ldp->q921_cmd ); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Не путайте протоколы с их РЕАЛИЗАЦИЕЙ через анус. Сотня состояний конечного автомата это уже анус. Отладка сколь-нибудь серьезных ПРОТОКОЛОВ отладчиком есть абсолютно непригодное средство, ибо все проблемы взаимодействия оборудования раснообразных производителей начнутся не тогда, когда все лежит на столе. Прямо сейчас у меня в работе протокол с 41-им case в парсере. Линейная структура кода позволяет легко его форматировать и рефакторить. Регулярные выражения замены легче писать под такую структуру кода. Работает она быстрее. Короче одни плюсы. Протоколы только отладчиком через SWD и можно детально отладить. Логи для протоколов - это во первых медленно, во вторых менее информативно, в третьих сами вносят нежелательный эффект в виде роста стека задач и ухудшения реалтайма. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Только вот enum для этого негодное средство, поскольку при отладке невозможно узнать значение макроса и приходится все равно либо в комментариях либо прямым присваиванием вписывать числа. Вот этого не понял. Мой отладчик пишет численное значение при помещени указателя мыши на имя. Да и небходимость узнать конкретное значение возникает очень редко, чаще гораздо важнее знать именно имя состояния конечного автомата. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Мой отладчик пишет численное значение при помещени указателя мыши на имя. Трудно припомнить название? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 10 июля, 2016 Опубликовано 10 июля, 2016 · Жалоба Трудно припомнить название? gdb + eclipse. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться