Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Linux 2.6.38-rc6 Kernel Released; Lots Of Small Fixes

  1. #11
    Join Date
    Apr 2010
    Posts
    1,946

    Default

    Quote Originally Posted by XorEaxEax View Post
    Well, I find both solutions quite readable but I'd likely not use goto myself due to habit. I don't understand why 'goto' would lead to 'higher' cache usage than calling an outside function?
    Well, the code size is meant. Keeping it as lots of smaller islands is better as one large cake. But well, it does not matter anymore. Like whats said in that thread, it is programmer who missuses goto and any keyword/function can be misused. Readability sure means more for the future than a compact less understandable code.

  2. #12
    Join Date
    Jul 2008
    Location
    Greece
    Posts
    3,762

    Default

    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.

  3. #13
    Join Date
    Nov 2008
    Posts
    755

    Default

    Quote Originally Posted by crazycheese View Post
    Hehe, 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(){... };
    probably because a lot of the resources needing cleanup are bound to local variables, which wouldn't be available in a separate cleanup() function. Making them global is a no-go (bigger evil than goto, memory usage, thread safety), passing them explicitely would increase code size over a goto.
    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();
    }
    That avoids the goto, but gets ugly fast because of other reasons.
    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

  4. #14
    Join Date
    Apr 2010
    Posts
    1,946

    Default

    Quote Originally Posted by rohcQaH View Post
    Thanks for explanation

  5. #15
    Join Date
    Jun 2010
    Posts
    70

    Default

    Quote Originally Posted by rohcQaH View Post
    probably because a lot of the resources needing cleanup are bound to local variables, which wouldn't be available in a separate cleanup() function.
    Using macros you can have clean looking code without goto's and without the overhead of functions.

    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;
    }
    Of course, what getout() does is specific to the state of the function e.g. myvar1 may not even allocated.

    If you are OCD'ed to 'goto', you can call the macro goto_out...;-)

  6. #16
    Join Date
    Oct 2008
    Posts
    2,904

    Default

    Quote Originally Posted by devsk View Post
    Using macros you can have clean looking code without goto's and without the overhead of functions.
    Macros 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.

  7. #17
    Join Date
    Jun 2010
    Posts
    70

    Default

    Quote Originally Posted by smitty3268 View Post
    Macros 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.
    Agreed, 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.

  8. #18
    Join Date
    Oct 2008
    Posts
    2,904

    Default

    Quote Originally Posted by devsk View Post
    Agreed, 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.
    True. Personally, I would never use a GOTO statement, but then i don't work on projects like the kernel where every little extra instruction might matter. Actually, I did use one once, but only because i was porting a bunch of old Fortran code into a new application and it was riddled with them. I got rid of most of them, but left a single one behind because it was just easier than trying to refactor the code.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •