# \#define, int or const int

**URL:** <https://forum.arduino.cc/t/define-int-or-const-int/246329>\
**Category:** Programming\
**Created:** [July 16, 2014, 7:53am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329 "2014-07-16T07:53:32Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![MisterG](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@MisterG](https://forum.arduino.cc/u/MisterG)\
**Post date:** [July 16, 2014, 7:53am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/1 "2014-07-16T07:53:32Z")

</div>

Good morning!

Relative newbie here, looking to use the Arduino I have rather than the Pi...

I've looked at loads of code and have come across a puzzle. Even in the Hello World "blink" sketch I have seen the following:

#define ledPin = 13  
int ledPin = 13  
const int ledPin = 13

Now, I understand that #define is really a "search an replace" type of thing, looking for ledPin and replacing it with 13.  
What about the other two? They are both integer variables, but the last one is also a constant. Is it important to declare it as such? The other example works without. Or is it a matter of choice?

Thanks in advance  
MisterG

---

<div class="post-metadata">

**Author:** ![knut\_ny](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/knut_ny/32/1013044_2.png) [@knut\_ny](https://forum.arduino.cc/u/knut_ny)\
**Post date:** [July 16, 2014, 8:03am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/2 "2014-07-16T08:03:31Z")

</div>

"const" makes the variable 'read only'.  
...so in this case: doesn't matter.

---

<div class="post-metadata">

**Author:** ![BijendraSingh](https://avatars.discourse-cdn.com/v4/letter/b/bbe5ce/32.png) [@BijendraSingh](https://forum.arduino.cc/u/BijendraSingh)\
**Post date:** [July 16, 2014, 8:50am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/3 "2014-07-16T08:50:09Z")

</div>

> int ledPin = 13

you are creating a variable (ledpin) of int data type and assigning 13 to it.  
but you can change the assigned value of ledpin when ever you want.

> const int ledPin = 13

you are creating a variable (ledpin) of int data type and assigning 13 to it.  
but you can **not** change the assigned value of ledpin throught out its scope.

---

<div class="post-metadata">

**Author:** ![holmes4](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/holmes4/32/215302_2.png) [@holmes4](https://forum.arduino.cc/u/holmes4)\
**Post date:** [July 16, 2014, 9:09am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/4 "2014-07-16T09:09:48Z")

</div>

For pin number you should not use int as it wastes memory, use one of the byte sized types.

Mark

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [July 16, 2014, 9:47am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/5 "2014-07-16T09:47:07Z")

</div>

Note that  
`#define ledPin = 13`is not correct. Unless, that is, you really want the pre-processor to replace all instances of ledPin with = 13, which is unlikely

---

<div class="post-metadata">

**Author:** ![cmiyc](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cmiyc/32/1204108_2.png) [@cmiyc](https://forum.arduino.cc/u/cmiyc)\
**Post date:** [July 16, 2014, 1:40pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/6 "2014-07-16T13:40:02Z")

</div>

> MisterG:  
> #define ledPin = 13

This is a great example of why #define shouldn't be used.

This is going to introduce confusing compiler messages and a difficult to locate bug...

> MisterG:  
> Is it important to declare it as such? The other example works without. Or is it a matter of choice?

Personally, I avoid #define except for keywords to make reading my code easier. For example, when using pull-up resistors on my buttons, I usually do this:

```arduino
#define PUSHED LOW
#define UNPUSHED HIGH

```

const does two things for you:

1. to will let the compiler complain if your program tries to modify a value. Which is good for things that shouldn't change while your program runs, e.g. pin numbers. and
2. the compiler will try place the variable in RAM if it can fit in a register.

As for #2, the compiler is pretty smart. If it sees in your program a non-const variable is never modified, it may actually treat it as a constant, never putting it into RAM.

I did a write up here, with a simple explain of how much RAM is used (checked with avr-size) when using const and when not:

> **[Const vs #define - When do you use them and why? - Bald Engineer](https://www.baldengineer.com/const-vs-define-when-do-you-them-and-why.html)**
>
> Arduino boards have microcontrollers with notoriously small amounts of RAM.  The Uno only has 2,048 bytes of static RAM available for your program to store variables.  So when you need to keep non-changing variables out of RAM which is best...

There's also a link to in-depth analysis done of this forum:  
[http://arduino.cc/forum/index.php/topic,86800.15.html](http://arduino.cc/forum/index.php/topic,86800.15.html)

---

<div class="post-metadata">

**Author:** ![econjack](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/econjack/32/1290082_2.png) [@econjack](https://forum.arduino.cc/u/econjack)\
**Post date:** [July 16, 2014, 1:58pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/7 "2014-07-16T13:58:22Z")

</div>

> They are both integer variables

Well, not really. Because a #define is a textual replacement, it is "typeless". That is: the code

```arduino
#define MYVAL 500

void setup() {
  // put your setup code here, to run once:
  int number = MYVAL;
  byte value = MYVAL;
}

void loop() {
  // put your main code here, to run repeatedly:
}

```

compiles without error, but assigning 500 into a _byte_ probably isn't going to work. This is likely why James says they can introduce hard-to-find bugs. There are, however, times when the fact that a symbolic constant is typeless can be a good thing (e.g., when working with a _union_). While James clearly doesn't like #define's, they do have their place. If the IDE had a symbolic debugger, I would rarely use #define, since it cannot be traced by a debugger once the preprocessor pass completes.

In either case, I think it helps to upper-case both #define's and _const_ data definitions to signal the reader that the expression is different.

---

<div class="post-metadata">

**Author:** ![pYro\_65](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/pyro_65/32/214665_2.png) [@pYro\_65](https://forum.arduino.cc/u/pYro_65)\
**Post date:** [July 16, 2014, 2:10pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/8 "2014-07-16T14:10:25Z")

</div>

> econjack:
> 
> > They are both integer variables
> 
> Well, not really. Because a #define is a textual replacement, it is "typeless".

But its replaced value is not.

---

<div class="post-metadata">

**Author:** ![econjack](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/econjack/32/1290082_2.png) [@econjack](https://forum.arduino.cc/u/econjack)\
**Post date:** [July 16, 2014, 2:15pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/9 "2014-07-16T14:15:47Z")

</div>

> But its replaced value is not.

True, but it can assume the resolved data type used in the expression. It is typeless in that it can be used in almost any expression where a data type is used and the compiler won't flag it as a type mismatch where a cast would normally be required.

---

<div class="post-metadata">

**Author:** ![pYro\_65](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/pyro_65/32/214665_2.png) [@pYro\_65](https://forum.arduino.cc/u/pYro_65)\
**Post date:** [July 16, 2014, 2:37pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/10 "2014-07-16T14:37:21Z")

</div>

> econjack:
> 
> > But its replaced value is not.
> 
> True, but it can assume the resolved data type used in the expression. It is typeless in that it can be used in almost any expression where a data type is used and the compiler won't flag it as a type mismatch where a cast would normally be required.

Its not type less at all, literal integers are a type of int, and will never be char/unsinged char, only character literals can be chars. Its the normal integral conversions which allow them to be converted and assigned, and the same rules apply regardless of weather the integer is a literal, variable, or constant. This genereates an error: **_char \*c = 500;_**

Here you can see its clearly an int.

```arduino
#define WHAT_TYPE_AM_I 500

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

void loop() {}

void Func( char c ){
  Serial.print( "printing char" );
  Serial.println( c ); 
}

void Func( int i ){
  Serial.print( "printing int" );
  Serial.println( i, HEX ); 
}

void Func( float f ){
  Serial.print( "printing float" );
  Serial.println( f, 2 ); 
}

```

---

<div class="post-metadata">

**Author:** ![econjack](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/econjack/32/1290082_2.png) [@econjack](https://forum.arduino.cc/u/econjack)\
**Post date:** [July 16, 2014, 2:47pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/11 "2014-07-16T14:47:10Z")

</div>

> Its the normal integral conversions which allow them to be converted and assigned, and the same rules apply regardless of ~~weather~~ whether the integer is a literal, variable, or constant.

I was very careful to use the term "expression" in what I said. Normally, if the compiler assigns a "smaller" data type into a "larger" data type (e.g., long = int), the silent cast is done without fanfare. However, the compiler should complain when it assigns a "larger" data type into a "smaller" data type (e.g., byte = int) and it doesn't. While the compiler must use some default data type in the preprocessor pass, it's the resolution of that expression that makes it seem to be typeless.

---

<div class="post-metadata">

**Author:** ![pYro\_65](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/pyro_65/32/214665_2.png) [@pYro\_65](https://forum.arduino.cc/u/pYro_65)\
**Post date:** [July 16, 2014, 3:36pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/12 "2014-07-16T15:36:33Z")

</div>

> econjack:  
> I was very careful to use the term "expression" in what I said. Normally, if the compiler assigns a "smaller" data type into a "larger" data type (e.g., long = int), the silent cast is done without fanfare. However, the compiler should complain when it assigns a "larger" data type into a "smaller" data type (e.g., byte = int) and it doesn't. While the compiler must use some default data type in the preprocessor pass, it's the resolution of that expression that makes it seem to be typeless.

If you ask it nicely, it will provide warnings.

```arduino
void setup() {
  const long l = 2864434397UL;
  unsigned int i = l;
  unsigned int x = 2864434397;
  signed int y = 2864434397;
  char z = 255;
}

void loop() {}

```

> sketch\_jul17a.ino:3:20: warning: large integer implicitly truncated to unsigned type  
> sketch\_jul17a.ino:4:20: warning: large integer implicitly truncated to unsigned type  
> sketch\_jul17a.ino:5:18: warning: overflow in implicit constant conversion  
> sketch\_jul17a.ino:6:12: warning: overflow in implicit constant conversion

---

<div class="post-metadata">

**Author:** ![econjack](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/econjack/32/1290082_2.png) [@econjack](https://forum.arduino.cc/u/econjack)\
**Post date:** [July 16, 2014, 3:52pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/13 "2014-07-16T15:52:05Z")

</div>

True, but compiling with the default settings for the IDE is alarmingly quiet, and those are the settings that most newbies use.

---

<div class="post-metadata">

**Author:** ![MisterG](https://avatars.discourse-cdn.com/v4/letter/m/ee7513/32.png) [@MisterG](https://forum.arduino.cc/u/MisterG)\
**Post date:** [July 16, 2014, 4:11pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/14 "2014-07-16T16:11:13Z")

</div>

Thanks for all the advice 🙂

It looks like "const int" is a good habit to get into for when I get on to more difficult code and, eventually, writing my own. I hadn't seen "const byte" used in the (limited number of) examples I've seen, but I can see how it will save RAM in a bigger application.

This is SO much more complicated than Python... I'm glad my daughter is using the Raspberry Pi at the moment. I have one, too, but I want it to run an arduino in a project I've not thought of yet!

---

<div class="post-metadata">

**Author:** ![TCWORLD](https://avatars.discourse-cdn.com/v4/letter/t/bb73d2/32.png) [@TCWORLD](https://forum.arduino.cc/u/TCWORLD)\
**Post date:** [July 16, 2014, 4:49pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/15 "2014-07-16T16:49:34Z")

</div>

> MisterG:  
> It looks like "const int" is a good habit to get into for when I get on to more difficult code and, eventually, writing my own. I hadn't seen "const byte" used in the (limited number of) examples I've seen, but I can see how it will save RAM in a bigger application.

If it is not used in an array, then it will probably not save any RAM at all - generally const variables (which don't involve pointers) are simply optimised into 'ldi' instructions wherever they are used - much like #defines.

---

<div class="post-metadata">

**Author:** ![cmiyc](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cmiyc/32/1204108_2.png) [@cmiyc](https://forum.arduino.cc/u/cmiyc)\
**Post date:** [July 16, 2014, 6:25pm UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/16 "2014-07-16T18:25:25Z")

</div>

Saving RAM is important, but the key reason to use const, in my opinion, is to make sure you (the programmer) doesn't make a mistake.

> MisterG:  
> This is SO much more complicated than Python...

With complexity comes power. C/C++ are considered lower-level languages than scripting languages like Python. Python offers simplicity, but at the cost of run-time resources. On a PC (or SBC like a Pi), there are usually plenty to spare. On an 8-bit microcontroller with 2,048 bytes of RAM, resources matter.

---

<div class="post-metadata">

**Author:** ![pYro\_65](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/pyro_65/32/214665_2.png) [@pYro\_65](https://forum.arduino.cc/u/pYro_65)\
**Post date:** [July 17, 2014, 6:51am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/17 "2014-07-17T06:51:00Z")

</div>

> econjack:  
> True, but compiling with the default settings for the IDE is alarmingly quiet, and those are the settings that most newbies use.

Its too quiet to tell you the truth, some warnings would be useful.

The IDE adds '_ **-w** _' which means Suppress all warnings, even the ones you mentioned should happen do not ( I agree they should be shown ). So just cos you don't see any warnings, does not mean they never happen. Its a mistake if you ask me, some warnings will point out logic errors which will compile fine.

In 1.0.5/1.5.3 and greater, you only get error messages. I guess they base it on the fact newbies can't understand the messages spewed out. Kind of defeats the verbose output mode, the last error is always shown.

---

<div class="post-metadata">

**Author:** ![TCWORLD](https://avatars.discourse-cdn.com/v4/letter/t/bb73d2/32.png) [@TCWORLD](https://forum.arduino.cc/u/TCWORLD)\
**Post date:** [July 17, 2014, 8:26am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/18 "2014-07-17T08:26:28Z")

</div>

> pYro\_65:  
> Its too quiet to tell you the truth, some warnings would be useful.
> 
> The IDE adds '_ **-w** _' which means Suppress all warnings, even the ones you mentioned should happen do not ( I agree they should be shown ). So just cos you don't see any warnings, does not mean they never happen. Its a mistake if you ask me, some warnings will point out logic errors which will compile fine.
> 
> In 1.0.5/1.5.3 and greater, you only get error messages. I guess they base it on the fact newbies can't understand the messages spewed out. Kind of defeats the verbose output mode, the last error is always shown.

Time to switch to UECIDE! At least that way you get a proper build environment - and can even change the compiler options if you want.

---

<div class="post-metadata">

**Author:** ![pYro\_65](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/pyro_65/32/214665_2.png) [@pYro\_65](https://forum.arduino.cc/u/pYro_65)\
**Post date:** [July 17, 2014, 8:52am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/19 "2014-07-17T08:52:41Z")

</div>

> [@](#):
>
> Time to switch to UECIDE! At least that way you get a proper build environment - and can even change the compiler options if you want.

I have used it and I did like it.

Arduino IDE 1.5.7 now has gcc 4.8.1 and C++11 will be turned on in 1.5.8. You can add -std=c++11 to platform.txt for now (1.5.7). Also all the compiler options can be modified ( just not without restarting the IDE ). The IDE itself still has a way to go, but its improving.

---

<div class="post-metadata">

**Author:** ![darkroomsource](https://avatars.discourse-cdn.com/v4/letter/d/e9bcb4/32.png) [@darkroomsource](https://forum.arduino.cc/u/darkroomsource)\
**Post date:** [July 19, 2014, 10:12am UTC](https://forum.arduino.cc/t/define-int-or-const-int/246329/20 "2014-07-19T10:12:36Z")

</div>

For those new to arduino,

I have been programming professionally since 1978, and could see NO reason to use const instead of define, based on my experience and reading of the documentation.

However, the arduino IDE does NOT differentiate between two defined "variables" with the same root properly  
(In my way of thinking, anyway, it can get confused)  
#define ABC 123.456 \* 789  
#define ABC\_DEF 654.321  
Is replaced with  
#define 123.456 \* 789\_DEF 654.123  
That isn't too bad, it does get resolved properly, but

#define ABC XYZ  
#define ABCDEF QWERTY  
#define XYZDEF ABCDEFG  
Gives  
Gives a compile error (already defined, because ABC is replaced with XYZ in the second line)

#define ABC XYZ  
#define DEF ABCDEFG  
means that when you use DEF you'll get XYZDEFG not ABCDEFG

once I knew that, I was far more careful, but still used defines instead of consts  
Because the documentation led me to believe that consts take up memory, and it is limited

But the I found an include that defined something that caused the same kind of problem. And it took AGES to figure it out. Everything was working, I added a few new functions, and started getting strange results in functions that had been working before, and nothing had changed.

So, I started looking at consts.  
Well, to my surprise,  
Using const int i\_variable\_for\_whatever does NOT use memory under ant circumstances that I have encountered so far.  
AND it is MUCH MUCH easier to ensure that calculations are type converted properly  
const double cd\_pi\_value = 3.14159 ;  
const int ci\_max\_encoder\_clicks = 80 ;  
#define PI\_VALUE 3.14159  
#define MAX\_ENCODER\_CLICKS

double d\_pi\_clicks = cd\_pi\_value \* ci\_max\_encoder\_clicks ;  
vs  
double d\_pi\_clicks = double(PI\_VALUE) \* double(MAX\_ENCODER\_CLICKS) ;  
double() is required, or it doesn't calculate correctly

When compiled, the version with consts uses the same variable storage memory, and LESS programming space  
(Might not for this example, but it did for me full sketch)

So, after 36 years of programming, I have changed my use of constants and defines (on the arduino at least)

[Next page](https://forum.arduino.cc/t/define-int-or-const-int/246329.md?page=2)
