It is OK to use such pattern (with goto
) in cases when resource management is required and there is a set of checks to be performed while each failure requires to stop the flow and perform the required cleanup.
To make the code cleaner, in my opinion, would be to place the rc != 0
condition inside the for
loop:
int rc = 1;for (int i = 0; i < 10 && rc != 0; i++){ ...
In such case you won't need the break
at all as the loop would stop anyway once rc
is compared to 0. I would also recommend check the resut of malloc
:
int foo(void){ int rc = 1; for (int i = 1; i < 10 && rc != 0; i++) { char *data = malloc(i); // Each iteration has a different alloc size if (!(rc = !!data)) goto cleanup; rc = do_something(data); if (rc != 0) goto cleanup; rc = do_something_else(); if (rc != 0) goto cleanup;cleanup: free(data); } return rc;}
Note that it is completely legal to free
a NULL
pointer.