Have a look at
You can also use a custom typedef to handle error - I like this because it allows me to slowly "throw" the error back to a function that could do something about it.
The classic one is when a malloc fails and a novice programmer would puts an exit there spitting out a message like "malloc fail".
Now imagine that you are a user who has spent 2 hours putting sales figures (for example) into the program. Behind the scene one of the malloc calls for a new "employee" struct fails. What does the user then see?...
"malloc fail", and then the program closes. 2 hours of work gone, along with any faith that they have in your program. You can expect an angry/panic phone call asking how to get the data back. If there is another program that does the same thing, you can bet that they'll start looking at prices.
With this very simple example (I'm just typing this on the fly, excuse any errors)
Code:
typedef int iResult;
#define NO_ERROR 0
#define MALLOC_FAIL 1
#define INVALID_ARGUMENT 2
Code:
iResult getMemory(struct fruitStruct **fruit)
{
*fruit = malloc(sizeof(**fruit));
if (fruit == NULL)
return MALLOC_FAIL;
return NO_ERROR;
}
Code:
do
{
switch( getMemory( &fruitBasket ))
{
case MALLOC_FAIL:
perror("Memory allocation error - Would you like to try closing other programs and try again? (Y/N)");
userFeedback = getUserFeedback();
break;
}
}
while (userFeedback == 'Y');
This by itself is a very useless example, but you can see if I was to start adding other things, like initialising values and adding the INVALID_ARGUMENT how I get control of the program when dealing with errors.
You could start adding error handling for other issues such as OVERFLOW and UNDERFLOW and predicting problems before any data gets smashed.
What if the user says that they don't want to try again - What do you want it to do then? Once again, don't suddenly close the program, start thinking of ways to recover.