Discussion:
Accès sur le type limité File_Type.
(trop ancien pour répondre)
Blady
2020-08-08 09:48:03 UTC
Permalink
Bonjour,

J'ai une variable F3 (dans mon programme de test) qui est est utilisée
pour avoir soit un fichier sur disque soit la sortie standard.
Ada.Text_ÏO.File_Type étant un type limité, je pensais utiliser le type
File_Access (procédure P1) ou un accès anonyme (procédure P2) mais je
n'ai pas de succès :

1. with Ada.Text_IO; use Ada.Text_IO;
2. procedure Essais_02 is
3. procedure P1 is
4. F1 : File_Type;
5. begin
6. Create (F1);
7. declare
8. Cond : Boolean;
9. F2 : File_Access := new File_Type;
|
initialization required for access-to-constant allocator
10. F2b : File_Access := new File_Type'(F1);
|
initialization not allowed for limited types
11. F3 : File_Access;
12. begin
13. if Cond then
14. F3 := Standard_Output;
15. else
16. F3 := F2;
17. end if;
18. end;
19. end;
20. procedure P2 is
21. begin
22. declare
23. Cond : Boolean;
24. F2 : access File_Type := new File_Type;
25. F3 : access File_Type;
26. begin
27. if Cond then
28. F3 := Standard_Output;
|
access-to-constant operand type not allowed
29. else
30. Create (F2.all);
31. F3 := F2;
32. end if;
33. end;
34. end;
35. begin
36. null;
37. end Essais_02;

Quel est le moyen pour avoir les deux possibilités avec F3 ?

Merci Pascal.
https://blady.pagesperso-orange.fr
J-P. Rosen
2020-08-09 15:05:25 UTC
Permalink
Post by Blady
Bonjour,
J'ai une variable F3 (dans mon programme de test) qui est est utilisée
pour avoir soit un fichier sur disque soit la sortie standard.
Ada.Text_ÏO.File_Type étant un type limité, je pensais utiliser le type
File_Access (procédure P1) ou un accès anonyme (procédure P2) mais je
Le plus simple pour faire ça (mais ça ne correspond pas forcément à ce
que tu veux faire), c'est d'écrire sur le fichier par défaut
(Current_Ouput), et de le rediriger vers un fichier avec Set_Output.

Sinon:>      1. with Ada.Text_IO; use Ada.Text_IO;
Post by Blady
     2. procedure Essais_02 is
     3.    procedure P1 is
     4.       F1 : File_Type;
     5.    begin
     6.       Create (F1);
     7.       declare
     8.          Cond : Boolean;
     9.          F2   : File_Access := new File_Type;
                                       |
        >>> initialization required for access-to-constant allocator
Normal, File_Access est un pointeur sur constante
Post by Blady
    10.          F2b  : File_Access := new File_Type'(F1);
                                       |
        >>> initialization not allowed for limited types
Le message n'est pas excellent: l'initialisation est autorisée si c'est
un agrégat ou un appel de fonction ("build in place", ce qui n'est pas
le cas ici); sinon, il y a copie, ce qui n'est pas autorisé pour un type
limité.
Post by Blady
    20.    procedure P2 is
    21.    begin
    22.       declare
    23.          Cond : Boolean;
    24.          F2   : access File_Type := new File_Type;
    25.          F3   : access File_Type;
    26.       begin
    27.          if Cond then
    28.             F3 := Standard_Output;
                          |
        >>> access-to-constant operand type not allowed
Standard_Output renvoie un File_Access, donc un pointeur sur constante
qui ne peut pas être affecté à un pointeur sur variable. Si tu déclares:
F3 : access constant File_Type;
ça marche. NB: les procédures d'E/S prennent un fichier en mode in, donc
on peut utiliser un pointeur sur constante.

Un autre moyen simple est de passer le fichier en paramètre à une
procédure qui fait le boulot:

procedure Do_The_Job (On: File_Type) is ...

if Cond then
Do_The_Job (Standard_Output);
else
Do_The_Job (F3);
end if;

Et on économise des pointeurs...
--
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr
Blady
2020-08-09 20:45:06 UTC
Permalink
Post by J-P. Rosen
Post by Blady
Bonjour,
J'ai une variable F3 (dans mon programme de test) qui est est utilisée
pour avoir soit un fichier sur disque soit la sortie standard.
Ada.Text_ÏO.File_Type étant un type limité, je pensais utiliser le type
File_Access (procédure P1) ou un accès anonyme (procédure P2) mais je
Le plus simple pour faire ça (mais ça ne correspond pas forcément à ce
que tu veux faire), c'est d'écrire sur le fichier par défaut
(Current_Ouput), et de le rediriger vers un fichier avec Set_Output.
J'ai un peu simplifié, du code que je ne veux pas trop modifier appelle
une série de Put_Line avec un fichier mettons F3.
Suivant la valeur de F3 le programme envoie soit sur la sortie d'erreur
soit sur une fenêtre graphique.
J'ai recodé un package du type de Text_IO avec un type File_Type objet
perso (voir aussi mon message sur CLA):
https://github.com/Blady-Com/SparForte/blob/with_gnoga/src/gui/input_output-text_io.ads#L3

F3 est du type 'Class
(https://github.com/Blady-Com/SparForte/blob/with_gnoga/src/gui/input_output-text_io.ads#L4)
qui reçoit soit l'objet graphique soit l'objet de la sortie d'erreur.
Ce que je n'arrive pas à coder c'est le lien de l'objet de la sortie
d'erreur avec la sortie d'erreur de Text_IO dans le champ correspondant
de l'objet:
https://github.com/Blady-Com/SparForte/blob/with_gnoga/src/gui/input_output-text_io-file_text_io.ads#L141
Je sais faire le lien avec un fichier mais pas avec la sortie d'erreur
Standard_Error (ou les deux autres Standard_XXX c'est pareil).
Post by J-P. Rosen
Sinon:>      1. with Ada.Text_IO; use Ada.Text_IO;
Post by Blady
     2. procedure Essais_02 is
     3.    procedure P1 is
     4.       F1 : File_Type;
     5.    begin
     6.       Create (F1);
     7.       declare
     8.          Cond : Boolean;
     9.          F2   : File_Access := new File_Type;
                                       |
        >>> initialization required for access-to-constant allocator
Normal, File_Access est un pointeur sur constante
OK
Post by J-P. Rosen
Post by Blady
    10.          F2b  : File_Access := new File_Type'(F1);
                                       |
        >>> initialization not allowed for limited types
Le message n'est pas excellent: l'initialisation est autorisée si c'est
un agrégat ou un appel de fonction ("build in place", ce qui n'est pas
le cas ici); sinon, il y a copie, ce qui n'est pas autorisé pour un type
limité.
OK
Post by J-P. Rosen
Post by Blady
    20.    procedure P2 is
    21.    begin
    22.       declare
    23.          Cond : Boolean;
    24.          F2   : access File_Type := new File_Type;
    25.          F3   : access File_Type;
    26.       begin
    27.          if Cond then
    28.             F3 := Standard_Output;
                          |
        >>> access-to-constant operand type not allowed
Standard_Output renvoie un File_Access, donc un pointeur sur constante
F3 : access constant File_Type;
ça marche. NB: les procédures d'E/S prennent un fichier en mode in, donc
on peut utiliser un pointeur sur constante.
Je ne peux pas non plus car si le programme appelle Close par exemple
j'obtiens l'erreur : "actual for "File" must be a variable".
Post by J-P. Rosen
Un autre moyen simple est de passer le fichier en paramètre à une
procedure Do_The_Job (On: File_Type) is ...
if Cond then
Do_The_Job (Standard_Output);
else
Do_The_Job (F3);
end if;
Et on économise des pointeurs...
Pour les raisons évoquées ci-dessus je ne préfère pas embarquer la
condition trop loin dans le programme.

Une question annexe me vient : quel est l'usage des sous-programmes
retournant File_Access si on ne peut pas les mettre dans une variable
avec des fichiers normaux ?
J-P. Rosen
2020-08-10 13:43:47 UTC
Permalink
Post by Blady
Post by J-P. Rosen
     20.    procedure P2 is
     21.    begin
     22.       declare
     23.          Cond : Boolean;
     24.          F2   : access File_Type := new File_Type;
     25.          F3   : access File_Type;
     26.       begin
     27.          if Cond then
     28.             F3 := Standard_Output;
                           |
         >>> access-to-constant operand type not allowed
Standard_Output renvoie un File_Access, donc un pointeur sur constante
    F3 : access constant File_Type;
ça marche. NB: les procédures d'E/S prennent un fichier en mode in, donc
on peut utiliser un pointeur sur constante.
Je ne peux pas non plus car si le programme appelle Close par exemple
j'obtiens l'erreur : "actual for "File" must be a variable".
Il n'y a que les procédures d'ouverture/fermeture qui prennent un
paramètre in out, les autres sont en in. Et pour ce que tu veux faire,
il me parait normal (pour ne pas dire souhaitable) d'interdire les
ouvertures/fermetures. Sinon, tu pourrais fermer Standard_Output!
Post by Blady
Une question annexe me vient : quel est l'usage des sous-programmes
retournant File_Access si on ne peut pas les mettre dans une variable
avec des fichiers normaux ?
On peut les utiliser pour Get et Put. L'idée, c'est que quand un
sous-programme a besoin de travailler sur un fichier déterminé
extérieurement, on lui passe le fichier ouvert, et c'est à l'appelant de
le refermer.
--
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr
Loading...