последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
В одном из тестов нарвался на примерно такой код:
В тестах был вопрос - что мы увидим на экране после того, как программа отработает. Понятно, что finally выполнится при любом раскладе. Т.е. сообщение "Это мы увидим" мы обязательно увидим. По сути, вопрос превращается в "что выполнится раньше - блок finally или return"? А у меня вопрос - для такого случая последовательность выполнения где то регламентирована? Полез в msdn.microsoft.com - ответа не нашёл. Может, в какой то другой статье есть ответ? Исправлено 2 раз(а). Последнее : S-type, 22.02.17 00:09 |
Re: последовательность выполнения | |
---|---|
Рома Сообщений: 1079 Дата регистрации: 06.06.2001 |
return конечно будет после finally, но неопределенного поведения здесь нет.
Компилятор просто сделает
|
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
Если запустить приведённую мной программу, в консоли высвечивается
Finally каким то образом выполнилось после return-а! |
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
Но, на основании чего он это сделает? Это где то прописано? Почему Return бегает по коду? |
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
Если сделать:
то компилятор выдаёт предупреждение "Обнаружен недостижимый код". Т.е. return после finally реально существует... Если подумать - на приведённый изначально код компилятор не выдаёт ошибку "Не все ветки кода возвращают значение", хотя оператор return после finally в явном виде не указан. Исправлено 2 раз(а). Последнее : S-type, 22.02.17 11:44 |
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
Почему то вспомнилось:
|
Re: последовательность выполнения | |
---|---|
Рома Сообщений: 1079 Дата регистрации: 06.06.2001 |
На основании того, что пользователь захотел вернуть вполне конкретное значение. Если бы у нас не было finally, то можно было бы просто загрузить значение аргумента str на стек и выйти. В случае с finally не ясно, что будет висеть на стеке после его выполнения (неопределенное поведение) Поэтому результат сохраняется во временную переменную, из которой он загружается на стек перед выходом. |
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
Сначала
Потом
Всё таки, в случае с finally есть "неопределённое поведение"... Поясню на примере. Предположим, в С есть код:
Всегда можно запустить на выполнение и увидеть результат. Но, в самом стандарте языка С не прописано - что должно выполнится в первую очередь - присваивание или инкремент. Потому, результат может меняться в зависимости от реализации. Приведённый тобой код иллюстрирует "как это работает". Но, "почему работает именно так?" - не понятно. Это где то "задокументировано", или, "есть как есть"? |
Re: последовательность выполнения | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Нет, на самом деле это return выполнился после блока try-finally (но его выражение "посчиталось" внутри блока!). finally выполняется всегда при выходе из блока - в частности при выходе из него по return. Не выполняется он в редких случаях: - катастрофические/неотлавливаемые (типа StackOverflow, OutOfMemory или ThreadAbort) исключения. - банально неотловленные/необработанные исключения (то что по сути вываливается "наружу" C# кода - оно тупо убивает приложение). - Environment.FastFail() ------------------ WBR, Igor |
Re: последовательность выполнения | |
---|---|
Рома Сообщений: 1079 Дата регистрации: 06.06.2001 |
Задокументировано здесь ECMA 335 - I.12.4.2.8 Control flow restrictions on protected blocks В защищенном блоке (try/catch/finnaly) нельзя выполнять инструкцию ret. Для начала надо выполнить leave (чтобы выполнился код finally) Например, в VFP return нельзя делать внутри try/catch/finally C# это разрешает, но делает через временную переменную. |
Re: последовательность выполнения | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Какое именно? В чём неопределённость? Нет, это совершенно чётко прописано в стандартах языка. Ссылку на ISO нет смысла давать, ибо там только за бабки можно скачать документ ru.cppreference.com ------------------ WBR, Igor |
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
В том, что какие то действия выполняются "за кулисами". А именно - вычисленное значение сначала сохраняется, потом выполняется finally, потом вычисленное значение возвращается. Return выполняется после finally, но возвращается не "текущее значение", а "запомненное раньше". Так понимаю, что это надо "принять как данность".
Согласно стандарта, сначала надо выполнить присваивание, потом - инкремент. Т.е. если i=1 и сделать j=i++, то j=1, а i=2. В случае i=i++ сначала в i надо занести 1, а потом значение в i инкрементировать. А, это не так! Исправлено 1 раз(а). Последнее : S-type, 22.02.17 14:44 |
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
Понимая некоторое скептическое отношение к Википедии, всё таки её упомяну. ru.wikipedia.org ru.wikipedia.org Т.е. есть различие межу Неопределённым поведением и Неуточняемым поведением программы.
|
Re: последовательность выполнения | |
---|---|
S-type Автор Сообщений: 2969 Дата регистрации: 24.04.2004 |
Очень разумное ограничение. Сразу многое становится ясным и понятным. Видимо, в этом корни моих проблем, что перейдя с VFP на C# ни когда внутри try/catch/finally не использовал return, и на такие проблемы не нарывался. |
Re: последовательность выполнения | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Я тоже обычно не использую return внутри блоков try (в "неявных" блоках типа foreach нет ЯВНЫХ finally или catch). Но даже если бы и использовал, то вряд-ли стал бы в finally писать нечто НЕ связанное с освобождением неуправляемых ресурсов - как и советуют все мануалы
Так там как раз и описывается поведение (неопределённое, неуточнённое или зависимое от реализации) для этих "хитрых ситуаций". По сути это как раз формализованное описание - можно сказать директива разработчику "так не писать" если он хочет получить strictly conforming program ------------------ WBR, Igor |
© 2000-2024 Fox Club  |