A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
goto jumps to a labeled statement within the same function. It is the oldest control flow primitive. It is also the most abused. In the 1960s and 70s, goto was used for loops, conditionals, and error handling, producing spaghetti code that was impossible to maintain. Dijkstra's 1968 letter "Go To Statement Considered Harmful" argued for structured alternatives. Today, goto has exactly one legitimate use in C: the centralized cleanup pattern for multi-resource error handling. Every other use is a code smell.
#include <stdio.h>#include <stdlib.h>int load_config(const char *path) {int result = -1;FILE *fp = NULL;char *buffer = NULL;int *parsed = NULL;fp = fopen(path, "r");if (!fp) { perror("fopen"); goto cleanup; }buffer = malloc(256);if (!buffer) { fprintf(stderr, "malloc\n"); goto cleanup; }parsed = malloc(10 * sizeof(int));if (!parsed) { fprintf(stderr, "malloc\n"); goto cleanup; }if (fgets(buffer, 256, fp) == NULL) {fprintf(stderr, "empty file\n");goto cleanup;}printf("Config loaded: %.30s...\n", buffer);result = 0;cleanup:free(parsed);free(buffer);if (fp) fclose(fp);return result;}int main(void) {printf("Status: %d\n", load_config("notes.txt"));printf("Status: %d\n", load_config("missing.txt"));return 0;}
Four resources. Four failure points. One cleanup label. Every error path jumps to the same cleanup code. The resources are freed in reverse allocation order. free(NULL) is safe. The fclose is guarded. Without goto, you would need nested if-else blocks or duplicated cleanup code at every failure point. The goto version is shorter, clearer, and less error-prone.
#include <stdio.h>int main(void) {int i = 0;loop_start:if (i >= 5) goto loop_end;printf("i = %d\n", i);i++;goto loop_start;loop_end:printf("Done\n");return 0;}
This is a for loop written with goto. It works. It is also unreadable, unmaintainable, and unnecessary. The for loop exists for this exact purpose. Using goto here signals that the author does not know C's structured control flow. In a code review, this gets rejected. The cleanup pattern is the only goto that survives review.
goto is a tool with one good use. Learn that use. Apply it in multi-resource functions. Reject every other use in code review. The structured alternatives (for, while, if-else, switch, return) cover every other control flow need. Next: static local variables, which persist across function calls without becoming global.
Finish the lesson once you have worked through the material. This awards ★ 30 XP.