Совместимость
Язык И++ развивается и улучшается. Начиная с версии платформы 10.2 язык И++ получил новый компилятор.
Некоторые синтаксические правила И++, реализуемые компилятором первой версии, были пересмотрены. Вторая версия компилятора содержит поддержку опций совместимости для переносимости существующего исходного кода И++.
Опции совместимости указываются в настройках проекта. Для новых проектов не рекомендуется включать опции совместимости. Используйте в новых проектах современный синтаксис, максимально исключающий неоднозначности.
Ниже приводится список опций совместимости с примерами и путями их переработки для полного отказа от старого синтаксиса.
Старый синтаксис условной операции
Условная операция в версии 10.2 является частью ядра языка И++, в то время как ранее существовала функция ? в модуле IBSTD. Т.е. ? являлся именем функции, а параметры передавались в круглых скобках, как принято для функций. Новый синтаксис условной операции приближен к аналогичному синтаксису в других языках программирования (например, C).
Использование старого синтаксиса не является ошибкой, но при выключенной опции совместимости компилятор выводит предупреждение. Независимо от формы записи условная операция реализуется ядром языка, модуль IBSTD не задействуется.
Старый синтаксис:
?(<условие>, <вариант1>, <вариант2>)
Новый синтаксис:
<условие>? <вариант1>: <вариант2>
Пример:
ФУНКЦИЯ СТРОКА: ТекстПереключателя(ЛОГИКА: состояние) РЕЗУЛЬТАТ = ?(состояние, "Вкл", "Выкл") КОНЕЦ_ФУНКЦИИ
Переработка примера:
РЕЗУЛЬТАТ = состояние? "Вкл": "Выкл"
Краткое обращение к контейнерным полям
Ранее поддерживалась возможность обращения к единственному контейнерному полю объекта без указания точки и имени поля. В основном, такая возможность была введена из-за невозможности полноценной работы с контейнерными значениями, например, передачи их в качестве параметров функций. Поэтому, создавался объект тип, служащий оберткой для поля контейнерного типа.
В новой версии И++ ограничения на работу с контейнерными значениями сняты. Больше нет необходимости в объектах-обертках. Поэтому, неявное обращение к полю признано устаревшим, затрудняющим чтение программы.
Включение опции совместимости разрешает краткое неявное обращение к единственному контейнерному полю. При включенной опции усложняется анализ исходного текста и слегка увеличивается время компиляции.
Пример:
ПЕРЕМ МАССИВ: массив массив[1] = "Альфа" массив.эл[2] = "Бета" ОТЛАДКА(массив[2])
Переработка примера:
ПЕРЕМ МАССИВ: массив массив.эл[1] = "Альфа" массив.эл[2] = "Бета" ОТЛАДКА(массив.эл[2])
или с использованием переменной контейнерного типа:
ПЕРЕМ МАССИВ_: массив // ТИП МАССИВ_ = *: @[] массив[1] = "Альфа" массив[2] = "Бета" ОТЛАДКА(массив[2])
Поддержка ключевого слова ОБРАБОТЧИК
Ранее для вызова обработки событий от визуальных элементов модуля FC была введена специальная абстракция языка - обработчик события. Ключевое слово ОБРАБОТЧИК использовалось для задания функций-обработчиков событий формы.
В новой версии И++ поддерживается специальный тип - тип функции. Обработчики событий визуальных элементов модуля FC теперь представлены обычными полями типа функция. Определение значений по умолчанию для таких полей теперь выполняется на общих основаниях. В новой версии И++ для этого может использоваться ключевое слово ПОДМЕНА или указание типа поля.
Включение опции совместимости делает ключевое слово ОБРАБОТЧИК тождественным ключевому слову ПОДМЕНА.
Пример:
ТИП МойДиалог(ДИАЛОГ) [ ОБРАБОТЧИК открытие = Подготовка; ФУНКЦИЯ Подготовка // ... КОНЕЦ_ФУНКЦИИ ]
Переработка примера:
ПОДМЕНА открытие = Подготовка;
или используя синоним типа функции:
ФОРМА_ОТКРЫТИЕ_: открытие = Подготовка;
Неявное объявление переменных
Ранее разрешение неявного объявления переменных включалось опцией проекта. Действие этой опции распространялось только на случай неизвестного имени слева от =. Неявно объявлялись все выходные параметры циклов, объявленных в модулях.
В новой версии И++ неявное объявление переменных разрешено только для переменных-счетчиков циклов ДЛЯ и ИНДЕКС. Неявное объявление переменных затрудняет понимание исходного кода и затрудняет его сопровождение. Например, в функции можно изменить значение глобальной переменной, полагая, что объявлена новая локальная переменная.
Включение опции совместимости разрешает неявное объявление локальных переменных для неизвестного имени слева от = и для выходных параметров циклов, объявленных в модулях.
Пример:
код = "Контрагенты/СПР" // код - новая переменная? ПЕРЕМ ФИЛЬТР_ОБЪЕКТОВ: фильтр ПЕРЕМ МАСКА_АН: маска ЦИКЛ УРОВЕНЬ(код; фильтр; маска; об) // об - новая переменная? ОТЛАДКА(об) КОНЕЦ_ЦИКЛА
Переработка примера:
ПЕРЕМ код = "Контрагенты/СПР" // код - новая переменная! ПЕРЕМ ФИЛЬТР_ОБЪЕКТОВ: фильтр ПЕРЕМ МАСКА_АН: маска ПЕРЕМ АНАЛИТИКА: об // об - новая переменная! ЦИКЛ УРОВЕНЬ(код, фильтр, маска, об) ОТЛАДКА(об) КОНЕЦ_ЦИКЛА
При переработке также заменены разделители в цикле с ';' на ',' (см. ниже).
СТОП как ВЫХОД вне цикла
Ранее вне тела цикла ключевое слово СТОП было тождественно ключевому слову ВЫХОД и приводило к выходу из функции.
В новой версии И++ использование ключевого слова СТОП вне тела цикла является ошибкой.
Включение опции совместимости заменяет ошибку предупреждением и выполняет действие ключевого слова ВЫХОД.
Пример:
ФУНКЦИЯ ЛОГИКА: ПроверкаИмени(СТРОКА: имя) РЕЗУЛЬТАТ = НЕТ ЕСЛИ имя = "" ТО СТОП КОНЕЦ_ЕСЛИ РЕЗУЛЬТАТ = ДА КОНЕЦ_ФУНКЦИИ
Переработка примера:
ФУНКЦИЯ ЛОГИКА: ПроверкаИмени(СТРОКА: имя) РЕЗУЛЬТАТ = НЕТ ЕСЛИ имя = "" ТО ВЫХОД КОНЕЦ_ЕСЛИ РЕЗУЛЬТАТ = ДА КОНЕЦ_ФУНКЦИИ
Имя функции как синоним РЕЗУЛЬТАТ
Ранее для обращения к возвращаемому значению функции в ее теле можно было использовать как имя функции, так и ключевое слово РЕЗУЛЬТАТ.
В новой версии И++ для обращения к возвращаемому значению функции используется только ключевое слово РЕЗУЛЬТАТ. Это устраняет неоднозначность при рекурсивном вызове и для функций с результатом типа функция.
Включение опции совместимости позволяет использовать имя функции для обращения к возвращаемому значению, если за именем не следует открывающаяся круглая скобка.
Пример:
ФУНКЦИЯ ЛОГИКА: ПроверкаИмени(СТРОКА: имя) ПроверкаИмени = имя <> "" КОНЕЦ_ФУНКЦИИ
Переработка примера:
РЕЗУЛЬТАТ = имя <> ""
Разделитель параметров циклов ';' вместо ','
Ранее параметры циклов, объявленных в модулях, разделялись символом ';'.
В новой версии И++ параметры циклов и функций унифицированы. Соответственно синтаксис передачи параметров требует символа ',' в качестве разделителя.
Включение опции совместимости позволяет использовать в качестве символа-разделитоля как ',', так и ';'.
Пример:
ПЕРЕМ ФИЛЬТР_ОБЪЕКТОВ: фильтр ПЕРЕМ МАСКА_АН: маска ПЕРЕМ АНАЛИТИКА: об ЦИКЛ УРОВЕНЬ("Бухгалтерия/ПланСчетов"; фильтр; маска; об) ОТЛАДКА(об) КОНЕЦ_ЦИКЛА
Переработка примера:
ЦИКЛ УРОВЕНЬ("Бухгалтерия/ПланСчетов", фильтр, маска, об)
Расширенная совместимость типов ЦЕЛОЕ и ЧИСЛО
Ранее И++ поддерживал только один числовой тип - ЧИСЛО.
В новой версии И++ наряду с типом вещественных чисел присутствует целочисленный тип. Значения типов ЧИСЛО и ЦЕЛОЕ совместимы в широких пределах. Допустимы присваивания в любую сторону, неявное преобразование при передаче параметров и т.д. Но есть несколько сценариев, когда старый исходный код требует еще большей совместимости в ущерб контролю типов.
Включение опции совместимости позволяет достичь работоспособности старого исходного кода в трех следующих сценариях:
- В условной операции, если типы второго и третьего операнда ЦЕЛОЕ и ЧИСЛО или ЧИСЛО и ЦЕЛОЕ, то результатом операции будет значение типа ЧИСЛО. Без опции совместимости такая ситуация считается неоднозначной и приводит к ошибке.
- При переопределении значений по умолчанию полей типа ЦЕЛОЕ допускается указание типа ЧИСЛО. При этом вещественный тип просто игнорируется. Без опции совместимости такая ситуация приводит к ошибке контроля совместимости типа поля. На практике ситуация встречается из-за того, что многие поля, объявленные в модулях стали целочисленными в новой версии И++.
- При задании значений типа функции соответствующие параметры типов ЦЕЛОЕ и ЧИСЛО считаются совместимыми. К ошибкам вызова таких функций дополнительная совместимость не приводит, т.к. преобразование происходит неявно при передаче параметра. На практике ситуация встречается из-за того, что многие обработчики событий (поля типа функция), объявленные в модуле FC, получили целочисленные параметры в новой версии И++.
Пример 1:
ПЕРЕМ ЧИСЛО: ч ПЕРЕМ рез = ?(ч < 1, ч, 1) // 1 - константа типа ЦЕЛОЕ
Переработка примера 1:
ПЕРЕМ ЧИСЛО: ч ПЕРЕМ рез = (ч < 1)? ч: 1.0 // 1.0 - константа типа ЧИСЛО
При переработке примера также устранен старый синтаксис условной операции (см. выше).
Пример 2:
ТИП МойСписок(СПИСОК) [ ЧИСЛО: выбор = 2; // поле СПИСОК.выбор имеет тип ЦЕЛОЕ ]
Переработка примера 2:
ЦЕЛОЕ: выбор = 2; // также можно использовать ключевое слово ПОДМЕНА
Пример 3:
ТИП МойДиалог(ДИАЛОГ) [ // для поля ТАБЛИЦА.нажатие тип параметров столбец и строка определен как ЦЕЛОЕ ТАБЛИЦА: Таблица1 = [ нажатие = НажатаЯчейка ]; ФУНКЦИЯ НажатаЯчейка(ПЕРЕМ ТАБЛИЦА: элемент; ЧИСЛО: столбец, строка) //... КОНЕЦ_ФУНКЦИИ ]
Переработка примера 3:
ФУНКЦИЯ НажатаЯчейка(ПЕРЕМ ТАБЛИЦА: элемент; ЦЕЛОЕ: столбец, строка)
Необязательная ';' в объявлении полей
Ранее при объявлении полей без задания значения по умолчанию можно было не ставить ';' после имени поля.
В новой версии И++ используется более строгий и однородный синтаксис.
Включение опции совместимости исключает ошибку компиляции при отсутствии ';'.
Пример:
ТИП ПерсДанные [ СТРОКА: имя, фамилия ДАТА: дата_рождения ]
Переработка примера:
ТИП ПерсДанные [ СТРОКА: имя, фамилия; ДАТА: дата_рождения; ]