#define or int for your Arduino Ports?

I recently received an Arduino program segment from a customer and noticed that he used #define in the port identifiers, ie.

#define LED_RED = 3;
#define LED_GREEN = 4;

I have seen this used previously, and have used this method myself in my early Arduino programs. However, const int has been my go to in this situation for a long time, so I decided to look in to which was better, and found the following:

When declaring Arduino ports (such as pin numbers), using const int is generally preferred over #define. Here’s why:

1. Type Safety

  • Using const int ensures type checking at compile time, preventing unintended type mismatches.
  • #define creates a preprocessor macro with no type, meaning it can lead to unexpected behavior if misused.
const int LED_RED = 3;  // Type-safe
#define LED_RED 3       // No type checking

2. Debugging and Readability

  • const int allows the compiler to associate variable names with addresses, making debugging easier.
  • With #define, the compiler replaces occurrences of the macro before compiling, so the debugger won’t show meaningful names.

3. Memory Usage and Optimization

  • Modern compilers optimize const int variables by replacing them with their values at compile time, similar to #define, but with additional benefits.
  • const int may also allow for better optimization in function calls compared to macros.

4. Scope Control

  • #define macros are global and can accidentally override other macros.
  • const int has proper scope rules, meaning it won’t interfere with other variables unintentionally.

Conclusion:
Using const int (or even better, constexpr) is safer, more readable, and just as efficient as #define, making it the better choice for defining Arduino ports.