If you follow the single return() at the end of the function paradigm, its much much easier to keep the cleanup code consistent with the setup code as there will only be one instance of it.
But then you have to add code and variables to keep track of what you should clean up. Not to speak about all code and variables added to avoid executing the code between the forbidden return point and the permitted return point at the end (can't have any goats you know).
Using only one return point just adds a number of other problems.
^This is exactly opposite of the case in assembly programming.
My code can and will jump around anywhere and everywhere, but quite often I direct multiple exit points of a subroutine into one return for the exact reason Ian.M stated. If you leave multiple exit points, you have to redundantly do the cleaning at multiple points in the code. And if you ever change your code in a way that requires modification of this exit cleanup, now you have to track down and modify each exit point. This is not only redundant, but you have higher chance of missing one and creating what could have been an avoidable bug.
I think the single exit point is in general a good idea for code portability. In case you are going to reuse this code, it is easier to describe (in notes to even just yourself, for later) and to implement if you follow this guideline.
Exit points are extremely significant things to me, in order to even read my own code. I use specific tabbing/indentation on exit points so I can understand what I'm looking at.
This probably has nothing to do with C funtions; sorry for the distraction.