Jump to content
Sign in to follow this  
edt

Static Const

Recommended Posts

I've been using static const definitions in my C header files, and I just noticed they're all going into RAM. I expected these to stay only in compiler memory and to be put in the code as literals when they're necessary.

 

Coming from assembly, I'm well aware of the differences between #define directives and const definitions, and I much prefer the typechecking etc. of consts, but perhaps I'm misusing 'static const'?

 

Is this an enhancement for a future version or am I missing something?

Share this post


Link to post
Share on other sites

edt,

but perhaps I'm misusing 'static const'?

It has been said that the "static" keywords is overused in C (and C++).

If used in conjuction with a variable definition it means that the variable has static linkage, that is that particular variable is only visible in the .c source file in which variable is declared. This means a variable declared as static in a header file will have a unique instance in each .c file the header file is included in. Take away static and you will end up with a linking error (if the header file is included in more than one file).

 

"const" indicates that the data can't be changed, but a variables const-ness can be cast away, so that variable still needs to reside in RAM.

 

The storage class specifier that indicates data is store in ROM is rom. Unfortunately that currently doesn't work on data other than strings.

 

Regards

Dave

Share this post


Link to post
Share on other sites

If data is "stored in ROM", then it will still have a separate data location in ROM and then be loaded from that location on every use, correct? I was aiming for a global type-checked constant that was always treated as a literal (and resolved before link-time). For example, I wanted this:

1: static const unsigned char MY_NUM = 5;
; (no instructions)
2: my_var = MY_NUM;
movlw 5
movwf my_var

without the value 5 being placed in any other RAM or ROM.

Share this post


Link to post
Share on other sites
If data is "stored in ROM", then it will still have a separate data location in ROM and then be loaded from that location on every use, correct?  I was aiming for a global type-checked constant that was always treated as a literal (and resolved before link-time).  For example, I wanted this:

1: static const unsigned char MY_NUM = 5;
; (no instructions)
2: my_var = MY_NUM;
movlw 5
movwf my_var

without the value 5 being placed in any other RAM or ROM.

Forget the word static (in this case it has nothing to do with what you want).

 

rom const unsigned char MY_NUM = 5; // not currently supported

But as you suggest this would be nice.

 

The best approach currently is:

#define MY_NUM 5

 

Regards

Dave

Share this post


Link to post
Share on other sites

But with the ROM keyword, if it were supported yet, I think the single value will be placed in a specific data block in a predetermined ROM location and then read from ROM into a register for each reference to it. That's not what I want. I want that constant to be completely resolved into a literal before the linking stage just as if I had used #define.

 

I do intend to use "static" because I don't want the linker to know that I named the constant. I only want it accessible from one source file to another through an #include, just like a #defined constant would be. The multiple "independent copies" of the constant are only a problem if each declaration reserves RAM or ROM instead of constant folding the value as I'd hoped.

Share this post


Link to post
Share on other sites

To me using "static const blah" doesnt make sense ....

 

The "static" keyword in std C/C++ refers to a persistant mutable data location for a function

to access needed data the next time it runs.

 

Where as "const" is an unmutable (or was that im?) storage holder, usually for the duration of a function process.

 

So using both together ... i've never tried using them together but i would have expected the

compiler to balk at it.

 

As for ROM space, i belive bothe MCC18 and the HITechC compilers place this data in the last

usable sections of the internal flash. i say usable because other chunks get used up by things

like bootloaders and ICD debugging code, etc

But it would be nice to have "rom" work on other things than strings... especially my address

arrays for onewire devices.

 

If anyone knows a case where using "static const blah" makes sense i would very much like

to see an example code snippet and the reasoning behind it.

Share this post


Link to post
Share on other sites
The "static" keyword in std C/C++ refers to a persistant mutable data location for a function to access needed data the next time it runs.
the "static" modifier actually has two unrelated uses. Inside a function scope it means "persistent across calls" like you were saying, but when used in a global context it means "local to this source file."

 

A static value is not globally accessible, so it's irrelevant to the linker. The const keyword should clue in the compiler to an opportunity for value propagation. AFAIK, a "static const" value could function identically to a #define except for two things: type safety, and an address. (I know a #define only uses text substitution, but the effect should be the same).

 

Anyway, my point from the first post was that unless the value is dereferenced (with the & operator), I don't see any reason not to propagate the literal value all the way through to the instructions that use it and completely remove it from RAM and from any explicit data sections in ROM.

 

Here's a better example of what I mean by propagation:

1: static const unsigned char MY_NUM = 3;
2: my_var += MY_NUM;
  movlw 0x3
  addwf my_var

The value 3 only exists in the movlw instruction, never in RAM, and it doesn't need to be fetched from a table somewhere in ROM.

 

All I wanted was efficient type-checked constants, it wouldn't need to be with "static const," but it seemed like that should do what I want and I don't see any other syntax that would. I've been using #defines anyway, but I always had to use them when I was working in assembly and I've been wishing for something else.

Share this post


Link to post
Share on other sites

i had forgotten about that second case as i rarly use it, in general i try to avoid

globals unless it is unavoidable.

 

But i must say that using "const static" as an alternate form of a macro definition...

btw how does using "static const" assure type safety? From my understanding

all macro values are of void datatype so they can be used as any needed type and

if you cannot change the value how can you violate it's use? bad programming or

a broken compiler?

 

In the same hand if it is a runtime compile substitution why would you need an

address and what would you use/need an address for something that cannot change

since it is passed at compile time? i do not see any valid reason to pass it as a pointer

or as a dereferenced address to anything ...

hmm on second thought i suppose you could use it as an indexed bit mask that way.

 

It is a very interesting idea i must say, now i am trying to think of ways that it would be

useful to me :D

Share this post


Link to post
Share on other sites
btw how does using "static const" assure type safety?
#define is completely handled by the preprocessor, so all it can do is substitute text. Const definitions (static or not) must have a type, and since they're processed later, they work a bit better. For instance, you could
#define MY_VAL 3
static const unsigned char MY_CONST = MY_VAL;
#undefine MY_VAL

but if you try it with

#define MY_CONST MY_VAL

it would actually evalute MY_VAL after you #undefined it. There's the same kind of text-substitution vs. syntax-checking issue between macros and inline functions.

In the same hand if it is a runtime compile substitution why would you need an

address and what would you use/need an address for something that cannot change

since it is passed at compile time?

First off, "dereference" wasn't the right word there...I always get them confused. I meant "take the address of," but I think you understood that anyway. It's the prefix & as in "addr = &var", not the infix "bit = 0x08 & var".

 

I haven't found a use for it myself, but I'm sure someone has/will. If the constant gets propagated and optimized out of existence, as I'd hoped it could, it wouldn't have an address. Either it would have to return NULL or some dummy value for the address, or it would have to disable the optimization for any values that need an address. The first option would be easier, but the second would be the most correct (and not too much harder since it's static and only needs to check one file at a time).

Share this post


Link to post
Share on other sites
In the same hand if it is a runtime compile substitution why would you need an

address and what would you use/need an address for something that cannot change

since it is passed at compile time?

I haven't found a use for it myself, but I'm sure someone has/will. If the constant gets propagated and optimized out of existence, as I'd hoped it could, it wouldn't have an address. Either it would have to return NULL or some dummy value for the address, or it would have to disable the optimization for any values that need an address.

I think I figured out why the address of a const might matter. You could have a const array, which would need an address if the indexes can't be simplified to constants. In cases where the literal couldn't be propagated, ROM storage would still be much better than RAM.

 

On a related note, I've been pondering whether the linker could handle a global (non-static) const in the same way. It seems to me that provided it's not an array, and all the object files are compiled with the same version compiler, the linker could export the value of the const instead of its address. Not necessarily suggesting that for sourceboost, but could that be possible/practical?

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...