C++ осуществляет операторы возврата?

Хорошо, мало причуды я обнаружил со своим компилятором C++.

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

Вот мой вопрос: действительно ли это - ошибка компилятора или не является там никакой гарантией, что компилятор C++ осуществит потребность в операторе возврата в непустой функции возврата?

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

7
задан deworde 6 July 2010 в 14:49
поделиться

3 ответа

Лично я считаю, что это должно быть ошибкой:

int f() {
}

int main() {
    int n = f();
    return 0;
}

но большинство компиляторов рассматривают это как предупреждение, и вам, возможно, даже придется использовать переключатели компилятора, чтобы получить это предупреждение. Например, в g ++ вам понадобится -Wall, чтобы получить:

[neilb@GONERIL NeilB]$ g++ -Wall nr.cpp
nr.cpp: In function 'int f()':
nr.cpp:2: warning: no return statement in function returning non-void

Конечно, с g ++ вы всегда должны компилировать по крайней мере с -Wall.

12
ответ дан 6 December 2019 в 06:13
поделиться

Нет гарантии, что компилятор C ++ будет применять это. Функция C ++ могла выпрыгнуть из потока управления механизмами, неизвестными компилятору. Переключение контекста, когда C ++ используется для написания ядра ОС, является примером этого. Неперехваченное исключение, созданное вызываемой функцией (код которой не обязательно доступен вызывающей стороне), является другим.

Некоторые другие языки, такие как Java, явно предписывают, что при наличии знаний, доступных во время компиляции, все пути возвращают значение. В C ++ это неверно, как и во многих других случаях в языке, например, доступ к массиву за его пределами также не проверяется.

13
ответ дан 6 December 2019 в 06:13
поделиться

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

Однако в Visual Studio это предупреждение. И мы должны обращать внимание на все предупреждения .... не так ли? :)

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

enum TriBool { Yes, No, Maybe };

TriBool GetResult(int input) {
    if (TestOne(input)) {
        return Yes;
    } else if (TestTwo(input)) {
        return No;
    }
}

Потерпите меня, потому что это старый код. Изначально там было «еще может вернуться».:) Если TestOne и TestTwo находятся в другом модуле компиляции, то, когда компилятор встречает этот код, он не может определить, могут ли TestOne и TestTwo оба вернуть false для заданного ввода. Вы, как программист, написавший TestOne и TestTwo, знаете, что если TestOne выйдет из строя, то TestTwo будет успешным. Возможно, у этих тестов есть побочные эффекты, поэтому их нужно делать. Было бы лучше написать это без «иначе, если»? Может быть. Наверное. Но дело в том, что это законный C ++, и компилятор не может знать, можно ли выйти без оператора return. Я согласен, что это уродливо и нехорошо, но это законно, и Visual Studio выдаст вам предупреждение, но оно будет скомпилировано.

Помните, что C ++ не защищает вас от самих себя. Речь идет о том, чтобы позволить вам делать то, что душе угодно, в рамках ограничений языка, даже если это включает в себя выстрел себе в ногу.

4
ответ дан 6 December 2019 в 06:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: