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
Ключевое слово, функция вернется автоматически.