Использование нескольких операторов return в функции C++
Мне было интересно, может ли это быть полезным для компилятора C++, если в функции есть только один оператор return. один из моих бывших боссов однажды сказал мне об этом, но я не понимаю, будет ли какая-то разница между объявлением возвращаемой переменной или просто наличием нескольких операторов возврата, например, в операторе switch-case.
Поэтому мой вопрос: есть ли разница, возможно, в качестве, производительности или экономии памяти стека?
5 ответов
В идеале вы всегда хотите один оператор return, так как это гарантирует, что ваш код ВСЕГДА будет возвращать значение, и вы устанавливаете это значение перед его возвратом, например:
int getNumber(int x){
int toReturn = 0;
if (x == 0){
toReturn = 5;
} else {
toReturn = 10;
}
return toReturn;
}
Если бы вы должны были вернуться в операторе "if", то вам также пришлось бы вернуться в операторе "else", и, если вы когда-нибудь захотите добавить больше случаев, вам нужно будет добавить больше операторов "return" - что может оказываются очень запутанными, если у вас множество случаев, и в конечном итоге могут повлиять на время компиляции, если вы не будете осторожны.
Однако бывают случаи, когда вам определенно требуется более одного оператора возврата. Это происходит, когда есть какая-то дальнейшая операция, которую вы хотите остановить - например, в рекурсии или в алгоритмах оценки, которые имеют некоторый порог для одного или нескольких параметров, который дисквалифицирует оцениваемый объект.
Например, если вы хотите набрать что-то на основе его расстояния, но вы всегда хотите, чтобы счет был нулевым, если расстояние меньше десяти, тогда:
float scoreObject(float distance){
if(distance < 10){
return 0;
}
float score;
//Scoring function continues here, presumably with some time-intensive
//calculations that the above return statement avoids doing.
return score;
//Please note that this would result in a crash as score is not initialized.
}
Не пишите код, подходящий вашему компилятору. Это меняется с каждой версией компилятора. То, что правда сегодня, может быть не так завтра. Напишите код, чтобы он читался и показывал ваши намерения.
Что касается множественных возвратов, я сильно сомневаюсь, что это вообще имеет значение Что касается попыток компиляции и профилирования, имейте в виду, что оптимизация весьма подозрительна к контексту. Многократный возврат может быть в два раза быстрее в вашем тестовом примере, но вдвое быстрее в следующей функции, если это вообще покажет разницу. Чтобы получить достоверное сравнение, вы должны протестировать множество различных функций и мест их использования. Но если вы скомпилируете их и получите одинаковый или почти одинаковый ассемблер, это будет хорошим показателем того, что компилятору действительно все равно.
Нет, не совсем.
Я делаю actullay как много возвращаемых значений. Это значительно упрощает код, и я не нашел никаких проблем с ним. Visual Studio, IDE, которую я использую, справляется с этим без проблем.
Эта проблема может быть связана с оптимизацией возвращаемого значения - компилятор не создаст возвращенную переменную как локальную переменную и выполнит конструкцию assignmen/copy, когда функция выполнит оператор return, скорее он создаст переменную в адресе памяти переменной, которой значение будет присвоено.
Вы можете иметь несколько операторов return, и это не должно иметь значения, если вы возвращаете одну и ту же переменную. Однако если в вашей функции несколько переменных и вы возвращаете их, то в зависимости от потока кода компилятор не может выполнить такую оптимизацию по-разному.
Давайте иметь следующее назначение
string str;
str = make_name(2);
Компилятор может выполнить RVO в следующем коде
string make_name(int num){
string result = "Simon";
if (num & 1){
result.append(" Hrabec");
return result;
} else {
result.append(" John");
return result;
}
}
Однако в этом коде компилятор не может сказать, какая переменная должна встраиваться в местоположение переменной, которой назначено новое значение. Во время оценки функции оба могут жить одновременно, будучи обновленными, и решение о том, какое из них следует вернуть, может быть принято в конце.
string make_name(int num){
string result1 = "Simon Hrabec";
string result2 = "Simon John";
if (num & 1){
return result1;
} else {
return result2;
}
}
Однако я не имею в виду использовать такой стиль программирования.
См. https://en.wikipedia.org/wiki/Return_statement подраздел "Несколько операторов возврата".