Sample Video Frame
Exercise 19: Zed's Awesome Debug Macros
There's a reoccurring problem in C that we've been dancing around, but I'm going to solve it in this exercise using a set of macros I developed. You can thank me later when you realize how insanely awesome these macros are. Right now, you don't know how awesome they are, so you'll just have to use them, and then you can walk up to me one day and say, "Zed, those debug macros were the bomb. I owe you my first born child because you saved me a decade of heartache and prevented me from killing myself more than once. Thank you, good sir, here's a million dollars and the original Snakehead Telecaster prototype signed by Leo Fender."
Yes, they are that awesome.
The C Error Handling Problem
Handling errors is a difficult activity in almost every programming language. There are entire programming languages that try as hard as they can to avoid even the concept of an error. Other languages invent complex control structures like exceptions to pass error conditions around. The problem exists mostly because programmers assume errors don't happen, and this optimism infects the type of languages they use and create.
C tackles the problem by returning error codes and setting a global
errno value that you check. This makes for complex code that simply exists to check if something you did had an error. As you write more and more C code, you'll write code with this pattern:
- Call a function.
- Check if the return value is an error (and it must look that up each time, too).
- Then, cleanup all the resource created so far.
- Lastly, print out an error message that hopefully helps.
This means for every function call (and yes, every function), you are potentially writing three or four more lines just to make sure it worked. That doesn't include the problem of cleaning up all of the junk you've built to that point. If you have ten different structures, three files, and a database connection, you'd have 14 more lines when you get an error.
In the past, this wasn't a problem because C programs did what you've been doing when there was an error: die. No point in bothering with cleanup when the OS will do it for you. Today, though, many C programs need to run for weeks, months, or years, and handle errors from many different sources gracefully. You can't just have your Web server die at the slightest touch, and you definitely can't have a library that you've written nuke the program it's used in. That's just rude.
Other languages solve this problem with exceptions, but those have problems in C (and in other languages, too). In C, you only have one return value, but exceptions make up an entire stack-based return system with arbitrary values. Trying to marshal exceptions up the stack in C is difficult, and no other libraries will understand it.
Register for Learn C the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.