Originally posted by XorEaxEax
View Post
Announcement
Collapse
No announcement yet.
Linux 2.6.38-rc6 Kernel Released; Lots Of Small Fixes
Collapse
X
-
-
A goto label for error handling is more efficient. If you call a function for clean-up, that function needs to know about the state of the function that called it. That means passing arguments. This results in more complex code.
Another example where goto is useful is jumping from the middle of one loop into another. This occurs when you are processing a stream of data for example, and need to switch to a different algorithm when certain data appears in the stream. An example is UTF-8 parsing, where you can goto from the current loop inside another loop that handles plain ASCII bytes once you detect a few ASCII bytes in succession.
Comment
-
Originally posted by crazycheese View PostHehe, I understand your point. But why not consider this(not trying to teach anyone..):
Code:int function(){ do_somestuff(); if (failure) { cleanup(); return failure; } do_morestuff(); if (failure) { cleanup(); return failure; } return success; } ... void cleanup(){... };
Also, function calls are slow, forcing the compiler to shuffle all those local variables on the stack until they're in the right order. This can be avoided if the compiler chooses to inline the cleanup() function, but you know what'll happen to code size then.
The only valid alternative is the big nested function:
Code:void function() { do_somestuff(); if (success) { do_morestuff(); if (success) { //... return success; } } cleanup_stuff(); }
Both styles suck, but there really is no better way until you introduce exceptions and all the problems related to them. I don't think the linux kernel community is ready to take that step, yet
Comment
-
Originally posted by rohcQaH View Postprobably because a lot of the resources needing cleanup are bound to local variables, which wouldn't be available in a separate cleanup() function.
Code:int myfunc(...args...) { ...local vars myvar1, myvar2... #define getout() \ do \ { \ free(myvar1); \ free(myvar2); \ return failure; \ } while(0) ...allocate myvar1, myvar2... do_something(); if (failure) { getout(); } do_morestuff(); if (failure) { getout() } return success; }
If you are OCD'ed to 'goto', you can call the macro goto_out...;-)
Comment
-
Originally posted by devsk View PostUsing macros you can have clean looking code without goto's and without the overhead of functions.
Comment
-
Originally posted by smitty3268 View PostMacros get inlined directly into the function, though, don't they? Which would balloon the size of the function and hurt performance by blowing up the CPU caches. The GOTO commands would just be a simple JMP instruction.
If the goto label is doing error handling and it has to check for 20 different conditions to conditionally free some middle of the pack allocations after a failure, then the loss can be reduced with macros through localization.
IMO, Judicious use of goto is a VERY good thing! But most of the time, its better to avoid them.
Comment
-
Originally posted by devsk View PostAgreed, but it also depends on what the target goto label does. If its just 'return return_code;', the code is actually smaller with macro because there is no JMP...;-)
If the goto label is doing error handling and it has to check for 20 different conditions to conditionally free some middle of the pack allocations after a failure, then the loss can be reduced with macros through localization.
IMO, Judicious use of goto is a VERY good thing! But most of the time, its better to avoid them.
Comment
Comment