开发者

Embedded C++, any tips to avoid a local thats only used to return a value on the stack?

I have a local that's only used for the purposes of checking the result from another function and passing it on if it meets certain criteria. Most of the time, that criteria will never be met. Is there any way I can avoid this "extra" local?

I only have about 1MB of storage for my binary, and I have several thousand function calls that follow this pattern. I know it's a minor thing, but if there's a better pattern I'd love to know!

SomeDataType myclass::myFunction()
{
   SomeDataType result;  // do I really need this local???

   // i need to c开发者_StackOverflow社区heck the result and pass it on if it meets a certain condition
   result = doSomething();
   if ( ! result ) {
      return result;
   }

   // do other things here
   ...

   // normal result of processing
   return SomeDataType(whatever);
}


How complex is SomeDataType? Does it have a lot of members? Does it do a lot of work in a constructor? If so, then I'd avoid this. If not, you may find the compiler will generate good code for this. For example, the compiler will probably do pretty well with integer types.

With a question like this, the answer is almost always: consult the compiler's assembly output.


Depends if your compiler has return value opitmization or not, and if Somedatatype is big or small. The safe side is using smart pointers for this kind of patterns if objects are big. If they are POD, they might be optimized and returned on registers.


What if change function to

void myclass::myFunction(SomeDataType* pResult)
{
  // i need to check the result and pass it on if it meets a certain condition
   *pResult = doSomething();
   if ( ! *pResult ) {
      return;
   }

   // do other things here
   ...

   // normal result of processing
  *pResult = SomeDataType(whatever);
}


If you're not using the result variable elsewhere in the function you could try this:

if (!doSomething())
{
    return;
}

The above example allows the compiler to create temporary variables if necessary, rather that you telling the compiler to create one.

If you are a stickler for structured programming, you could try this:

do
{
    if (!doSomething())
    {
        break;
    }
// ...
} while (false);
return;

This example allows for only one return point in a function. Which may be a good thing when dealing with quality and traceability guidelines.


I would disassemble the code and figure out what your compiler is doing when it generates the code. Modern compilers do some tricky stuff, and trying to guess how to save code space is not obvious - sometimes I see very little correspondence from the source to the assembly. Source code is more about clarity and maintenance - generating the assembly has different metrics.


As asveikau pointed out, if SomeDataType will "fit in a register" (i.g. its a plain old int), then your local will (depending on the platform) not waste any memory. And I concur with asveikau that you should consult the assembly output to evaluate if this is the case.


If you have a pattern that repeats in thousands of functions, you could consider replacing it with one function and a look-up table.

(I can't really be more specific without knowing more details about your situation.)


I'd suggest that you check your compiler options and make sure that they are set to "optimize for size" since that is what you're worried about. And if your compiler doesn't have something like this as a setting, then perhaps it's time to check out a different one.


In your call to doSomething(), instead of returning null, you could return SomeDataType(whatever).


I would suggest you don't worry about it. It's not really a good use of time to optimize down at this level, since any decent compiler will minimize the amount of the local storage required. The stack is reusable, thousands of calls won't matter because the memory is only required for the context where it is used and will not be relevant beyond that.

If it is really necessary for you to be concerned about a few bytes of temporary storage on the stack, you should probably be working in assembly. I doubt this is the case, so don't sweat it and spend your time on other more interesting and important issues!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜