When I learned C, teacher told me all day long: "Don't use goto, that's a bad habit, it's ugly, it's dangerous!" and so on.
Why then, do some kernel programmers use goto
, for example in this function, where it could be replaced with a simple
while(condition) {}
or
do {} while(condition);
I can't understand that. Is it better in some cases to use goto instead of while
/do
-while
? And if so, why?
Historical context: We should remember that Dijkstra wrote Goto Considered Harmful in 1968, when a lot of programmers used goto
as a replacement for structured programming (if
, while
, for
, etc.).
It's 44 years later, and it's rare to find this use of goto
in the wild. Structured programming has already won, long ago.
Case analysis:
The example code looks like this:
SETUP...
again:
COMPUTE SOME VALUES...
if (cmpxchg64(ptr, old_val, val) != old_val)
goto again;
The structured version looks like this:
SETUP...
do {
COMPUTE SOME VALUES...
} while (cmpxchg64(ptr, old_val, val) != old_val);
When I look at the structured version, I immediately think, "it's a loop". When I look at the goto
version, I think of it as a straight line with a "try again" case at the end.
The goto
version has both SETUP
and COMPUTE SOME VALUES
on the same column, which emphasizes that most of the time, control flow passes through both. The structured version puts SETUP
and COMPUTE SOME VALUES
on different columns, which emphasizes that control may pass through them differently.
The question here is what kind of emphasis do you want to put in the code? You can compare this with goto
for error handling:
Structured version:
if (do_something() != ERR) {
if (do_something2() != ERR) {
if (do_something3() != ERR) {
if (do_something4() != ERR) {
...
Goto version:
if (do_something() == ERR) // Straight line
goto error; // |
if (do_something2() == ERR) // |
goto error; // |
if (do_something3() == ERR) // |
goto error; // V
if (do_something4() == ERR) // emphasizes normal control flow
goto error;
The code generated is basically the same, so we can think of it as a typographical concern, like indentation.