Подтвердить что ты не робот

Опускание оператора return в С++

У меня просто было странное поведение из версии 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. Когда я добавил return retBoundTag;, все было в порядке.

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

4b9b3361

Ответ 1

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

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

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

Например

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.

Ответ 2

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

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

[Раздел 6.6.3/2]

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

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

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

Ответ 3

Несмотря на то, что компилятор aС++ не всегда может обнаружить, когда функция не может выполнить оператор return, она обычно может.

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