Неочевидные особенности конвертации типов

Рассмотрим простой пример:

В данном случае у нас возникнет исключительная ситуация, т.к. среда не сможет целиком поместить указанное число в переменную типа p.

Как вы считаете что в данном случае будет с переменной lv_p? Очевидным ответом будет — ну раз произошло исключение, значит переменная осталась без изменений. В реальной же ситуации все несколько иначе.

Далее рассмотрим почему.

До 7.5 переменная выглядит так, как-будто с ней все в порядке (за исключением бинарного представления):

Нормальное бинарное представление до присвоения:

Более того, если попробовать её изменить сразу после:

Возникнет исключение, которые мы не сможем обработать: BDC_BADDATA.

После 7.5 мы видим что отладчик нам подсказывает о наличии INVALID VALUE внутри переменной:

Согласно документации, присвоения между различными переменными выполняются следующим образом:

When the value of a source object (source) is assigned to a destination object (destination), three cases can be distinguished with respect to the data type:

  1. source and destination are compatible, which means that all technical type attributes match. The content is transferred from source to destination without being converted…
  2. source and destination are not compatible but can be converted. The content of source is converted in accordance with the conversion rules and then transferred to destination. Two data types are convertible if a conversion rule exists for them. An exception is raised if the content of source cannot be handled in accordance with the conversion rules. After an exception, the content of destination depends on the category of the data type. An assignment where a conversion takes place is always slower than an assignment without conversion.
  3. If the data objects are neither compatible nor convertible, no assignment can take place. If the syntax check recognizes this status, a syntax error is raised, otherwise an exception is raised when the program is executed.

В первом случае для совместимых типов данных (технические атрибуты совпадают) — будет выполнен перенос данных без процедуры конвертации (правила для структур и таблиц опустим в данном случае).

В третьем случае система либо сама скажет вам что типы не являются совместимыми (если это можно проверить статически), либо выкинет исключение при исполнении программы.

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

Другими словами, наличие исключительной ситуации вовсе не обозначает того, что переменная останется в своём первоначальном состоянии. И этот факт может сбить с толку.

Согласно ABAP Guidelines:

Only assign data objects to each other if the content corresponds to the data type of the target field and produces an expected result. Do not exploit every ABAP conversion rule to its full extent. Consider using lossless assignments.

Другими словами в случае не совместимых, но конвертируемых согласно правилам присвоений типов следует использовать присвоение без потерь, оператор EXACT, либо дополнение EXACT у оператора MOVE до 7.4:

В данном случае система проверит что присвоение без потерь будет невозможно, возникнет исключение, но переменная lv_p останется без изменений. Другим выходом будет — всегда очищать переменные в блоке CATCH при присвоении не совместимых, но конвертируемых типов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *