powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Delphi XE4, лёгкий баг в аттрибутах
4 сообщений из 4, страница 1 из 1
Delphi XE4, лёгкий баг в аттрибутах
    #39579087
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сразу зафигачу безразмерный листинг для тех кто такого не страшится.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  rtti;

type
  // TSomeType = (stA, stB, stC);
  TSomeType = (stA, stB, stC, stD, stE, stF, stG, stH, stI, stJ, stK, stL, stM,
    stN, stO, stP, stQ, stR, stT, stU, stV, stW, stX, stY, stZ, st0, st1, st2,
    st3, st4, st5, st6, st7, st8, st9);
  TSomeTypeSet = set of TSomeType;
type
  SomeAttribute = class(TCustomAttribute)
  private
    FElements: TSomeTypeSet;
  public
    constructor Create({const }AttrElements: TSomeTypeSet);
    property Elements: TSomeTypeSet read FElements;
  end;

  [SomeAttribute([stA, stC])]
  TClassWithAttribute = class
  end;

function GetChildrenFor(aClass: TClass): TSomeTypeSet;
var
  rttiContext: TRttiContext;
  rttiType: TRttiType;
  attribute: TCustomAttribute;
begin
  rttiContext := TRttiContext.Create;
  try
    rttiType := rttiContext.GetType(aClass);
    for attribute in rttiType.GetAttributes do  // <- падает здесь
      if attribute is SomeAttribute then
        Exit(SomeAttribute(attribute).Elements);
    Result := [];
  finally
    rttiContext.Free;
  end; // try to recover and return the DisplayLabel
end;

{ SomeAttribute }

constructor SomeAttribute.Create({const }AttrElements: TSomeTypeSet);
begin
  FElements := AttrElements;
end;

var
  Elements: TSomeTypeSet;
  El: TSomeType;
begin
  try
    Elements := GetChildrenFor(TClassWithAttribute);
    for El in Elements do
      Writeln(format('Element: %d', [integer(El)]));
    readln;
  except
    on E: Exception do
    begin
      Writeln(E.ClassName, ': ', E.Message);
      readln;
    end;
  end;
end.


Смысл бага в том, что в атрибут компилируется разный тип данных в зависимости от количества елементов в перечисляемом типе.
Если в типе TSomeType оставить несколько элементов - приведённая программа работает, иначе падает, потому что вместо сета в аттрибут передаётся массив из 2-х элементов и при создании атрибута инвокер конструктора падает с ошибкой Invalid class typecast.

Не знаю, есть ли здесь что обсуждать и решён ли баг в более новых версиях, но оставлю это здесь для информации.
...
Рейтинг: 0 / 0
Delphi XE4, лёгкий баг в аттрибутах
    #39579102
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimonka,

Если я не ошибаюсь, баг связан с некорректным определением размера множества. Пофикшен, вроде, в берлине только.
...
Рейтинг: 0 / 0
Delphi XE4, лёгкий баг в аттрибутах
    #39579103
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал передать список элементов как array of const, ошибка:
E2150 Bad argument type in variable type array constructor
Похоже Дельфи не очень любит сеты с количеством элементов > 32
...
Рейтинг: 0 / 0
Delphi XE4, лёгкий баг в аттрибутах
    #39579107
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaПохоже Дельфи не очень любит сеты с количеством элементов > 32
Да, именно для таких сетов в RTTI размер хранится с минусом.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Delphi XE4, лёгкий баг в аттрибутах
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]