Not Keil specific; one for the 'C' experts:
Why would one put 'static' variables definitions in a header?
eg, in a header file:
/* * TCO count to temperature conversion table. */ static erTcoTableStruct tcoTableOPUS1[] = { /*{TCO,Temp,} */ {1,-99}, {4,-45}, {5,-40}, {8,-35}, {11,-30}, {16,-25}, {22,-20}, {29,-15}, {37,-10}, {48,-5}, {61,0}, {78,5}, {99,10}, {124,15}, {153,20}, {188,25}, {227,30}, {270,35}, {315,40}, {365,45}, {420,50}, {481,55}, {549,60}, {625,65}, {710,70}, {805,75}, {910,80}, {1010,85}, {1060,88} };
AIUI, the whole point of so-called "header" files in 'C' is to share stuff between source files;
But the whole point of the 'static' keyword (at file scope) in 'C' is to make stuff private so that it is not visible to other modules - ie, not shared.
So I can't see why one would want to have 'static' definitions in a header?!
I agree: having identically-named and identically-typed but distinct objects sounds very dodgy to me!
I think MISRA frowns upon it - even for automatic variables?
I don't always agree with MISRA.
But since you & Tamir bring up the 'same name' issue, you must realize that the compiler shall complain if it doesn't appear in the 'extern' area in addition to the data-allocation area. So such maintenance shall be caught by the compiler.
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA
Actually, they will be caught by the Linker!
And nothing can catch the error where you thought your were accessing the 'x' in this.c but you're actually accessing the 'x' in that.c...
Can you imagine to total nightmare one code-monkey might end up in, when such statics are passed as parameters, and the wrong/inappropriate configuration is used, but it does not affect the function that is called so the code-monkey can't immediately tell what's happening...? In other words: Sorry captain, I usually agree with just about anything you write, but not this time...
The key dis-advantage that I see to headers of the form
#if MAKE_DEFINITION unsigned int x; // This is a definition #else extern signed int x; // This should be the corresponding declaration #endif
is that the compiler only ever sees either one or the other; so it can never verify that the two match - or, conversely, report that they don't!
That's why I prefer: file1.h
extern signed int x; // declaration
file1.c
#include "file1.h" // The declaration is visible unsigned int x; // definition: // The compiler can now see both declaration & definition // and, therefore, can report any discrepancy
file2.c
#include "file1.h" // The declaration is visible; // this file just references the external object
Andy, I understand your concern. I used copy-n-paste for the externs required.
Tamir,
You are right in that people with lesser skills shall screw things up really fast.
All I can suggest is that you try 'my' method for a small project, and you'll get the hang of it.
The reason I do it this way, is that I realized that the #include process is generally uncontrolled, and I wanted a way of controlling which files get included and when... and to ensure that all common files are indeed common to all modules.
Came accross this 'hiring' test for embedded programmers that may amuse and challenge some. Regarding use of the keyword static:
6. What are the uses of the keyword static?
This simple question is rarely answered completely. Static has three distinct uses in C:
(1) A variable declared static within the body of a function maintains its value between function invocations.
(2) A variable declared static within a module, (but outside the body of a function) is accessible by all functions within that module. It is not accessible by functions within any other module. That is, it is a localized global.
(3) Functions declared static within a module may only be called by other functions within that module. That is, the scope of the function is localized to the module within which it is declared.
Most candidates get the first part correct. A reasonable number get the second part correct, while a pitiful number understand the third answer. This is a serious weakness in a candidate, since he obviously doesn't understand the importance and benefits of localizing the scope of both data and code.
...BRUTAL...
The complete test, if your interested, is here: www.embedded.com/.../0005feat2.htm
Indeed - so, again, why would one put static definitions in a header file?!
You're declaring them static to localise their scope - so why try to extend it by putting them in a header?!
Unfortunately, this seems to be a 'loophole' within the standard ,as no real information is defined for header files. This should, at the very least, generate a warning/error message.
According to spec: "If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined."
(A translation unit being a source file and all headers referenced in it.)
Furthermore, the only requirement of the 'translation enviornment' (ie: compiler/linker) is:
"A conforming implementation shall produce at least one diagnostic message (identified in an mplementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined."
But since each source file is it's own 'translation unit' there are no requirements to flag this usage.
Moral: You can really do some damage without knowing it. I hope none of this code is used within heavy machinery.
I hope none of this code is used within heavy machinery.
Don't worry, the code is in the very capable hands of the good old caption. Oh, by the way, he is the guy that protects us from the ultimate bad guys - his stuff explodes. Heavy enough for you ? ;-)
As long as the vector is outgoing.
I don't think so.
"no real information is defined for header files."
Header files are just verbatim text inclusion, so the Compiler itself knows nothing about them. They are effectively irrelevant as far as the Compiler is concerned.
"If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined."
But that's not happening here - the header file is just creating identifiers with internal linkage. Nothing else.
But since each source file is it's own 'translation unit' there are no requirements to flag this usage. is in effect what you stated: "the header file is just creating identifiers with internal linkage"
And since the header files are "just verbatim text inclusion" if its syntatically correct, including using static keyword, can be used. The 'loophole' being just that, that there either should be some limitation or flagging of this type of use within a non-source or non .c file.
Just my opinion.
Not to prolong this thread too much longer, but another discussion not broached deals with 'how efficient' this usage is.
To that end I found an article that may be of interest...
www.eetimes.com/.../showArticle.jhtml
I know it is syntactically correct - that wasn't the question.
The questions was why anyone would want to do it?
So you can further argue your point of view??
I think this question has been answered. The developer explained the reasons for why it was used, which is more than you can usually expect from a code snippet.
It was also estabished that this is not the most efficent way to code. But, the developer seems to be in high regard within this community and I personally have no issue with the way he wants to code something. If it is a preference, and it does not violate the responsibilities entrusted to an engineer regarding safety and reliability then it is allowed.
Would I use this approach? I believe that question has also been answered.
There is no absolutely correct way to code to solve a problem. There are only more efficient and effective ways to do it. If the coding solution is accomplished within established guidelines and is well documented so be it. The fix would be easy enough: static --> const
Finally, if it is expected that someone else will post the why to this question, knowing full well the bias of this thread regarding why you should not use this approach, given a choice, do you really expect someone to do this? Only if they like to argue a point.
As far as I'm concerned, this was nothing more than an academic exersize.
Cheers.