Пропуск возврата в C ++ - PullRequest
       3

Пропуск возврата в C ++

20 голосов
/ 04 августа 2010

У меня только что было странное поведение в версии g ++ для Windows, которую я получил со Strawberry Perl.Это позволило мне опустить оператор возврата.

У меня есть функция-член, которая возвращает структуру, состоящую из двух указателей, которая называется boundTag:

struct boundTag Box::getBound(int side) {
    struct boundTag retBoundTag;
    retBoundTag.box = this;
    switch (side)
    {
        // set retBoundTag.bound based on value of "side"
    }
}

.выходной, и я обнаружил, что он не имеет оператора возврата.Я хотел вернуть retBoundTag, но на самом деле забыл написать оператор возврата.Как только я добавил return retBoundTag;, все было хорошо.

Но я проверил эту функцию и получил правильный boundTag вывод из нее.Даже сейчас, когда я удаляю оператор return, g ++ компилирует его без предупреждения.WTF?Догадывается ли вернуть retBoundTag?

Ответы [ 3 ]

16 голосов
/ 04 августа 2010

Пропуск оператора return в функции non-void [За исключением main()] и использование возвращаемого значения в вашем коде вызывает Неопределенное поведение .

ISO C ++ - 98 [Раздел 6.6.3 / 2]

Оператор возврата с выражением может использоваться только в функциях, возвращающих значение;значение выражения возвращается вызывающей функции.При необходимости выражение неявно преобразуется в тип возвращаемого значения функции, в которой оно появляется.Оператор возврата может включать конструирование и копирование временного объекта ( class.tegoti * ). Выход из конца функции эквивалентен возврату без значения;это приводит к неопределенному поведению к функции, возвращающей значение .

Например,

int func()
{
    int a=10;
    //do something with 'a'
    //oops no return statement
}


int main()
{
     int p=func();
     //using p is dangerous now
     //return statement is optional here 
}

Обычно g ++ дает warning: control reaches end of non-void function.Попробуйте скомпилировать с опцией -Wall.

12 голосов
/ 04 августа 2010

C и C ++ не требуют наличия оператора return. Возможно, нет необходимости иметь его, потому что функция входит в бесконечный цикл или потому что она выдает исключение.

Прасун уже процитировал соответствующую часть стандарта:

[Раздел 6.6.3 / 2]

Оператор возврата с выражением может использоваться только в функциях, возвращающих значение; значение выражения возвращается вызывающей функции. При необходимости выражение неявно преобразуется в тип возвращаемого значения функции, в которой оно появляется. Оператор возврата может включать создание и копирование временного объекта (class.teven). Выпуск из конца функции эквивалентен возврату без значения; это приводит к неопределенному поведению в функции, возвращающей значение.

Это означает, что без оператора возврата - это нормально. Но достижение конца функции без возврата равно неопределенное поведение .

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

2 голосов
/ 17 октября 2012

Хотя компилятор aC ++ не может всегда определять, когда функция не может выполнить инструкцию возврата, она обычно может.по крайней мере, g ++ позволяет легко это определить с помощью параметра компилятора командной строки «-Wreturn-type».Вам просто нужно помнить, чтобы включить его.(Он также включается, если вы используете «-Wall».)

...