Here are coding techniques that I have been learning for many years working in Embedded Systems field.
Hope these can be useful for you.
1. About C Coding
1.1) Things that must be careful about local parameter declaration.
Ex :
void A(){
char *a;
int b;
int c[100]
a=(char*)malloc(sizeof(char*10));
//do function
}
In this case you must initial charactor array c because local parameter may has junk value as an initial value and might effect your program algorithm.
such as : c[i]=c[i]+1; // in your logic it might be 1=0+1; but because of junk value it might be 211=210+1;
so,the best way to due with local parameter is ALWAYS initialize it.
Ex:
void A(){
char *a=NULL;
int b=0;
int c[100]
memset(c,0,sizeof(c));
a=(char*)malloc(sizeof(char*10));
memset(a,0,sizeof(a));
//do function
}
1.2) [static] keyword meaning...
- Inside function with static variable : This means this variable value will keep it value no matter how many times the function is called.
Ex:
void B(){
static i=0;
i++;
}
int main(){
int j=0;
for(j=0;j<10;j++)
B();
//At this line value of i = 9
}
- static function : This means to locallize your function to be reach this c file only. It won't be called by outside scope of the c file.
Ex:
//in testA.c file
static int the_one_function(){
//do function
}
------------------------------------------------------
//in testB.c file
int the_two_function(){
//call fucntion the_one can not be done.
the_one_function();
}
- static global variable : same as static function (I believe), It will limit scope of using static variable just on that c file and can not be access by the others.
Ex:
//in file testA.c file
static int global_x=0;
------------------------------------------------------
//in file testB.c file
global_x=1; //this should not be done.
The above code will give an error during the compile time.
1.3) too much clever compiler optimizing.
Due to lack of experiences, I had faced some kind of weired problem while developing c code for microcontroller.
with my code to doing some delay like...
int a=0;
for(a=0;a<1000;a++);
After build the binary and run on real machine.These code has no effect!! Why? The reason is compiler's optimizing function consider these two lines of code are no meaning and just cut them out. So, be careful of your compiler optimize setting. If it not that sensitive just turn it off.
Or you might try to using volatile keyword.
int volatile a=0;
for(a=0;a<1000;a++);
volatile is keyword that tell compiler not to do trick with this variable and no optimizing.
2. About Coding style
2.1) declaration of constant value, should declare with human language for bettter understanding the meaning of declaration.
Ex:
#define MAX_VALUE (200)
generally constant value should define with all capital alphabet. MAX_VALUE is clearly understand that this is the maximum value
moreover,(200) is the better way to declaring the value to a constant. Because of some ambiguity equation that might happen.
Ex:
#define MAX_VAULE -100
a=b-MAX_VALUE;
In this case, a=b-MAX_VALUE; might look like a=b--100; when compiling and giving a compile error.
so,it is better to declare like this
#define MAX_VALUE (-100)
Then the meaning is a=b-(-100) and everything is back to normal sense.
2.2) Avoiding making ambiguous condition
if(a){
//do something
}
this is equal to...
if(a!=0){
//do something
}
It might be convenience for expert programmer to do short form condition but it producing a lot of confusing when checking the code and might be the cause of bugs.
So, It would be better to write in full form condition.
2.3) Things you should do when enter into function.
- check passing parameter
Ex:
int func_a(int par1){
if(par1<0)
return(-1)
//do function
}
In case that is unnessery to continue processing in function which the passing parameter is already wrong value.
So,you should return error at the first time.
- always de-malloc,free resource before return
Ex:
int func_b(){
char * c=NULL;
c=(char *)malloc(sizeof(char*10));
//do function
if(result==1){
free(c);
c=NULL;
return (-1);
}
free(c);
c=NULL;
return (-1);
}
This always the cause of all memory leak if you reserved space in heap memory and didn't clear it when you left function.
You might confuse about the concept of using malloc. I'm not the expert on this topic but it would be safer to free every unuse variable that had been malloc.
For my understanding...
1. all the array variable that declaring in function are using STACK to storing value. So,it will automaticlly clear when it leaving the function.
2. all the variables that using malloc (in function or global variable) are using HEAP to store value. So,you must FREE it manually and not other way else.
Moreover, when your free the variable, You should point the pointer to NULL because free is not point your variable to NULL after clear the space. And if you check the code like this after called free ...
if(c==NULL)
c=(char *)malloc(sizeof(char*10));
This may not be done because pointer c is point to unknown place and not NULL value.Or getting worse if you access to use pointer c that contain unknown value, critical error may occurred.
Moreover, When you try to free a pointer that already free some double free problem always crash your program.
Ex:
char * c1=NULL;
c1=(char *)malloc(sizeof(char)*10);
//do something
free(c1);
free(c1);
this code will give an critical error like....
*** glibc detected *** ./testc: double free or corruption (fasttop): 0x081b2008 ***
So,If you point pointer c1 to NULL after free. double free problem will not happen (Anyway, It not the right thing for you to do double free code)
free(c1);
c1=NULL;
free(c1);