The program has a function that, depending on the selected address, writes the transferred value to some variables. It looks like this:

int reg_write(uint16_t addr, uint16_t value) { switch(addr) { case S0_1_A: return write_to(value, 0, 1, SA); case S0_2_B: return write_to(value, 0, 2, SB); . . . case S1_12_B: return write_to(value, 1, 12, SB); default: return ERROR_CODE; } } 

That is, there is a range of addresses and, depending on the address, I write to some variable of one of the 2 structures s0 or s1. That is, for example:

 int write(uint16_t value, int sn, int n, enum SE se) { if(se == SA) s[sn].a[n] = value; else s[sn].b[n] = value; } 

The example is conditional, in fact, I have a lot more structures and variables. The Sxxx constants generally have arbitrary values, but for one structure S they go strictly in order, but there are “holes” (S0_1_A, S0_1_B, S0_2_A, S0_5_A, S0_5B), followed by index 2 immediately. 5 addresses. Question: how can you simplify the recording of a switch-case as much as possible?
GCC compiler, you can use any means. It may even be some kind of code generation, but preferably as simple as possible and, if possible, in C, not in C ++.

  • Make a table of type value / function, and search in it. Only it will be slower to work ... - Harry
  • std::map<uint16_t, std::pair<uint8_t, uint8_t> = {{S0_1, {0 ,1}}, ...} - user1056837
  • one
    And what are the constants SX_X equal to? Can the sn and n values ​​be pulled out by overlaying a bit mask? - Anton Shchyrov 2:41 pm
  • 3
    Something you have a question is changing like a chameleon on a heap of skittls, it is not at all interesting to adjust the answer to the new conditions every time. - αλεχολυτ
  • one
    @Reffum Where are these constants declared? there is in fact some kind of .h file in which they are all listed ... you can make a script in any less familiar word processing language that reads this file of constants and, on the basis of them, generates a transition table (generate a giant switch of course not worth it). - Mike

1 answer 1

Your task in general is reduced to the need to obtain a mapping of one integer value (address) to a set of others (possibly of different types):

 addr -> { sn, n, se } 

There are several possible solutions:

  1. Because addr is set to 16-bit value, there are not so many of them (65536) and you can create a table (array), where the index will be the address, and the value at this index will store the structure with a suitable set of values.

  2. Using not an array, but std::map / std::unordered_map (for C ++), if there are few branches (much less than 64K), then this may be more advantageous.

  3. If there exists (maybe it just needs to be understood) the well-known logic of forming target values ​​from an address, then this logic can be implemented as a function. And then use the result of this function as the desired set.

  4. Combine method 3 with (1 or 2) to fill the array / display during program execution during initialization, and in subsequent calls use the already prepared table.

The maximum brevity of the code can be achieved only if we find the dependence of the output on the input. If there is no such dependence, then somehow it is necessary to fill the table manually. But using the table is still preferable to switch to multiple screens.

  • "Laconic code." So it turns out a huge switch-case, I just think how to enter it. The table does not solve the problem, you also need to enter it somehow. - Reffum 2:41 pm
  • 3
    @Reffum if there is any known logic of forming sn , n from addr , then you just need to create such a function / pair of functions, and call write_to(value, f(sn, n), g(sn, n)); instead of a huge switch . - αλεχολυτ