Rozwijam oprogramowanie układowe dla aplikacji osadzonej z ograniczeniami pamięci. Mam zestaw poleceń, które muszą zostać przetworzone po ich otrzymaniu. Każde polecenie przypada na inne "wiadra", a każde "wiadro" dostaje zakres prawidłowych numerów poleceń. Stworzyłem dwa ENUMs, jak pokazano poniżej, aby to osiągnąć.Używanie ENUM jako map bitowych, jak sprawdzać poprawność w C
enum
{
BUCKET_1 = 0x100, // Range of 0x100 to 0x1FF
BUCKET_2 = 0x200, // Range of 0x200 to 0x2FF
BUCKET_3 = 0x300, // Range of 0x300 to 0x3FF
...
...
BUCKET_N = 0xN00 // Range of 0xN00 to 0xNFF
} cmd_buckets;
enum
{
//BUCKET_1 commands
CMD_BUCKET_1_START = BUCKET_1,
BUCKET_1_CMD_1,
BUCKET_1_CMD_2,
BUCKET_1_CMD_3,
BUCKET_1_CMD_4,
//Add new commands above this line
BUCKET_1_CMD_MAX,
//BUCKET_2 commands
CMD_BUCKET_2_START = BUCKET_2,
BUCKET_2_CMD_1,
BUCKET_2_CMD_2,
BUCKET_2_CMD_3,
//Add new commands above this line
BUCKET_2_CMD_MAX,
//BUCKET_3 commands
...
...
...
//BUCKET_N commands
CMD_BUCKET_N_START = BUCKET_N
BUCKET_N_CMD_1,
BUCKET_N_CMD_2,
BUCKET_N_CMD_3,
BUCKET_N_CMD_4,
//Add new commands above this line
BUCKET_N_CMD_MAX,
}cmd_codes
Gdy funkcja obsługi komend odbierze kod polecenia, musi sprawdzić, czy polecenie jest włączone przed jego przetworzeniem. Planuję użyć bitmapy do tego. Polecenia mogą być włączone lub wyłączone z przetwarzania w czasie wykonywania. Mogę użyć int dla każdej grupy (dając mi 32 polecenia na grupę, zdaję sobie sprawę, że 0xN00 do 0xN20 są poprawnymi kodami poleceń i że inne kody z tego zakresu są marnowane). Mimo że kody poleceń są marnowane, wybór projektu ma tę zaletę, że można łatwo powiedzieć grupie kodu polecenia podczas przeglądania surowych danych na konsoli.
Ponieważ wielu programistów może dodawać polecenia do enum cmd_codes (nawet nowe wiadra mogą być dodawane w razie potrzeby do enum cmd_buckets), chcę się upewnić, że liczba kodów poleceń w każdym segmencie nie przekracza 32 (bitmapa jest int). Chcę złapać to w czasie kompilacji, a nie w czasie wykonywania. Oprócz sprawdzania każdej wartości BUCKET_N_CMD_MAX, jak poniżej i wyrzucania błędu czasu kompilacji, czy istnieje lepsze rozwiązanie?
#if (BUCKET_1_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_1 exceeded 32")
#endif
#if (BUCKET_2_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_2 exceeded 32")
#endif
#if (BUCKET_3_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_3 exceeded 32")
#endif
...
...
...
#if (BUCKET_N_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_N exceeded 32")
#endif
Proszę również zasugerować, czy istnieje bardziej elegancki sposób zaprojektowania tego.
Dzięki, doceniam twój czas i cierpliwość.
Komentarze można wysyłać; jednak wydaje mi się, że pytanie jest bardziej trafne dla forum Stack Overflow _Code Review_. Czy ktokolwiek może to przenieść do recenzji kodu? –
@PaulOgilvie Pytanie wydaje się lepiej pasować do przepełnienia stosu. Przegląd kodu wymaga pełnych, działających przykładów kodu. – Lundin
Ten przykład nie ma żadnego sensu. Masz stałą wartość 'BUCKET_1 = 0x100', którą następnie przypisujesz' CMD_BUCKET_1_START = BUCKET_1'. Końcowe wyliczenia otrzymają wartości 0x101, 0x102, ... a "BUCKET_1_CMD_MAX" będzie 0x106. Ponieważ 0x106 jest zawsze większe niż 0x20, twój statyczny dowództwo zawsze będzie wyzwalać. Opublikuj działający przykład. – Lundin