Quantcast
Channel: User Lundin - Code Review Stack Exchange
Viewing all articles
Browse latest Browse all 42

Answer by Lundin for Embedded IoT: local data storage (Second Update)

$
0
0

Overall the code is well-written and easy to read. I found no major things to remark on, just details:

  • cvaluetypes is only used by the .c file and should be declared static, to achieve private encapsulation. It's good that you use * const for read-only pointer tables, since this typically makes them flash allocated on embedded systems, as opposed to RAM where they shouldn't be.

  • Minor remark: to avoid multiple returns from a function, it is best to make a habit of doing:

      static uint8_t BucketGetRegisteredFeedSlot(const cbucket_t *data){      uint8_t slotIdx = 0xFF;      ...          if(data == registeredFeed[slotIdx]){              break;          }      return slotIdx;  }
  • There's a few cases of "magic numbers" like 99. These should be made named constants with #define or const.

  • unsigned head, const int etc. You suddenly slip back to the native C types here and there. Stick with stdint.h or use size_t for sizes of types and arrays.

  • Strive to keep for loops as simple as possible. That is, always count upwards and avoid multiple iterators. For example you could as well do this:

      uint16_t start = cBucketBufTail - cBucketBuf + offset;  for(size_t i=start; i<size; i++)

    There's many such needlessly complicated for loops in the code.

  • Avoid strncpy, it's a dangerous function since it is prone to mess up the null termination. And needlessly slow when you know the exact size in advance. So you could have used memcpy:

      memcpy(key, registeredFeed[slotIdx]->key, strlen(registeredFeed[slotIdx]->key) + 1);

    Although in this specific case, since you call strlen anyway, you should use neither of these functions including strlen. The correct function here is strcpy:

      strcpy(key, registeredFeed[slotIdx]->key);
  • Your error handling is inconsistent - some times you use bool, some times magic numbers -1, -2 etc. All of these function results should be replaced by a consistent error type used by the whole library, in the form of a typedef enum {...} bucket_err_t; Then document which functions that return which error codes, in what situations.

  • Comments containing the function documentation should be placed in the header, in case of public functions. Comments documenting private static functions obviously need to be in the .c file like you have though.

  • You forget const correctness in a few places like void PrintFeedValue(cbucket_t *feed) -> const cbucket_t *.

  • It's ok to use uint8_t as the string type, particularly in embedded systems. However please note that this might upset compilers when you call standard libs with that type. Therefore make a habit of casting to char* before calling strlen etc.


EDIT

  • In case you have functions doing return false etc upon error and those functions also return values through parameter pointers, you must document what happens to those parameters in case of errors. Are they untouched in case of errors, are they set to some error code or known value, or are they to be considered as indeterminate values?

Viewing all articles
Browse latest Browse all 42

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>