Что происходит, когда непустой метод достигает конца в Objective-C?

Вопрос Я хотел бы спросить, что происходит, когда непустой метод достигает конца без возврата?

Окружающая среда Этот вопрос относится к iOS и Objective-C. Я не уверен, как вещи, описанные в этом вопросе, ведут себя в другом месте.


Введение и история

Обычно, когда вы объявляете непустой метод в Objective-C и не указываете return, Xcode показывает ошибку компиляции

Control reaches end of non-void function

и запрещает вам компилировать, пока вы не исправите эту проблему.

Система может быть очень умной, определяя, может ли ваш код достичь конца непустой функции, или не может, — распознавая, удовлетворяют ли ваши блоки if/else всем параметрам, проходя через переключатели и т. д.

Тем не менее, я нашел один (и на самом деле могут быть и другие) варианты, как заставить компилятор подумать: «Эй, приятель, да, этот код выглядит прекрасно, давайте скомпилируем его и повеселимся!». Это было случайно и вызвало некоторые головные боли. Вот код!

Кодекс

typedef enum eSections { eSectionRecent, eSectionAround, eSectionAll } eSections;

...

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger localSection = section;
    if (numberOfSections == 2) localSection++;

    switch ((eSections)@(localSection))
    {
        case eSectionRecent:
            return 1;
            break;
        case eSectionAround:
            return 1;
            break;
        case eSectionAll:
            return 3;
            break;
    }
}

Результат

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

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

Ошибка

Для всех, кто интересуется, моя ошибка была в (eSections)@(localSection), где вместо ввода localSection в eSections я набрал @(localSection), который компилируется в NSNumber и вместо значения использует указатель на объект, таким образом, не совпадая ни с одним из case, поскольку указатели могут быть довольно длинными (и, скорее всего, не 0, 1 или 2). Далее произошло то, что проект попытался выделить место для действительно огромного количества ячеек (я думаю, что не указывать возврат было чем-то вроде давайте просто добавим туда какое-то значение памяти) и в конечном итоге разбил приложение для давление памяти.

Спасибо за все ответы!


person Gyfis    schedule 19.04.2015    source источник
comment
Вы могли бы также спросить: что происходит, когда я обращаюсь к неинициализированным указателям.   -  person qwerty_so    schedule 20.04.2015
comment
вы получите кучу мусора, так как компилятор больше не может вас защитить.   -  person Jakub Truhlář    schedule 20.04.2015
comment
Я не могу представить, почему кто-то проголосовал бы за этот вопрос. На самом деле это один из наиболее часто задаваемых вопросов, которые я когда-либо видел здесь. Это ясно, это показывает хорошие усилия, и у него есть четкий пример проблемы. Оснований для отрицательного голосования нет.   -  person rmaddy    schedule 20.04.2015
comment
Изучайте язык ассемблера.   -  person Hot Licks    schedule 20.04.2015
comment
Любые просьбы об улучшениях от проголосовавших против?   -  person Gyfis    schedule 20.04.2015


Ответы (1)


Результатом является неопределенное поведение.

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

person Ken Thomases    schedule 19.04.2015
comment
Спасибо за ответ! Интересно, это ошибка SDK, что я могу скомпилировать упомянутый код и (потенциально) опубликовать его в AppStore? Вот почему я думаю, что в обычном случае компилятор ошибка, а не предупреждение, о том, что Control достигает конца непустой функции, есть. Кроме того, есть ли у вас какое-либо доказательство/дополнительное объяснение оператора... или, в некоторых случаях, некоторого местоположения стека...? Мне было бы очень интересно углубиться сюда! - person Gyfis; 20.04.2015
comment
Это не ошибка в инструментах. C и Objective-C позволяют вам, программисту, выстрелить себе в ногу. Выражение приведения типа означает, что вы сообщаете компилятору, что выражение относится к определенному типу, даже если оно таковым не кажется. Итак, он компилируется, как если бы это было так. Компилятор мог бы сообщать об ошибке всякий раз, когда теоретически возможно, что функция достигает конца непустой функции, но это заставит нас добавить случаи по умолчанию или посторонние операторы return в тех случаях, когда мы знаем, что на самом деле это невозможно. Это компромисс. - person Ken Thomases; 20.04.2015