В процессе разработки на платформе 1С:Предприятие начинающие программисты часто сталкиваются с ситуацией, когда код, написанный после оператора Возврат, игнорируется системой. При пошаговой отладке заметно, что курсор отладчика мгновенно перемещается на строку КонецФункции или КонецПроцедуры. Разберем подробно, почему это происходит, как устроена работа интерпретатора 1С и какие технические нюансы скрываются за этим поведением.
Для начала проанализируем базовое определение. Оператор Возврат (или Return) — это ключевое слово языка, которое выполняет две функции: завершает выполнение текущей подпрограммы (функции или процедуры) и, в случае функции, передает результат обратно в точку вызова. Как только интерпретатор встречает эту команду, он прекращает обработку всех последующих строк в данном блоке кода. Рассмотрим пример, который вызвал затруднение:
&НаСервере
Функция РаботникПриИзмененииНаСервере(Работник)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Должность ИЗ Справочник.Сотрудники ГДЕ Ссылка = &Работник";
Запрос.УстановитьПараметр("Работник", Работник);
ВыборкаДетальныеЗаписи = Запрос.Выполнить().Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Как только найдена первая запись, функция завершается
Возврат ВыборкаДетальныеЗаписи.Должность;
КонецЦикла;
// Этот код никогда не будет выполнен, если выборка не пуста
А = 10;
КонецФункции
В данном фрагменте кода, если запрос вернул хотя бы одну строку, выполнение зайдет в цикл Пока, выполнит Возврат и немедленно покинет функцию. Присваивание А = 10 технически достижимо только в одном случае — если выборка запроса оказалась пустой и цикл не выполнился ни разу.
Многих смущает, что отладчик не возвращается сразу в вызывающую процедуру, а делает промежуточную остановку на последней строке функции. Выясним причину этого поведения. С точки зрения работы виртуальной машины 1С, каждая подпрограмма имеет так называемый эпилог.
Байт-код модуля устроен таким образом, что у функции существует строго одна физическая точка выхода. Когда мы пишем Возврат, компилятор генерирует команду безусловного перехода к этому эпилогу. Именно на строке КонецФункции выполняются критически важные системные операции:
Запрос, ВыборкаДетальныеЗаписи).Поэтому остановка отладчика на строке КонецФункции — это не ошибка, а визуализация финальной стадии жизненного цикла функции.
Код, написанный после безусловного оператора Возврат, в программировании называется недостижимым (unreachable code). Рассмотрим ситуацию:
Функция ВычислитьСумму(А, Б)
Сумма = А + Б;
Возврат Сумма;
Сообщить("Расчет окончен"); // Этот текст никогда не будет выведен
КонецФункции
Проанализируем ситуацию: оператор Сообщить находится за пределами логики исполнения. В некоторых языках программирования компилятор выдаст предупреждение или ошибку при попытке сохранить такой код. В 1С 8.3 конфигуратор позволяет сохранить такой модуль, но фактически этот код является «мертвым». Если вам необходимо выполнить какие-то действия перед выходом, они должны быть расположены строго до оператора Возврат.
Важно помнить, что Возврат может использоваться не только в функциях, но и в процедурах. В этом случае он не возвращает значение, а просто служит для прерывания алгоритма по условию. Посмотрим на пример:
&НаКлиенте
Процедура ОбработатьДанные()
Если Объект.Ссылка.Пустая() Тогда
Сообщить("Сначала запишите объект!");
Возврат; // Прерываем выполнение процедуры
КонецЕсли;
// Логика обработки, которая выполнится только для записанных объектов
ПровестиДанныеНаСервере();
КонецПроцедуры
Здесь Возврат помогает избежать глубокой вложенности блоков Если...Иначе, делая код более читаемым. Поведение отладчика будет таким же: прыжок на КонецПроцедуры.
Иногда начинающие путают Возврат с оператором Прервать. Разберем отличия:
Для или Пока), но продолжает выполнение кода внутри функции, идущего сразу за циклом.Также стоит отметить, что в 1С отсутствует блок Finally (как в C# или Java), который выполняется в любом случае после завершения блока Try. В 1С конструкция Попытка...Исключение не гарантирует выполнение кода после Возврат, если он был вызван внутри блока Попытка.
Чтобы эффективно анализировать значения переменных в момент выхода, рекомендуем придерживаться следующих правил:
Возврат.Возврат, до того как шагнете дальше.КонецФункции, вы можете посмотреть значение переменной, которая была возвращена, только вернувшись в вызывающий код (нажав F10 или F11).Резюме: Переход в конец функции — это стандартное поведение платформы 1С, подтверждающее успешное завершение работы подпрограммы и подготовку к передаче управления обратно. Любой код после Возврат игнорируется, так как логическая цепочка выполнения прерывается в пользу системного эпилога функции.