Pages: [1] 2 3   Go Down
Author Topic: Const vs #define  (Read 6541 times)
0 Members and 1 Guest are viewing this topic.
Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 2
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Although #define is deprecated over const in the Arduino Reference Manual, and in C++ books is stated that there is little need for it, I note that its use is quite common in Arduino code.  Why is this - particularly as there's no overhead in using const?

I ask because I was a confirmed #define user until I got bitten by a bug in a macro. It was such an unpleasant experience that I now avoid it and always use const..

Jim
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8842
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pre-processor directives such as #define existed in C long before the 'const' storage class.  Old-school programmers go used to using #define for constants.  You can also use an enum to create named constants.

It is possible that a 'const int' will take up memory space even if it not used.  That would be a problem for libraries that define a large number of constants.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As preprocessor macros are pre-processed and not compiled, they themselves don't take up any memory / flash.  Only their contents do.

So if a macro is not used then it won't take up any room.  If it contains 1 byte then it will take up 1 byte per usage (depending on context).

const variables are real variables with real allocated space - whether they are used or not.

One thing that a const cannot do which a #define can is selective compilation and inline replacement.

#defines are absolutely perfect (and the only way) for making code that will compile on multiple platforms with different settings/features.


Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

const variables are real variables with real allocated space - whether they are used or not.

Please provide evidence or references.
Logged

Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 2
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the replies.

I'm pretty sure that when I changed my code to use 'const ints'  rather than '#defines', the compiled code wasn't any larger.

Jim
Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Please provide evidence or references.

http://www.nongnu.org/avr-libc/user-manual/pgmspace.html:

Quote
A Note On const

Many users bring up the idea of using C's keyword const as a means of declaring data to be in Program Space. Doing this would be an abuse of the intended meaning of the const keyword.

const is used to tell the compiler that the data is to be "read-only". It is used to help make it easier for the compiler to make certain transformations, or to help the compiler check for incorrect usage of those variables.

For example, the const keyword is commonly used in many functions as a modifier on the parameter type. This tells the compiler that the function will only use the parameter as read-only and will not modify the contents of the parameter variable.

const was intended for uses such as this, not as a means to identify where the data should be stored. If it were used as a means to define data storage, then it loses its correct meaning (changes its semantics) in other situations such as in the function parameter example.

for one.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 2
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, P138 of my 'Stroustrup' says with regards to macros:

"The first rule is: Don't use them if you don't have to."

and on P140:

"The const, inline and template mechanisms are intended as alternatives to many traditional uses of preprocessor constructs."

Seems pretty clear to me, which is why I asked why people are so 'gung ho' about #defines!

Jim
Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In a "traditional" (i.e., Princeton) architecture there's very little to chose between them.

However, with a microcontroller, with the Harvard architecture, using #define on a number guarantees that the number will end up in program space as it is literally just a number.  Using "const" just makes it read-only and doesn't guarantee that it is in program space, thus taking up precious RAM when you don't need to.

However, if speed is what you want then const (in RAM) is faster that a number (in PROGMEM) as the PROGMEM will have flash wait states associated with it that you don't get with RAM.

It's all a matter of tradeoffs.  Faster access + wasted memory, or slower access + more RAM available.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Offline Offline
Edison Member
*
Karma: 48
Posts: 1628
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
P138 of my 'Stroustrup' says with regards to macros
Does "macros" refer to all uses of #define? I would differentiate between using this:
Code:
#define LEDpin 13
which simply defines a manifest constant, and this (obviously fictitious) example:
Code:
#define READ_SOMETHING(a,b) { b = read(a); \
     C = b*something_else(); \
}
which can potentially cause problems if not used correctly, especially by someone other than the original author who's modifying/debugging the code later on.

Furthermore:
Quote
alternatives to many traditional uses
clearly implies that const is not a replacement for all such uses.

Pete
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You make the claim the const variables always allocate space...

Quote
const variables are real variables with real allocated space - whether they are used or not.


As a reference you site compiler documentation that states that const variables may or may not allocate space...

Quote
const was intended for uses such as this, not as a means to identify where the data should be stored


I suggest you spend a bit more time searching.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12631
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

const variables are real variables with real allocated space - whether they are used or not.

Please provide evidence or references.


Any potential optimisation is up to the compiler, isn't it? What does the Arduino IDE actually do with const variables (used or otherwise)?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Using "const" just makes it read-only and doesn't guarantee that it is in program space,

True.

Quote
thus taking up precious RAM when you don't need to.

Only true for consts placed in SRAM.  What about consts that are optimized into simple values?

Quote
However, if speed is what you want then const (in RAM) is faster that a number (in PROGMEM) as the PROGMEM will have flash wait states associated with it that you don't get with RAM.

Why are you bringing PROGMEM data into the discussion?
Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Why are you bringing PROGMEM data into the discussion?

Because that highlights a big distinction between const and #define.

A const may be in either RAM or PROGMEM.  A value in a #define will always be in PROGMEM.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A value in a #define will always be in PROGMEM.

Ah.  There it is.  The source of the confusion.  You're misusing the word PROGMEM.

A #define of a simple constant will always be part of one or machine instructions stored in Flash.  Which is also true for const declarations of simple constants.  In the GCC-AVR world, they produce exactly the same code (a few machine instructions) and consume exactly the same amount of SRAM (zero).

const has the benefit of including a datatype.  #define has the benefit of living in the preprocessor's world.  Pick the one that suites the need.
« Last Edit: January 12, 2012, 04:21:44 pm by Coding Badly » Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Any potential optimisation is up to the compiler, isn't it?

Yes.  And the linker.

Quote
What does the Arduino IDE actually do with const variables (used or otherwise)?

This...

  static const int MagicNumber = 42;

...and this...

  #define MagicNumber  ((int)(42))

...produce exactly the same code in all expressions.  They are interchangeable.

You can exclude static if the symbol is not defined in any other modules (which is almost always the case).
« Last Edit: January 12, 2012, 04:22:15 pm by Coding Badly » Logged

Pages: [1] 2 3   Go Up
Jump to: