Использование нескольких операторов 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 подраздел "Несколько операторов возврата".

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