0
/* UART HEADER */
#define featureA        0xA0
#define featureB        0xB0
#define featureC        0x20
        -
        -
        -
        - // increment on feature, value of feature are random
        -
        -
#define featureZ     0x??

#define CHECK_CHAR(x) ((x==featureA)||(x==featureB)||(x==featureC) ------- (x==featureZ)? TRUE: FALSE)

Hi all, I got a set of UART header that to indicate what the commands for. So every time I am checking the header using the macro, but I realize that when the command is keep increasing and the macro length also keep increasing, it make the code very messy. I am looking for a mechanism to handle this checking when the feature is more and more.

JDC
  • 43
  • 6
  • is there a reason this has to be a macro and not a function? The compiler will mostly inline this anyway – Ajay Brahmakshatriya Jun 11 '20 at 03:20
  • @AjayBrahmakshatriya It can be a function also. The only thing I want to is simplified the macro. The macro had been use by several developer before, and they keep expending it only. Now on my hand I feed that is very messy and wish to clean up that. Take note that the #define HAD NO PATTERN for the value. – JDC Jun 11 '20 at 03:38
  • You could at least get rid of `(/*... boolean expression ... */ ? TRUE : FALSE)` by removing the ternary. Well, if your `TRUE` and `FALSE` are booleans. I have seen a lot of crap around such stuff. -- And please don't add additional information as comment, [edit] your question. This is not a forum. – the busybee Jun 11 '20 at 05:43

2 Answers2

1

Since this seems to be a run-time check, you can speed up the program considerably by using a look-up table instead. It will also make the code more readable. Assuming you can spare 256 bytes of flash and all codes are unique, then:

bool CHECK_CHAR (uint8_t ch)
{
  const bool LOOKUP [256] = 
  {
    [featureA] = true,
    [featureB] = true,
    [featureC] = true,
  };

  return LOOKUP[ch];
}

The second best option is a sorted array of uint8_t constants + binary search.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Are the non-specified keys guaranteed to be 0? – Daniel Walker Jun 11 '20 at 19:27
  • 1
    @DanielWalker Yes, since a partially full initializer list zero-initializes items where no initializer was specified. – Lundin Jun 12 '20 at 06:34
  • 1
    @DanielWalker This rule is also the reason why we can zero-initialize a whole array with `int name [n] = { 0 }`. Some examples here: https://stackoverflow.com/a/15521368/584518. – Lundin Jun 12 '20 at 14:14
0

Assuming that your values follow the simple pattern above, this would work:

#define CHECK_CHAR(x) ( ((x)&0xf) == 0 && (x) >= featureA && (x) < featureInvalid )

where you define featureInvalid to be the next logical value after featureZ.

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45
  • Hi, I think I am too simplified my question already just now, sorry about that. Please note that the #define is not increment in ascending. If using enum then a lot's of assign will inside the enum. – JDC Jun 11 '20 at 03:23
  • I've changed my answer to reflect your change. – Daniel Walker Jun 11 '20 at 03:25
  • There is no pattern in term of the header, it had been use long time ago from other's developer. Only thing for those define is only 1 Byte, range from 0x00 to 0xFF. They simply define any value to there and put into macro. So the macro become more and more longer, and now I want to simplified that. – JDC Jun 11 '20 at 03:30
  • Oof, that's rough! Is the reason you want to clean up the macro that 1) it's an eyesore or 2) it's too much of a pain to maintain? If it's the latter, some may frown on this suggestion but I'd recommend creating a Python script to auto-generate the header file for you. – Daniel Walker Jun 11 '20 at 03:36
  • It's definitely an eyesore for me, that why I wish to kill it. Imagine the macro already over 4 lines on that. Got any design reference/mechanism to handle without changing the #define value had been done before. It a UART header related to the slave device. If restructure the whole definition will be painful. – JDC Jun 11 '20 at 03:43
  • 1
    Sorry to hear that. If you can, I'd push to have the error codes changed so that my above solution (or something akin) works. Failing that, you could make the macro a little prettier by putting each condition on a separate line. Of course, that would make it take up a lot of lines. – Daniel Walker Jun 11 '20 at 03:49