There is no reason for this. The usual way programmers write such macros is that they have code with multiple return statements (which should be avoided if possible, but sometimes itโs just not wise to avoid it). Example:
// Bad code err_t func (void) { err_t err; ... if(err == error1) { cleanup(); return err; } ... if(err == error2) { cleanup(); return err; } cleanup(); return err; }
To clear the whole function, this is bad practice due to code repetition.
An ancient way to solve the problem would be purer "goto error", where you put a label at the end of the function. And do the cleaning and return only there. In fact, this will be a somewhat acceptable solution, but goto is a taboo, so people shy away from it. Instead, they come up with something like:
// Slightly less bad code
This removes code repetition, so the program is more secure and easy to maintain. This is probably the answer to your question.
But this macro is still not a good solution, because it makes the code more difficult to read, because C programmers read C well, but poorly read "native language, secret macro language." And, of course, there are common problems with macros: type of security, hard to debug / maintain, etc.
However, all of the above methods (including on-error-goto) are due to the inability to think outside the field. The optimal solution is as follows:
// proper code err_t func (void) { err_t err; allocate(); // allocate whatever needs to be allocated err = func_internal(); cleanup(); // one single place for clean-up return err; } static err_t func_internal (void) // local file scope, private function { err_t err; ... allocate_if_needed(); // or maybe allocation needs to be here, based on results ... if(if(err == error1) { return err; } ... if(err == error2) { return err; } return err; }