Suppose a function that does the following, assuming all operations can fail and none can block:
- Allocate XXX bytes of memory (on the heap)
- Open file for reading
- Read file into allocated buffer
- Acquire lock
- Do stuff with data now in memory
Each of the steps in italics has a corresponding "cleanup" before exiting the function:
- Free memory
- Close file
- Release lock
Arguably, one of the cleanest solutions to design this function is using goto
:
Allocate memory
if fail
set error code
goto end
Open file
if fail
set error code
goto end
Read data
if fail
set error code
goto end
Try to acquire lock
if fail
set error code
goto end
// Do the stuff
end:
if lock acquired
release lock
if file opened
close file
if mem allocated
release mem
return error code