C/C++ операторы условного возврата

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

foo() {
   if (a < b) {
       return 0;  // bail, since condition is met
   } else {
       // lots of calculations in this block
   }
   return 1;
}

Мой вопрос, плохо ли иметь несколько операторов return? Это плохая практика? Есть ли лучшие методы? MISRA что-нибудь говорит об этом?

ПРИМЕЧАНИЕ. Этот вопрос относится к встраиваемым системам и касается MISRA, а не только C/C++.

Спасибо...

5 ответов

Решение

MISRA требует одного оператора возврата:

(MISRA, правило 14.7: требуется) "Функция должна иметь единую точку выхода в конце функции"

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

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

Я предлагаю вам прочитать эту статью о даффинге (написание кода сверху вниз):

Я бы написал это так, потому что else избыточно:

   if (a < b) {
       return 0;  // bail, since condition is met
   }
   // lots of calculations in this block
   return 1;

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

Однако в рекурсивной функции, например, очень удобно помещать ваши "базовые случаи" в качестве операторов возврата в начале функции.

Например, рассмотрим факториал:

int fact(int x) {
  // base cases
  if (x == 0 || x == 1)
    return 1;

  // recursive call
  return x * fact(x-1);
}

Вы также можете написать это так:

int fact(int x) {
  int ret = 0;
  if (x == 0 || x == 1)
    ret = 1;
  else
    ret = x * fact(x-1);
  return ret;
}

Мне просто нравится первый способ лучше, но это не значит, что один из способов лучше другого.

Это действительно сводится к тем стандартам, которым вы должны следовать и личным предпочтениям.

Некоторые считают это плохой практикой, я лично согласен с этим, так как это может быть более чистый код. Вы также можете сделать это следующим образом:

foo() {
   int results = 0;  // good practice to initialize
   if (a < b) {
       results = 0;  // redundant, likely optimized out
   } else {
       // lots of calculations in this block
       results = 1;
   }
   return results;
}

Множественные операторы возврата вполне допустимы в C/C++. Но убедитесь, что хотя бы один из операторов возврата всегда выполняется. Следующая функция неверна,

int foo(int x)
{
  if(x>0)
  {
    return 1;
  }
  else if(x==0)
  {
    return 0;
  }
  else
  {
    // No return in this block
  }
}

таких ситуаций следует избегать в C/C++.

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

Просто убедитесь, что если ваша функция не имеет возвращаемого типа void, тогда у вас есть оператор возврата в конце, и все операторы возврата возвращают этот тип. Например, если ваша функция объявлена ​​так:

int foo ();

Тогда все ваши операторы return должны возвращать целые числа, и вы должны возвращать целое число в конце, несмотря ни на что. Но если ваша функция имеет возвращаемый тип void, вот так:

void foo ();

Тогда, если вы достигнете конца функции и не return Ключевое слово, функция вернется автоматически.

Другие вопросы по тегам