Pages: [1] 2   Go Down
Author Topic: #define vs. static const  (Read 1816 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a lot of named references to memory locations to in my code, and I'm curious if it would be wiser to use #define instead of static const to define them.

This is what I have:
Code:
static const word EPROM =    0xB600;  //EEPROM Location
static const word EXTRAM2 =  0xB800;  //EXTRAM Location
static const word LCD_CTL =  0x3000;  //Control register of LCD
static const word LCD_DATA = 0x3001; //Data register of LCD
static const word HIRAM =    0xBFFF;    //Highest address for 32k * 8 RAM

This is what I'm considering
Code:
#define EPROM 0xB600  //EEPROM Location
#define EXTRAM2 0xB800  //EXTRAM Location
#define LCD_CTL 0x3000  //Control register of LCD
#define LCD_DATA 0x3001 //Data register of LCD
#define HIRAM 0xBFFF    //Highest address for 32k * 8 RAM

I know static const is the preferred method, but I have a lot of these and thought #define would be better as it is a direct substitution and won't eat up memory.

Reasons to pick one over the other?
Logged

Ayer, Massachusetts, USA
Offline Offline
Edison Member
*
Karma: 54
Posts: 1848
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In C++, the compiler treats a 'const int a = value' similarly to #define (other than const int being properly scoped).  You can use it as an array bound for instance.

If you were using C, instead of the C++ that the IDE uses, then const int's at the global level do allocate space, and when you use the value, it loads it from memory.  You can't use it as an array bound without the compiler using variable sized arrays.

If you use #define, the compiler does a textual substitution anytime it sees the name, so you can't use the same name for instance as a member of a structure.

On systems with real source level debuggers, const int values are more often available in the debugger for use in expressions.  However, this isn't an issue for Arduino, where debugging consists of blinky lights or Serial.println's.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So "const int foo = value" won't result in memory being allocated for "foo" when it's compiled in the Arduino IDE?
would "static const int foo = value" be the same then? 

If I used "#define TempRead 20", then later on in my code had "int TempReading = 1;", would it get converted to "20ing = 1;" by the preprocessor?

Thanks
Logged

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

Reasons to pick one over the other?

Const values are explicitly typed, and #defined literal values are not. Const values have a defined scope and namespace, and #defined literal values do not. Before const definitions were supported, using #defines for the literal values was the best option. Now that const definitions are available, there is no good reason to use #defines for constants. Const values do the same job, better.
Logged

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

London
Offline Offline
Edison Member
*
Karma: 47
Posts: 1432
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

However, this isn't an issue for Arduino, where debugging consists of blinky lights or Serial.println's.

How much easier it would be to find our coding errors if we could 'run to' a point in the code and then 'step' from there, like real debuggers allow you to do.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49258
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A "real debugger" is another process on the same computer. When you have developed an operating system for the Arduino that supports multiple processes, then you can think about running a "real debugger" on the Arduino.

Let us know when it is ready.
Logged

Ayer, Massachusetts, USA
Offline Offline
Edison Member
*
Karma: 54
Posts: 1848
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A "real debugger" is another process on the same computer. When you have developed an operating system for the Arduino that supports multiple processes, then you can think about running a "real debugger" on the Arduino.

Let us know when it is ready.
GDB supports various embedded platforms by linking a stub program in with the user's program.  Typically this stub is fairly small, and most of the smarts are on the host side.  It can also be done by simulating the target chip.  For example, it looks like there was a WinAVR that supported AVR chips via GDB, though the last release was in 2009.  CrossPack for AVR that runs on the Mac looks like it is maintained and more recent.  So, it can be done, it is just nobody has stepped up to do the work for the Arduino.
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3013
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Defining things as "word"  seems to be an obscure and obfuscatory thing to do.
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 70
Posts: 2171
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Remember, const isn't always a compile time constant.

If you really have constant values, and and want to guarantee they are compile time constants: simply use an enum.
Then the values aren't cast if the datatypes don't match, they will be natural type of the L-Value.

Code:
enum{
  EPROM = 0xB600,  //EEPROM Location
  EXTRAM2 = 0xB800,  //EXTRAM Location
  LCD_CTL = 0x3000,  //Control register of LCD
  LCD_DATA = 0x3001, //Data register of LCD
  HIRAM = 0xBFFF ,   //Highest address for 32k * 8 RAM
};
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Remember, const isn't always a compile time constant.

Oh?

Quote
I have a lot of named references to memory locations to in my code, and I'm curious if it would be wiser to use #define instead of static const to define them.

I would just use const rather than "static const". The use of "static" has an effect (if any) other than what you intend, which is to not make the constant exported to the linker.

I prefer the use of const variables because defines are just a text substitution, whereas const variables are typed. Also the error messages which arise from them (when they happen) are less confusing.

We have shown before that const "variables" (is there really such a thing?) do not take up memory.
Logged


Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49258
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Defining things as "word"  seems to be an obscure and obfuscatory thing to do.
It's a Microsoft thing, I'm sure.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Microsoft does a lot of interesting things. I use the word in the sense of "may you live in interesting times."
Logged


Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49258
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Microsoft does a lot of interesting things.
Yes, and obfuscation is near the top of the list. Why use a standard type when you can invent 14 levels of indirection to hide that.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for all the info, I've left it consts (which can be changed via pointers AFAIK).  We've kind of diverted a bit, but is there a fundamental difference between declaring something a word, vs. an unsigned int vs. a uint16?  I just picked word because I'm doing a lot of stuff with bytes and double bytes and think of it that way.  Plus it's the shortest name to type smiley
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18764
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

From Arduino.h:

Code:
typedef unsigned int word;

However I should caution you about this define in the same file:

Code:
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);

#define word(...) makeWord(__VA_ARGS__)

Logged


Pages: [1] 2   Go Up
Jump to: