Некоторые особенности при работе со структурами типа GROUP

Думаю, многие знают, что такое Deep Assignment, или по нашему «глубокое присваивание»? Для тех, кто не в курсе — почитайте про это в Help`e.

Так вот, будет полезно знать некоторые особенности данной фичи, в применении к группам/классам/очередям/файлам.

1. Внутренняя реализация данной фичи основана на так называемом «списке соответствия полей», где каждому полю одной структуры сопоставлено поле с таким же названием из другой структуры. Используются, естественно, просто номера полей в своих структурах. Данный список составляется КОМПИЛЯТОРОМ во время компиляции программы. Таким образом данная фича НЕ РАБОТАЕТ для не типизированных реферал-указателей! Грубо говоря, разработчики просто поленились, так как данный список прекрасно строится на основе той инфы о группах, которая доступна в рантайме.
Пример:

TGrp   GROUP,TYPE
Field1   LONG
       END
Grp1   LIKE(TGrp)
Grp2   GROUP(TGrp)
Field2   BYTE
       END

GRef   &GROUP       ! Deep Assignment не работает
GRef1  &Grp1
GRef2  &Grp2

  Code
  GRef1 &= Grp1
  GRef2 &= Grp2
  GRef2 :=: GRef1   ! Будет работать
  GRef &= Grp1
  GRef2 :=: GRef    ! Работать уже не будет
  Return

Кстати! Для тех, кто не в курсе — не пытайтесь использовать реферал-указатели, пока они не указывают на какую-либо переменную! GPF обеспечен! Это, кстати, одна из ошибок в ядре, связанная с отсутствием проверок указателей на валидность.

2. Если первую особенность ошибкой не назовешь, то данная особенность, думаю, является именно ошибкой. И ошибкой компилятора! Как было сказано в п.1, «список соответствия полей» строится компилятором на основе имен полей, участвующих в «глубоком присваивании», структур. Но, при этом компилятор не учитывает, что поля с одинаковыми именами могут находится в разных подгруппах! Более того — что полей с одинаковыми именами в одной структуре может быть несколько в разных подгруппах! И компилятор честно начинает генерить пары соответствия для каждого совпадения имен полей!
Пример:

TDateTime    GROUP,TYPE
Date           DATE
Time           TIME
             END
Grp1         GROUP
Create         LIKE(TDateTime) ! 1,2,3 поля
Change         LIKE(TDateTime) ! 4,5,6 поля
             END
Grp2         GROUP
Create         LIKE(TDateTime)
Change         LIKE(TDateTime)
             END

  Code
  Grp1 :=: Grp2
  Return

В результате, после такого присваивания, получим:
Grp1.Create.Date = Grp2.Change.Date !!!
Grp1.Create.Time = Grp2.Change.Time !!!

так как компилятор сгенерит для данного случая такой «список соответствия полей»:

1 - 1   ! Grp1.Create      = Grp2.Create
2 - 2   ! Grp1.Create.Date = Grp2.Create.Date
2 - 5   ! Grp1.Create.Date = Grp2.Change.Date   !!!
3 - 3   ! Grp1.Create.Time = Grp2.Create.Time
3 - 6   ! Grp1.Create.Time = Grp2.Change.Date   !!!
4 - 4   ! Grp1.Change      = Grp2.Change
5 - 2   ! Grp1.Change.Date = Grp2.Create.Date
5 - 5   ! Grp1.Change.Date = Grp2.Change.Date
6 - 3   ! Grp1.Change.Time = Grp2.Create.Time
6 - 6   ! Grp1.Change.Time = Grp2.Create.Time

Кстати! Вадим (Синявский), насколько я помню, в ранних релизах твоего шаблона DC использовалось именно Deеp Assignment?