We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have some code running on an 8051 based processor that is quite large and complex and it also uses a few arrays. To make sure that I can avoid mistakes accessing memory location that do not exist, I'd like to know if there are anyway to get the C51 Compiler to catch this type of mistakes.
BYTE xdata myArray[8] BYTE i; for (i=0;i<10;i++) myArray[i]=i;
The compiler has no problem with that and doesn't report memory leaks. Are there any ways to make the compiler to generate an error or even a warning?
PC-lint will catch that type of mistake.
http://www.gimpel.com/
1) that is not what I call memory leaks, It is BUGS. 2) the example you give is BAD, it uses a numeric value which should make it obvious that this is wrong. 3) it not ythe purpose of a compiler to protect you against yourself 4)it is very easy to do a thing like #ifdef DEBUG if (var > sizeof myArray) { make the program error out } #endif
Erik
Thanks Dan, I'll have a look
I agree with you Erik, you could call that a bug, What you suggest with the #ifdef, is good, I didn't think of it. Thanks for that.
Laurent
#define MYARRAY_SIZE 8 BYTE xdata myArray[MYARRAY_SIZE] BYTE i; for (i=0;i<MYARRAY_SIZE;i++) myArray[i]=i;
"Not creating bugs" is often preferable to "finding and fixing bugs".
As already noted, this is not what the term "memory leak" usually means: a "memory leak" is when you use dynamic allocation, but don't fully release the memory when you're finished with it. The risk of such problems is one reason why dynamic allocation is usually avoided in embedded systems...
What you're talking about requires runtime array bounds checking. That means adding code at every array reference to validate the index before using it. In 'C', this would probably be pointless without also having some sort of runtime check on all pointer accesses.
The overhead in terms of both execution time and code size is likely to be impractical on an 8051-based system
"I'd like to know if there are anyway to get the C51 Compiler to catch this type of mistakes"
This kind of error is not detectable at compile time, so no compiler can catch it.
However, things like Lint can check for constructs that are susceptible to the risk - and warn you about that.
This is the classic problem with Magic Numbers!
Don't use a Magic Number for your array size or your loop test:
#define MY_ARRAY_SIZE 8 BYTE xdata myArray[ MY_ARRAY_SIZE ] BYTE i; for ( i=0; i < MY_ARRAY_SIZE; i++ ) { myArray[i]=i; }
Note also the use of braces, even though they are not strictly necessary in this case.
Try doing some searches on "defensive programming".
You might also have a look at the MISRA rules...
#ifdef DEBUG if (var > sizeof myArray) { make the program error out } #endif
But how does that square with the "Debug what you fly; fly what you debug" mantra...?
It does not. However, there is such a thing as "a piece of added code to see if the bug you found while you Debug what you fly, fly what you debug originate in this place".
I DO have flycatchers in production code, but only for places where outside stimuli may cause e.g. a variable to be outside bounds, as far as "internally generated" values, I do not.
Try doing some searches on "defensive programming". You might also have a look at the MISRA rules...
Would you elaborate on that,
"Would you elaborate on that"
Just put those terms into your favourite internet search engine, then you can learn about "defensive programming" and "the MISRA rules"...
Hint: "internet search engines" include Google, AltaVista, etc...
Andy said:
A deep static code analyser like QAC should find the bug (in this particular case). It's better to use defensive coding techniques though.
This reminded me of a technique we used for a long time when indexing through arrays. Rather than #define a constant for the array size, we used the following:
for (i=0; i<(sizeof(array)/sizeof(array[0]); i++) { . . . }
Obviously, you can't use this on external arrays where the specific size isn't included in the array declaration. Jon
"This reminded me of a technique ..."
And for which we have as one of our standard macros:
#define DIM(a) (sizeof(a) / sizeof(a[0])) for (i=0; i<dim(array); i++) { . . . }
Nice macro, I've just found a use for it!