CIsForCookies
CIsForCookies

Reputation: 12837

how to copy a function optimally

I have a function that is called by polling (every 10 ms) and it has a check on it's start:

if(input != saved_data)
    return;
// rest of the function...

and while this check saves a lot of time, sometimes it's wrong, and I'm currently debugging a situation where I need to keep executing the function albeit the input == saved_data.

I thought of 2 options:

  1. add a "force" flag to the argument list, and while it's true, the if will be disregarded
  2. create a new function old_function_force with the same code, except the if

I chose option 2 because I didn't want to modify all the other callings to the function, and I wanted the code to be backwards compatible, but it occurred to me that my solution is also bad, because when someone should change the old_function he will probably forget to change mine, and that would cause new bugs

Is there a better solution other then these two, or a way to improve one of them?

Upvotes: 1

Views: 51

Answers (1)

A mixture of both is actually how you can avoid code duplication and changing every possible call site:

  1. Rename your function and add the flag parameter.

    void func_with_force(/*parameters*/, bool force)
    {
      if(!force && input != saved_data)
        return;
    
      // Other code
    }
    
  2. Add a new function, under the old name, that calls the one above with the flag equal to false.

    void func(/*parameters*/)
    {
      func_with_force(/*Argument forwarding*/, false);
    }
    

And yes, I assumed stdbool.h.


You can also go a step further and place func completely in a header; just add the inline specifier:

inline void func(/*parameters*/)
{
  func_with_force(/*Argument forwarding*/, false);
}

To quote the C11 standard (6.7.4p7):

For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit.

The above means that even if many translation units include the header, the inline definitions won't interfere with each other. And being so short, it's very likely that the stub will simply be optimized into a direct call to your new function.

Upvotes: 5

Related Questions