4

I'm writing an Arduino library to communicate with an I2C device, and I'm wondering what the best way is to declare all the register addresses so as to save memory.

Using #defines:

#define REGISTER_MOTOR_1_MODE 0x44
#define REGISTER_MOTOR_2_MODE 0x47

Or using static const:

static const uint8_t REGISTER_MOTOR_1_MODE = 0x44;
static const uint8_t REGISTER_MOTOR_2_MODE = 0x47;

(Obviously I have more than just two registers I need to declare, but I thought two would illustrate the point just fine)

3 Answers3

8

You'll find no noticeable difference memory-wise between the two.

The only real difference is that the const method also imposes a type to the value, which can be useful for function overloading or mathematical operations.

Majenko
  • 105,851
  • 5
  • 82
  • 139
6

A #define is a preprocessor macro. As Gerben says in his comment, it's just an automated find-and-replace.

If you use it to hold things like C string constants, e.g. #define ERROR_STRING "You messed up, bud!" it could actually cause your program to take more memory, since that same string literal will be duplicated every time you reference it. In that case a static const would be both type-safe AND reduce memory usage.

Duncan C
  • 5,752
  • 3
  • 19
  • 30
3

Theoretically both approaches should consume the same amount of space and will probably result in the same code.


However, rather than that meaning "pick any one", what that actually means is that you should turn your attention to other factors when deciding which one to use.

As a rule of thumb you should generally avoid macros because they don't respect scoping rules due to how they work.
This can lead to some serious problems in certain cases.
See Why are preprocessor macros evil and what are the alternatives?.


However, I'd like to point out a third option: constexpr.

constexpr uint8_t motorMode1Register = 0x44;

constexpr implies const and is a better expression of the intent that the value should be capable of being evaluated at compile time.
constexpr literally means "this is a constant expression and thus can be evaluated at compile time".
As a result of this, constexpr variables can be used in situations where other variables cannot, such as template parameters.

See Constexpr vs Macros.

Pharap
  • 149
  • 8