using #define vs const in C

Thread Starter

bug13

Joined Feb 13, 2012
1,807
Hi teams

I have been using #define for most of time but recently I found using constant maybe a better idea in C. My question is, in what situation is better to use #define instead of constant?

For example:
C:
/* some settings for a peripheral */
#define SETTING1    ((uint8_t)0x10)
#define SETTING2    ((uint8_t)0x20)
#define SETTING3    ((uint8_t)0x30)
Code:
typedef struct PERIPHERAL_SETTINGS {
    uint8_t        setting1;
    uint8_t        setting2;
    uint8_t        seeting3;
}peripheral_settings_t;

const peripheral_settings_t FOO_SETTINGS = {
    .setting1     = 0x10,
    .setting2     = 0x20,
    .setting3     = 0x30,
};
 

WBahn

Joined Mar 31, 2012
25,224
Using #define is essentially using the preprocessor to perform a search and replace on the text in the file before it gets sent to the compiler.

The const keyword is essentially signalling your intention to the compiler to not make changes to a value, giving the compiler the opportunity to smack you if you try.
 

dl324

Joined Mar 30, 2015
9,985
Thanks, that's one good point!
It's only an issue if you're programming for a resource constrained application (e.g. Arduino). Instead of using variables for I/O pins, I started using #define. I'm nowhere near running out of RAM, but it's good to get in the habit of not wasting resources if you don't have to.
 

Thread Starter

bug13

Joined Feb 13, 2012
1,807
It's only an issue if you're programming for a resource constrained application (e.g. Arduino). Instead of using variables for I/O pins, I started using #define. I'm nowhere near running out of RAM, but it's good to get in the habit of not wasting resources if you don't have to.
Just did a quick test, you can store variables in flash if you want to:
C:
/*!
    Sketch uses 5946 bytes (2%) of program storage space. Maximum is 253952 bytes.
    Global variables use 188 bytes (2%) of dynamic memory, leaving 8004 bytes for local variables. Maximum is 8192 bytes.
*/

/* make a big array */
#define LEN   ((uint16_t)4000)

/* store this constant data in flash instead of ram */
const PROGMEM uint8_t test[LEN] = {0};

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (uint16_t i = 0; i < LEN; i++){
    Serial.println(test[i]);
  }
}
 

MrSoftware

Joined Oct 29, 2013
1,674
For the most basic case, if you're just representing simple data such as an int or char array, there's not an enormous difference (ignoring under the hood differences such as where data is stored, etc..). But since #define is a pre-processor feature, it can be used for so much more. Controlling what code is compiled, representing chunks of code, etc..
 

WBahn

Joined Mar 31, 2012
25,224
For the most basic case, if you're just representing simple data such as an int or char array, there's not an enormous difference (ignoring under the hood differences such as where data is stored, etc..). But since #define is a pre-processor feature, it can be used for so much more. Controlling what code is compiled, representing chunks of code, etc..
Many years ago I created (what I think) are some pretty sophisticated #define macros that make it easy to generate the skeleton of a object-oriented-like class file in which the basic structure definition along with constructor/destructor and get/set functions are automatically generated by just a few macro calls and all of the other function headers are consistently and simply defined via another macro. It made creating pretty sophisticated and reusable and robust structure-based programming quite easy.
 
Top