Как провести рефакторинг этого GOTO (без освобождения ресурсов)? - PullRequest
0 голосов
/ 07 ноября 2011

Это простой вопрос GOTO о потоке управления, ничего о распределении ресурсов.

Существует два уровня проверки, является ли часть данных «хорошей».Если и только если проходит первую проверку, мы делаем вторую проверку.Если данные не проходят какой-либо тест, мы используем вместо них значение по умолчанию.

Вторая проверка включает несколько шагов с промежуточными данными, поэтому мы не можем просто поместить их в состояние короткого замыкания ||.Кроме того, если второй тест пройден, мы используем выходные данные второго теста вместо исходных данных.

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

if (firstCheck(data)) {
    result = analyze(data);
    if (secondCheck(result)) {
        use_result(result);
    }
    else {
        goto FAIL;
    }
}
else {
FAIL:
    use_result(DEFAULT_VALUE);
}

Этот GOTO, кажется, удовлетворяет всем моим требованиям с максимальной эффективностью.Я могу подумать о некоторых других способах сделать это, но все это будет связано с дополнительным хранилищем или условиями.Я опасаюсь GOTO, хотя.На самом деле, если я буду использовать это, это будет первый раз, когда я использую GOTO.Поэтому, пожалуйста, помогите мне найти выход!

Ответы [ 3 ]

1 голос
/ 07 ноября 2011

Используйте continue для перехода к следующей итерации цикла

if (firstCheck(data)) {
    result = analyze(data);
    if (secondCheck(result)) {
        use_result(result);
        continue;
    }
}
use_result(DEFAULT_VALUE);
1 голос
/ 07 ноября 2011

Ну, мы можем исправить это без особой работы, но использование goto таким способом не обязательно является плохим поведением - например, ядро ​​linux использует это соглашение для обработки ошибок также только в одном месте, и я думаю, что код довольноясно как есть.

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

if (firstCheck(data) && secondCheck(result = analyze(data)) {
    use_result(result);
}
else {
    // fail
}
0 голосов
/ 25 февраля 2015

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

if (firstCheck(data)) {
    result = analyze(data);
    use_result (secondCheck (result) ? result : DEFAULT_VALUE);
}
else {
    use_result(DEFAULT_VALUE);
}

Очиститель, без дублирования кода и масштабируемый:

int result = DEFAULT_VALUE;
if (firstCheck(data)) {
    int tmpResult = analyze(data);
    if (secondCheck (tmpResult))
        result = tmpResult;
}
use_result (result);
...