Встроенный C ++, какие-либо советы, чтобы избежать локальных, которые используются только для возврата значения в стеке? - PullRequest
3 голосов
/ 04 марта 2010

У меня есть локальный файл, который используется только для проверки результата другой функции и передачи его, если он соответствует определенным критериям. В большинстве случаев эти критерии никогда не будут выполнены. Есть ли способ, которым я могу избежать этого "лишнего" местного?

У меня есть только около 1 МБ памяти для моего двоичного файла, и у меня есть несколько тысяч вызовов функций, которые следуют этому шаблону. Я знаю, что это второстепенная вещь, но если бы была лучшая модель, которую я хотел бы знать!

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

   // i need to check 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);
}

Ответы [ 10 ]

4 голосов
/ 04 марта 2010

Насколько сложен SomeDataType? У него много членов? Делает ли он много работы в конструкторе? Если так, то я бы избежал этого. Если нет, вы можете обнаружить, что компилятор сгенерирует хороший код для этого. Например, компилятор, вероятно, будет хорошо работать с целочисленными типами.

С таким вопросом ответ почти всегда: обратитесь к выводу сборки компилятора.

1 голос
/ 15 марта 2010

Я бы разбирал код и выяснил, что делает ваш компилятор, когда он генерирует код. Современные компиляторы делают некоторые хитрые вещи, и попытка угадать, как сохранить пространство кода, неочевидна - иногда я вижу очень небольшое соответствие между исходным кодом и сборкой. Исходный код больше о ясности и обслуживании - генерация сборки имеет разные метрики.

1 голос
/ 04 марта 2010

Если вы не используете переменную результата в другом месте функции, вы можете попробовать это:

if (!doSomething())
{
    return;
}

Приведенный выше пример позволяет компилятору создавать временные переменные, если это необходимо, вместо того, чтобы вы сообщали компилятору о его создании.

Если вы сторонник структурного программирования, вы можете попробовать это:

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

В этом примере допускается только одна точка возврата в функции. Что может быть хорошей вещью при работе с рекомендациями по качеству и прослеживаемости.

1 голос
/ 04 марта 2010

Что если изменить функцию на

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);
}
1 голос
/ 04 марта 2010

Зависит от того, имеет ли ваш компилятор оптимальное возвращаемое значение или нет, и если Somedatatype большой или маленький.Безопасной стороной является использование умных указателей для такого рода шаблонов, если объекты большие.Если они являются POD, они могут быть оптимизированы и возвращены в регистры.

0 голосов
/ 29 апреля 2010

Я бы посоветовал вам не беспокоиться об этом.Это не очень хорошее время для оптимизации на этом уровне, так как любой приличный компилятор минимизирует объем требуемого локального хранилища.Стек можно использовать многократно, тысячи вызовов не будут иметь значения, поскольку память требуется только для контекста, в котором она используется, и не будет иметь отношения к этому.

Если вам действительно необходимо беспокоиться онесколько байтов временного хранилища в стеке, вы, вероятно, должны работать в сборке.Я сомневаюсь, что это так, так что не переживайте и потратьте свое время на другие более интересные и важные вопросы!

0 голосов
/ 21 апреля 2010

При вызове doSomething () вместо возврата null вы можете вернуть SomeDataType (что угодно).

0 голосов
/ 17 марта 2010

Я бы посоветовал вам проверить параметры компилятора и убедиться, что они настроены на «оптимизацию по размеру», так как это то, что вас беспокоит. И если ваш компилятор не имеет ничего подобного в качестве настройки, тогда, возможно, пришло время проверить другую.

0 голосов
/ 09 марта 2010

Если у вас есть шаблон, который повторяется в тысячах функций, вы можете заменить его одной функцией и справочной таблицей.

(Я не могу быть более конкретным, не зная больше деталей о вашей ситуации.)

0 голосов
/ 04 марта 2010

Как указал asveikau, если SomeDataType будет "вписываться в регистр" (например, его обычный старый int), то ваш локальный (в зависимости от платформы) не будет тратить впустую память. И я согласен с asveikau, что вам следует обратиться к выходным данным сборки, чтобы оценить, так ли это.

...