OS : Windows seven. Delphi 2010 et Delphi 7

Résumé : survenue d'une erreur fatale générée par le compilateur DCC sous Delphi 2010.

J'ouvre cette discussion à la fois pour interroger les spécialistes des nouvelles versions Delphi mais également pour donner
une piste potentielle lorsque cette erreur apparaît.

J'aimerais savoir si il y a une limitation seulement dans cette version particulière (D2010) et si elle disparait dans les versions ultérieures.

Après avoir eu cette erreur pour le moins difficile à traiter j'ai réussi à isoler l'élément syntaxique qui l'a provoquée dans mon cas.

L'erreur est provoquée par la déclaration d'un trop grand nombre de "property" dans une classe ce nombre étant précisément égal à 1480.
Il faut savoir qu'avec le compilateur Delphi 7 j'arrive à compiler sans problèmes une classe avec 10000 "property".

Évidement on peut se poser la question de savoir qui peut créer des classes avec 10000 "property" : dans mon application (industrielle) certaines
unités du projet Delphi sont générées automatiquement (parfois on peut faire des choses étonnantes) et ont des dimensions très considérables.

Mes éléments concrets :

Le code (partiel) du projet qui compile sous D7 mais pas sous D2010 (remarque le programme principal n'a pas d'importance)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
//programme principal
library MyLib;
 
uses
  sysutils, myClasse;
 
var obj:tMyClasse;
 
begin
  obj:=tMyClasse.create;
  obj.nombre_0:=5.4;
  FreeAndNil(obj);
end.
 
//unité qui pose problème 
unit myClasse;
 
interface
 
type
 
  tMyClasse=class
  protected
    function getVal(index:integer):double;
    procedure setVal(index:integer; dbl:double);
  public
    property nombre_0:double  index 0 read getVal write setVal;
    property nombre_1:double index 1 read getVal write setVal ;
    property nombre_2:double index 2 read getVal write setVal ;
//...etc
    property nombre_1480:double index 1480 read getVal write setVal ;
  end;
 
implementation
 
    function tMyClasse.getVal(index:integer):double;
    begin
      result:=index;
    end;
 
    procedure tMyClasse.setVal(index:integer; dbl:double);
    begin
      exit;
    end;
 
end.
Le code du programme (console) qui permet de générer autant de "property" que nécessaire
il se lance par la ligne de commande suivante (premier argument : le répertoire pour accueillir le code généré, deuxième argument le nombre de "property"):

genereCodeBugD2010 c:\temp\props 1480


Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
72
73
74
75
76
77
78
79
80
81
82
program genereCodeBugD2010;
{$APPTYPE CONSOLE}
uses
  classes,
  SysUtils;
 
procedure generer(const repertoire:string; const nombreProprietes:integer);
  var liste:TStringList;
 
  procedure aj(const tab:array of string);
  var i:integer;
  begin
    for I := 0 to high(tab) do
      liste.Add(tab[i])
  end;
 
  procedure creeProg;
  begin
     Aj(['library MyLib;']);
     Aj(['']);
     Aj(['uses']);
     Aj(['  sysutils,']);
     Aj(['  myClasse;']);
     Aj(['']);
     Aj(['var obj:tMyClasse;']);
     Aj(['']);
     Aj(['begin']);
     Aj(['  obj:=tMyClasse.create;']);
     Aj(['  obj.nombre_0:=5.4;']);
     Aj(['  FreeAndNil(obj);']);
     Aj(['end.']);
  end;
 
  procedure addProperty(const numPropriete:integer);
  begin
     Aj(['    property nombre_'+intToStr(numPropriete)+':double index '+intToStr(numPropriete)+' read getVal write setVal ;']);
  end;
 
  procedure creeUnit();
  var i:integer;
  begin
     Aj(['unit myClasse;']);
     Aj(['interface']);
     Aj(['']);
     Aj(['type ']);
     Aj(['  tMyClasse=class']);
     Aj(['  protected']);
     Aj(['    function getVal(index:integer):double;']);
     Aj(['    procedure setVal(index:integer; dbl:double);']);
     Aj(['  public']);
     Aj(['    property nombre_'+intToStr(0)+':double  index 0 read getVal write setVal;']);
     for I := 1 to nombreProprietes do addProperty(i);
     Aj(['  end;']);
     Aj(['implementation']);
     Aj(['']);
     Aj(['    function tMyClasse.getVal(index:integer):double;']);
     Aj(['    begin']);
     Aj(['      result:=index;']);
     Aj(['    end;']);
     Aj(['    procedure tMyClasse.setVal(index:integer; dbl:double);']);
     Aj(['    begin']);
     Aj(['    end;']);
     Aj(['end.']);
  end;
 
begin
  liste:=TStringList.Create;
  try
    if not directoryExists(repertoire) and not ForceDirectories(repertoire) then  exit;
    creeProg;
    liste.SaveToFile(IncludeTrailingPathDelimiter(repertoire)+'MyLib.dpr');
    liste.Clear;
    creeUnit;
    liste.SaveToFile(IncludeTrailingPathDelimiter(repertoire)+'myClasse.pas');
  finally
    FreeAndNil(liste);
  end;
end;
 
begin
  generer(paramStr(1), StrToIntDef(paramStr(2),10));
end.
L'erreur renvoyée par le compilateur
[DCC Erreur fatale]F2084 Erreur interne : L3302