Start with this I am sure others will have something to add.
Regarding #1
Static makes a variable persistent.
Global variables are already persistent so it makes no sense to use the static modifier with a global.
If you have a value that needs to be persistent but only read or modified from one function you would make it local to that function and static.
Regarding #2
#define uses simple text substitution done by by cpp. The compiler sees a un-named constant, literal, for each instance of your #defined item. If you use "var const" the compiler and debugger see a named variable.
On the surface this seems trivial but if you #define too much stuff what the compiles sees and what you see are different enough to make debugging harder.
Start with this I am sure others will have something to add.
Regarding #1
Static makes a variable persistent.
Global variables are already persistent so it makes no sense to use the static modifier with a global.
If you have a value that needs to be persistent but only read or modified from one function you would make it local to that function and static.
1. you're not exactly correct - if you want a global variable not to be shared with other files (by name), then you'd want to define it as static.
2. I'm looking for an example of exactly what you described - when for example a "value needs to be persistent but only read of modified from one function?" - i'm looking for an example from programmers' "everyday life".
Regarding #2
#define uses simple text substitution done by by cpp. The compiler sees a un-named constant, literal, for each instance of your #defined item. If you use "var const" the compiler and debugger see a named variable.
On the surface this seems trivial but if you #define too much stuff what the compiles sees and what you see are different enough to make debugging harder.
3. I understand.
however say you do: #define X 5 (instead of const int X = 5
if you write somehwere in your code
X = 23;
the compiler would produce an error, as you can't assign a value to the number 5.
so what's the difference?
Static keyword on a global variable makes the variable visible only in the file it is defined. It also changes the linkage from external to internal. This means that if some other module (file) defines a global variable with the same name, the variables do not collide. It is good practice to define global variables in a module as static.
Static keyword on a global variable makes the variable visible only in the file it is defined. It also changes the linkage from external to internal. This means that if some other module (file) uses a global variable with the same name, the variables do not collide. It is good practice to define global variables in a module as static.
I had forgotten about the global aspect of static.
however say you do: #define X 5 (instead of const int X = 5
if you write somehwere in your code
X = 23;
the compiler would produce an error, as you can't assign a value to the number 5.
so what's the difference?
When you debug your code in IDE, you will still see START_TEMP, and not 70.
The compiler will see 70 instead of START_TEMP, as the pre-processor will put 70 every place START_TEMP is written, but you as a user who uses IDE in Debug Mode, will see START_TEMP.
Another distiction that "int const" is supposed to allocate a variable somewhere. It has a size, you can create a pointer to it etc. Embedded controllers have very diverse architectures, so, in theory, it is possible for the compiler to allocate this variable somewhere where it cannot be changed at run time.
"#define" doesn't have anything physical behind it, simply a different way to write the same thing.
When you debug your code in IDE, you will still see START_TEMP, and not 70.
The compiler will see 70 instead of START_TEMP, as the pre-processor will put 70 every place START_TEMP is written, but you as a user who uses IDE in Debug Mode, will see START_TEMP.
What the user sees in the debugger is up to the guy(s) doing that code. Embedded tools historically have had a small market and are not always the best. They may opt to use post cpp code as it is easier.
const is also used to restrict writing to variables, or to make it known that a member function is not going to modify the object instance.
e.g.
Code:
struct MyClass{
int value;
void setValue(const int &newValue) // states that newValue won't (can't) be changed in this function
{
value = newValue;
}
void setValue2(int &newValue)
{
value = newValue;
}
int getValue() const // states that this function won't (can't) change any values in the instance of this class
{
return value;
}
int getValue2()
{
return value;
}
};
The setValue() function can be called with a const int or int type parameter, whereas setValue2() cannot have a const in passed as the parameter. The getValue() function may be called on a constant reference to an instance of MyClass, whereas getValue2() may not.
2. I'm looking for an example of exactly what you described - when for example a "value needs to be persistent but only read of modified from one function?" - i'm looking for an example from programmers' "everyday life".
I am working on a home alarm system, I ended up redesigning it, but originally I used a static local variable in the "PollSensors" function. Each sensor is assigned to a zone and the PollSensors function would read each sensor, compare its current state to its previous state and if one or more sensors in a zone had changed state then the zone status was updated. The static local variable was used to store sensor states, all other functions only cared about zones, not individual sensors so there was no reason to expose the sensor state to the rest of the program, but I needed to store the state between function calls so I could detect a change.
I suspect that behaviour might depend on the architecture, compiler and how you use the variable. On PIC there are two types of ROM (well ROM-ish), the program flash can't be accessed by the program and the data EEPROM is slow to read and can't be directly referenced, so in most cases I suspect const's would be treated like any other variable and be stored in RAM, but at least they would only be stored once. If you used #define then they would be stored in program flash multiple times.
heydonms, Pommie
It seems that you both says opposite thing.
Pommie, you said that the const are stored in ROM, while heydonms you said that they are stored in RAM?
but at least they would only be stored once. If you used #define then they would be stored in program flash multiple times
I am saying they would be stored in RAM on a PIC because the alternative is too complicated to implement on that particular hardware, for too little gain and no one would bother creating a compiler to do it. If you are working on an architecture that has ROM in the same address space as RAM then Pommie's description is far more likely to be correct.
Knowing how variables will be handled just comes down to knowing the hardware you are working on.
#define's are handled by the preprocessor using a basic search and replace before the source is sent to the compiler, if you define a name for a long string, then by the time it hits the compiler all it sees is a bunch of strings. If it is very good at optimising it might figure out they are the same and only store them once, but I suspect that isn't common. Where as if you use a const (or a normal variable for that matter) the string is stored once in the program (where the variable is initialised), copied into RAM and from then on all future references to it are just pointing to an address in RAM.
EDIT:
After a bit more research it appears some compilers do store a single copy of duplicated strings, but it seems to be limited to larger OO languages (java, .Net, etc.) probably not going to happen with C on a micro.
I'd like to enhance my knowledge in ROM / RAM management.
for example, i didn't know the following fact that you mentioned:
Where as if you use a const (or a normal variable for that matter) the string is stored once in the program (where the variable is initialised), copied into RAM and from then on all future references to it are just pointing to an address in RAM.
Most of what I talk about tends to be specific to a subset of PIC chips, because that is what I mostly work on so don't take any of it as universal truth.
If you are interested in a particular family of uC then datasheets are probably as good a starting point as anything.
If you are interested in general concepts then maybe start by reading up on harvard and von neumann architectures, address spaces...and nothing else springs to mind right now...