Prev: Types, packages & objects : the good old naming conventions question (without religious ware)
Next: Performance of the Streams 'Read and 'Write
From: Peter Mueller on 29 Oct 2009 16:48 Hello, I have some strings and depending of an enum I want to return a string. My code looks the following: function Event_To_String(Event : in Events_Type) return String is Ev1_Name : aliased constant String :="ev3434"; Ev2_Name : aliased constant String :="evEnd"; eventStrings : constant array (1..2) of access constant String := (Ev1_Name'Access,Ev2_Name'Access); begin return EventStrings(Events_Type'Pos(Event)); end Event_To_String; The compiler says: expected type "Standard.String" found type access to "Standard.String" defined ... I think that my code returns the pointer to the string and not the string. But I don't know how to fix it. Is there a better solution to create an array of strings and accessing them with an index? Thanks, Peter
From: Jeffrey R. Carter on 29 Oct 2009 17:36 Peter Mueller wrote: > > I have some strings and depending of an enum I want to return a > string. My code looks the following: > > function Event_To_String(Event : in Events_Type) return String is > Ev1_Name : aliased constant String :="ev3434"; > Ev2_Name : aliased constant String :="evEnd"; > eventStrings : constant array (1..2) of access constant String := > (Ev1_Name'Access,Ev2_Name'Access); > > begin > > return EventStrings(Events_Type'Pos(Event)); > end Event_To_String; > > The compiler says: > > expected type "Standard.String" > found type access to "Standard.String" defined ... > > I think that my code returns the pointer to the string and not the > string. But I don't know how to fix it. You're correct. But first, a probable error: 'Pos for an enumeration type returns values starting at zero: type E is (One, Two); E'Pos (One) = 0 E'Pos (Two) = 1 Your array index range is "Integer range 1 .. 2". So, assuming Events_Type is the first-named subtype (the name used in the type declaration), if you ever called this with Events_Type'First, you would get Constraint_Error. However, there is no reason to use Integer indices. An array may be indexed by any discrete subtype: type Event_Name is array (Events_Type) of ...; Then you can say Eventstrings (Event) As for your question, you dereference an access value by appending .all to it: Eventstrings (Event).all > Is there a better solution to create an array of strings and accessing > them with an index? For a discrete subtype like this, probably not. What you have is a mapping Events_Type => String. If you were mapping something non-discrete to String, than a map or similar associative data structure would be better. It's also possible to store String values in [Un]Bounded_String objects; that would be better if the strings are not constant. It would also eliminate (explicit) use of access types and values. -- Jeff Carter "C's solution to this [variable-sized array parameters] has real problems, and people who are complaining about safety definitely have a point." Dennis Ritchie 25
From: Hibou57 (Yannick Duchêne) on 29 Oct 2009 17:38 On 29 oct, 21:48, Peter Mueller <peter.o.muel...(a)gmx.de> wrote: > Hello, > > I have some strings and depending of an enum I want to return a > string. My code looks the following: > > function Event_To_String(Event : in Events_Type) return String is > Ev1_Name : aliased constant String :="ev3434"; > Ev2_Name : aliased constant String :="evEnd"; > eventStrings : constant array (1..2) of access constant String := > (Ev1_Name'Access,Ev2_Name'Access); > > begin > > return EventStrings(Events_Type'Pos(Event)); > end Event_To_String; > > The compiler says: > > expected type "Standard.String" > found type access to "Standard.String" defined ... > > I think that my code returns the pointer to the string and not the > string. But I don't know how to fix it. > Is there a better solution to create an array of strings and accessing > them with an index? > > Thanks, > Peter The compiler error you've reported is not the single point to notice about in test case. The first one, the one you are talking about : You have a function whose return type is String. You have an array of anonymous access to String. The return statement returns an item of that array. So fat, you have then a function which is expected to return a String, but you return an access to String. The expected returned type of the function and the type you return are not the same. The compiler complains about that, it tries to tell you that the expression you attempt to return, is not of type String. To get a String from an access to String, you have to use the .all suffixe. Do know what is .all ? If you need explanations about it, just tell, you will be asked about it. Just change return EventStrings(Events_Type'Pos(Event)); into return EventStrings(Events_Type'Pos(Event)).all; and every thing will be OK. That's to correct what does not work. To got further now : you wants an association from Events_Type to String, aren't you ? So why to you use an array whose index range is 1 .. 2 ? I suggest you to use Events_Type instead. So, as a second step, you may turn eventStrings : constant array (1..2) of access constant String into eventStrings : constant array (Events_Type) of access constant String Do you understand what it is ? Then, as you use Events_Type as the array index range, you do not need any more (and must not also), the Events_Type'Pos(Event) and you can use just Event instead So then replace return EventStrings(Events_Type'Pos(Event)).all with return EventStrings(Event).all Providing that your Events_Type is a enumeration of two elements (otherwise, just update the array initialization to match the required number of items). Next now : you have an array of constant, which will be initialized each times you enter the function. There are no kind of static in Ada like there are in C. To achieve static global allocation, you have to declare your array outside of the function, at the package level. So now, try to change function Event_To_String(Event : in Events_Type) return String is Ev1_Name : aliased constant String :="ev3434"; Ev2_Name : aliased constant String :="evEnd"; eventStrings : constant array (Events_Type) of access constant String := (Ev1_Name'Access, Ev2_Name'Access); begin return EventStrings(Event).all; end Event_To_String;begin into Ev1_Name : aliased constant String :="ev3434"; Ev2_Name : aliased constant String :="evEnd"; eventStrings : constant array (Events_Type) of access constant String := (Ev1_Name'Access, Ev2_Name'Access); function Event_To_String(Event : in Events_Type) return String is begin return EventStrings(Event).all; end Event_To_String;begin What tutorial do you have in hands to learn Ada ? Read you soon Y.
From: Hibou57 (Yannick Duchêne) on 29 Oct 2009 17:42 On 29 oct, 22:36, "Jeffrey R. Carter" <spam.jrcarter....(a)spam.acm.org> wrote: > You're correct. But first, a probable error: He is not at all : his implementation is returning an access to String while the function is expected to return a String.
From: Gautier write-only on 29 Oct 2009 18:46
Hello! My usual way of doing that is: function Event_To_String(Event : in Events_Type) return String is begin case Event is when Ev1 => return "ev3434"; when Ev2 => return "evEnd"; end case; end; You live longer without pointer ;-). For more complicated cases, I use unbounded strings, like there: type External_packer_info is record name, title, URL, options: Unbounded_String; expanded_options : Unbounded_String; -- options with dynamically expanded tokens made_by_version : Unsigned_16; pkzm : Zip.PKZip_method; end record; ext: array(External) of External_packer_info:= ( (U("zip.exe"), U("Zip"), U("http://info-zip.org/"), U("-9"), U (""), 20, Zip.deflate), -- Zip 2.32 or later ... ); HTH _________________________________________________________ Gautier's Ada programming -- http://sf.net/users/gdemont/ NB: For a direct answer, e-mail address on the Web site! |