2010-08-04 3 views
19

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

У меня есть функция-член, которая возвращает структуру, состоящую из двух указателей, называется 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?

+5

Вы должны скомпилировать с помощью '-Wall'. Недопустимые операторы return захватываются '-Wreturn-type'. – jweyrich

+0

Я склоняюсь к предупреждению о недостающем возвращении в ошибку: '-Werror = return-type'. Сэкономил мне много времени. –

ответ

16

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

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

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

Например

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 
} 

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

+7

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

+0

Почему использование 'p' опасно? – ajay

+2

@ajay: Это потому, что оно не содержит никакого заданного значения. –

12

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

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

[Раздел 6.6.3/2]

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

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

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

+3

Благодарим вас за объяснение, почему ошибка компиляции не имеет явного оператора return в не-void функции :) – ajay

2

Даже если AC++ компилятор не всегда обнаружить, когда функция не может выполнить оператор возврата, он обычно может.

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

Смежные вопросы