Hocus Bogus
Par Fred le mercredi 28 décembre 2011, 15:06 - Développement - Lien permanent
Comme tout bon sorcier de l'informatique, c'est grâce à l'agilité de mes petits doigts que j'ai ouvert la boîte de Pandore du compilateur GCC pour en sortir un bogus.
Bon, n'exagérons rien, je suis fort, même très fort[1] mais là, je n'y suis pas pour grand chose :D
Dans le cadre de mon petit projet de développement perso en Ada (cf. ce précédent billet), j'ai décidé de faire un niveau d'abstraction me permettant d'écrire un accord de la même façon qu'une gamme.
L'idée géniale a donc été de créer un type possédant les caractéristiques suivantes :
- Un nom
- Une structure correspondant à un ensemble de d'intervalles
Le type NamedStructure était né.
Désirant faire de celui-ci un type manipulable seulement au travers de procédures et fonctions, il était normal d'en faire un type privé[2].
Ensuite, la création de types Scale et Chord ne correspond qu'à définir ceux-ci comme types dérivés[3] et à réécrire les opérations de manipulations spécifiques.
En clair, cela ressemble franchement à une sorte d'héritage dans les langages purement objets.
Vous vous demandez donc certainement pourquoi je n'ai pas utilisé de classes. C'est simple, je n'ai pas besoin de faire de polymorphisme ou d'autres choses du même acabit[4] :D
Venons-en aux faits !
Lors de l'écriture de tout ce code, je suis arrivé à quelque chose du style suivant (attention, c'est long) :
with Root_Private; package Derived_Root is type Derived_Root_obj(Size : Positive) is private; function Create(Name : String) return Derived_Root_obj; private type Derived_Root_obj(Size: Positive) is new Root_Private.Root(Size); end Derived_Root; package Root_Private is type Root(Size : Positive) is private; function Create(Name : String) return Root; private type Root(Size : Positive) is record Name : String(1..Size); end record; end Root_Private; package body Derived_Root is function Create(Name : String) return Derived_Root_obj is begin return Derived_Root_obj(Root_Private.Create(Name)); end Create; end Derived_Root; package body Root_Private is function Create(Name : String) return Root is Returned_Root : Root(Name'Length); begin Returned_Root.Name := Name; return Returned_Root; end Create; end Root_Private; with Root_Private; use Root_Private; with Derived_Root; use Derived_Root; procedure Test is My_Root : Root := Create("My test"); My_Derived : Derived_Root_obj := Derived_Root.Create("My derived root"); begin null; end Test;
Et bien, essayez donc de la compiler[5] et vous tomberez normalement sur
gnatgcc -c test.adb +===========================GNAT BUG DETECTED==============================+ | 4.6.1 20110627 (release) -=> GNAT AUX [FreeBSD] (i386-aux-freebsd8.2) GCC error:| | in gnat_to_gnu_entity, at ada/gcc-interface/decl.c:599 | | Error detected at test.adb:6:49 | | Please submit a bug report; see http://gcc.gnu.org/bugs.html. | | Use a subject line meaningful to you and us to track the bug. | | Include the entire contents of this bug box in the report. | | Include the exact gcc or gnatmake command that you entered. | | Also include sources listed below in gnatchop format | | (concatenated together with no headers between files). | +==========================================================================+ Please include these source files with error report Note that list may not be accurate in some cases, so please double check that the problem can still be reproduced with the set of files listed. Consider also -gnatd.n switch (see debug.adb). test.adb root_private.ads derived_root.ads compilation abandoned gnatmake: "test.adb" compilation error
Ça méritait bien un petit rapport de bug tout ça, non ?
Bon ceci dit, j'ai trouvé une parade en publiant
ma classe NamedStructure (ici, Root) au lieu de la laisser en private
mais je pense qu'il y a d'autres moyens plus sympas pour forcer l'encapsulation et l'utilisation des nouveaux types... c'est beau le dev :D