* How to do it in Ada ? @ 2001-07-16 3:33 Tomasz Wegrzanowski 2001-07-16 5:31 ` Jeffrey Carter ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Tomasz Wegrzanowski @ 2001-07-16 3:33 UTC (permalink / raw) int main(int argc, char **argv) { int *x; int n; n = (argc==1)?1:atoi(argv[1]); x = malloc (n*sizeof(int)); for (x=0;x<n;x++) x[i]=0; /* ... */ } Something like that ... how to do such dynamic array allocation in Ada ? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 3:33 How to do it in Ada ? Tomasz Wegrzanowski @ 2001-07-16 5:31 ` Jeffrey Carter 2001-07-16 6:41 ` Al Christians 2001-07-16 6:51 ` tmoran 2 siblings, 0 replies; 13+ messages in thread From: Jeffrey Carter @ 2001-07-16 5:31 UTC (permalink / raw) Tomasz Wegrzanowski wrote: > > int main(int argc, char **argv) > { > int *x; > int n; > > n = (argc==1)?1:atoi(argv[1]); > x = malloc (n*sizeof(int)); > for (x=0;x<n;x++) > x[i]=0; > > /* ... */ > } > > Something like that ... how to do such dynamic array allocation in Ada ? The simple answer is, you don't. Ada makes this kind of thing much simpler and less error-prone than in a low-level language. procedure The_Right_Way is type List is array (Positive range <>) of Integer; function Get return Positive is separate; Num_Integers : constant Positive := Get; X : List (1 .. Num_Integers) := (others => 0); begin -- The_Right_Way ... end The_Right_Way; Note that everything in your example is done in the declarative part. -- Jeff Carter "Nobody expects the Spanish Inquisition!" Monty Python's Flying Circus ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 3:33 How to do it in Ada ? Tomasz Wegrzanowski 2001-07-16 5:31 ` Jeffrey Carter @ 2001-07-16 6:41 ` Al Christians 2001-07-16 6:51 ` tmoran 2 siblings, 0 replies; 13+ messages in thread From: Al Christians @ 2001-07-16 6:41 UTC (permalink / raw) with Ada.Text_IO; with Ada.Command_Line; procedure Initialize_Array is A: Array(1..Integer'Value(Ada.Command_Line.Argument(1))) of Integer := ( Others => 0 ); begin -- The array is already initialized -- The following statements just show that it is Ada.Text_IO.Put( "First =" & Integer'Image(A'First)); Ada.Text_IO.Put( " First Value =" & Integer'Image(A(A'First))); Ada.Text_IO.Put( " Last =" & Integer'Image(A'Last)); Ada.Text_IO.Put( " Last Vale=" & Integer'Image(A(A'Last))); end; Tomasz Wegrzanowski wrote: > > int main(int argc, char **argv) > { > int *x; > int n; > > n = (argc==1)?1:atoi(argv[1]); > x = malloc (n*sizeof(int)); > for (x=0;x<n;x++) > x[i]=0; > > /* ... */ > } > > Something like that ... how to do such dynamic array allocation in Ada ? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 3:33 How to do it in Ada ? Tomasz Wegrzanowski 2001-07-16 5:31 ` Jeffrey Carter 2001-07-16 6:41 ` Al Christians @ 2001-07-16 6:51 ` tmoran 2001-07-16 16:56 ` Mark Lundquist 2001-07-16 17:37 ` Ken Garlington 2 siblings, 2 replies; 13+ messages in thread From: tmoran @ 2001-07-16 6:51 UTC (permalink / raw) > int main(int argc, char **argv) > { > int *x; > int n; > > n = (argc==1)?1:atoi(argv[1]); > x = malloc (n*sizeof(int)); > for (x=0;x<n;x++) > x[i]=0; > > /* ... */ > } The most natural Ada way is: with Ada.Command_Line; procedure Main is N : Integer; begin if Ada.Command_Line.Argument_Count = 0 then N := 1; else N := Integer'value(Ada.Command_Line.Argument(1)); end if; declare X : array(1 .. N) of Integer := (others=>0); begin .... end; end Main; > Something like that ... how to do such dynamic array allocation in Ada ? If you mean heap allocation, not just dynamic stack allocation, then: with Ada.Command_Line; procedure Main is N : Integer; type X_Array_Type is array(Integer range <>) of Integer; type Px_Type is access X_Array_Type; X : Px_Type; begin if Ada.Command_Line.Argument_Count = 0 then N := 1; else N := Integer'value(Ada.Command_Line.Argument(1)); end if; X := new X_Array_Type'((1 .. N => 0)); .... end Main; ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 6:51 ` tmoran @ 2001-07-16 16:56 ` Mark Lundquist 2001-07-16 18:42 ` Nonsense (was Re: How to do it in Ada ?) Mark Lundquist ` (2 more replies) 2001-07-16 17:37 ` Ken Garlington 1 sibling, 3 replies; 13+ messages in thread From: Mark Lundquist @ 2001-07-16 16:56 UTC (permalink / raw) I'd like to comment on Tom Moran's example, to highlight some Ada concepts for the benefit of the original poster and any other newbies who might be interested... In Tom's first example, all the important stuff is in this line: X : array(1 .. N) of Integer := (others=>0); Things to note: 1) No heap allocation is required. In C, the size in an array declaration _has_ to be static. So in the original C example, the use of malloc() is necessitated by the fact that we don't know at compile time how many elements the array will have. In Ada, you can declare an object with a non-static constraint. The language doesn't specify where the array in this example will be allocated from. Concepts like "stack" and "heap" are implementation-specifics; the Ada language definition is at a more abstract level. However, virtually all Ada compilers will allocate this array on the stack (they might go to the heap for a sufficiently large array). So, not only is there no pointer stuff or allocation stuff in the syntax, but for an array of sufficiently small size there is also no "behind the scenes" heap allocation -- it's going to happen on the stack, so (a) it's more efficient and (b) you don't have to remember to free it. 2) The "(others => 0)" thing is called an aggregate. Aggregates are to composite types (arrays and records) what literals are to elementary types, so you can use an aggregate to initialize an object of a composite type. So for arrays, there is no need to code an iteration across the array elements. Not only does this mean that you're programming at a higher level of abstraction, it leaves freedom for the compiler to do it more efficiently, if the compiler knows a better way then elementwise iteration. > If you mean heap allocation, not just dynamic stack allocation, > then: > > with Ada.Command_Line; > procedure Main is > N : Integer; > type X_Array_Type is array(Integer range <>) of Integer; ^^^^^^^^^^^^^^^^^^^^^^^^^^ This defines what is called an "unconstrained type". The meaning is that an object of the type might have bounds given by any particular integer range. So the following object declarations are all valid: A : X_Array_Type (1 .. 20); B : X_Array_Type (0 .. 5); C : X_Array_Type (17 .. 33); D : X_Array_Type (-7 .. 13); Saying "Natural range <>" or "Positive range <>" would impose more requirements on legal index ranges (Natural and Positive are subtypes of Integer). It's a good idea to use Natural or Positive whenever possible to express your intent, not just use Integer for everything. (I know some people say that you shouldn't use any of them, but always define your own integer types... I don't really want to open that argument back up right now... :-) But I think everyone would agree that you shouldn't use Integer if you don't expect or intend negative values. Objects of an unconstrained array type have fixed bounds, but the bounds are established where the object is declared (not the type). (There's also a special case called an "unconstrained object", but that's beyond the scope of this lesson :-). By contranst, a constrained type (or constrained subtype) has the index range "built in": type A_Constrained_Array_Type is array (Positive range 1 .. 10) of Whatever; All objects of this type will have index range 1..10. In Tom's example, the reason for declaring this type is that the access type definition that follows requires a name for the "designated type": > type Px_Type is access X_Array_Type; To create the initialized object, he does this: > X := new X_Array_Type'((1 .. N => 0)); What about those double parenthesis... do those look funny? Well, they really are required. The inner set of parens and their contents, "(1..N => 0)" is the aggregate, like in the earlier example that used "others". The outer set of parens is part of something (" X_Array_Type'(...) ") called a "qualified expression" (qualified by the name of its type). So they aren't like parens in mathematical notation -- you can't collapse them. Could he have used "others" instead of "1 .. N" in that example? Not the way he wrote it... try writing "others" in the place of "1 .. N", and there's no longer an "N" anywhere in the declaration, i.e. Ada has no way of knowing that you want the array to be N things big! Alternatively, the declaration could be written this way: X := new X_Array_Type (1 .. N) := (others => 0); That is, constrain the subtype first, then you can use the "others" notation now that the constraints are established. Hope this helps somebody... I think it's always a good thing when you can pull out some concepts, as opposed to just having a "recipe" for writing an equivalent Language X code fragment in Language Y :-)... -- Mark ^ permalink raw reply [flat|nested] 13+ messages in thread
* Nonsense (was Re: How to do it in Ada ?) 2001-07-16 16:56 ` Mark Lundquist @ 2001-07-16 18:42 ` Mark Lundquist 2001-07-16 22:20 ` Jeffrey Carter ` (2 more replies) 2001-07-16 22:18 ` How to do it in Ada ? Jeffrey Carter 2001-07-20 5:39 ` David Thompson 2 siblings, 3 replies; 13+ messages in thread From: Mark Lundquist @ 2001-07-16 18:42 UTC (permalink / raw) I <up.yerz@nospam.com> wrote nonsense in message news:P0F47.357734$p33.7248200@news1.sttls1.wa.home.com... > >[snip] > > Alternatively, the declaration could be written this way: > > X := new X_Array_Type (1 .. N) := (others => 0); > What a bunch of crap! I can't belive I wrote that. It must have been before my first cup of coffee this morning. Or, I started writing that line and then went away, and then came back and blew a brain fuse when I resumed typing. Maybe when I went away, it was to get the cup of coffee! What one *could* write (not that you'd want to, but it illustrates the language concept I was trying to highlight), is: X : new X_Array_Type (1 .. N); begin X := (others => 0); . . Doh! Sheesh... -- mark ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Nonsense (was Re: How to do it in Ada ?) 2001-07-16 18:42 ` Nonsense (was Re: How to do it in Ada ?) Mark Lundquist @ 2001-07-16 22:20 ` Jeffrey Carter 2001-07-17 0:13 ` Ken Garlington 2001-07-17 3:53 ` Robert Dewar 2 siblings, 0 replies; 13+ messages in thread From: Jeffrey Carter @ 2001-07-16 22:20 UTC (permalink / raw) Mark Lundquist wrote: > > I <up.yerz@nospam.com> wrote nonsense in message > news:P0F47.357734$p33.7248200@news1.sttls1.wa.home.com... > > > >[snip] > > > > Alternatively, the declaration could be written this way: > > > > X := new X_Array_Type (1 .. N) := (others => 0); > > > > What a bunch of crap! I can't belive I wrote that. I'm glad you realize this is incorrect. However, ... > X : new X_Array_Type (1 .. N); > > begin > X := (others => 0); this is also incorrect. You could write X := new X_Array_Type (1 .. N); X.all := (X'range => 0); -- Jeffrey Carter ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Nonsense (was Re: How to do it in Ada ?) 2001-07-16 18:42 ` Nonsense (was Re: How to do it in Ada ?) Mark Lundquist 2001-07-16 22:20 ` Jeffrey Carter @ 2001-07-17 0:13 ` Ken Garlington 2001-07-17 3:53 ` Robert Dewar 2 siblings, 0 replies; 13+ messages in thread From: Ken Garlington @ 2001-07-17 0:13 UTC (permalink / raw) "Mark Lundquist" <up.yerz@nospam.com> wrote in message news:yAG47.358161$p33.7256533@news1.sttls1.wa.home.com... : : I <up.yerz@nospam.com> wrote nonsense in message : news:P0F47.357734$p33.7248200@news1.sttls1.wa.home.com... : > : >[snip] : > : > Alternatively, the declaration could be written this way: : > : > X := new X_Array_Type (1 .. N) := (others => 0); : > : : What a bunch of crap! I can't belive I wrote that. It must have been : before my first cup of coffee this morning. Or, I started writing that line : and then went away, and then came back and blew a brain fuse when I resumed : typing. Maybe when I went away, it was to get the cup of coffee! : : What one *could* write (not that you'd want to, but it illustrates the : language concept I was trying to highlight), is: : : X : new X_Array_Type (1 .. N); : : begin : X := (others => 0); This still looks a little off... perhaps you meant something like package X_Array is type Object is array (Positive range <>) of Integer; type Object_Access is access Object; function New_Object_Access return Object_Access; end X_Array; package body X_Array is function N return Positive is... (see other post) function New_Object_Access return Object_Access is X : Object_Access := new Object(1 .. N); begin X.all := (others => 0); return X; end New_Object_Access; end X_Array; ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Nonsense (was Re: How to do it in Ada ?) 2001-07-16 18:42 ` Nonsense (was Re: How to do it in Ada ?) Mark Lundquist 2001-07-16 22:20 ` Jeffrey Carter 2001-07-17 0:13 ` Ken Garlington @ 2001-07-17 3:53 ` Robert Dewar 2 siblings, 0 replies; 13+ messages in thread From: Robert Dewar @ 2001-07-17 3:53 UTC (permalink / raw) "Mark Lundquist" <up.yerz@nospam.com> wrote in message news:<yAG47.358161$p33.7256533@news1.sttls1.wa.home.com>... > What one *could* write (not that you'd want to, but it illustrates > the language concept I was trying to highlight), is: > > X : new X_Array_Type (1 .. N); > > begin > X := (others => 0); > . > . I am sure others will point out that this is also incorrect. As I have suggested in the past, I strongly advise that if people post Ada code, they compile it and make sure it works, and then cut and paste actual working code. This will help avoid spreading misinformation. This is good advice for anyone, no matter how well you think you know Ada. I certainly do it for any code I post, it is too easy to make a silly typo, and end up confusing people if you do not take the trouble to make sure that code you post is correct. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 16:56 ` Mark Lundquist 2001-07-16 18:42 ` Nonsense (was Re: How to do it in Ada ?) Mark Lundquist @ 2001-07-16 22:18 ` Jeffrey Carter 2001-07-17 4:06 ` tmoran 2001-07-20 5:39 ` David Thompson 2 siblings, 1 reply; 13+ messages in thread From: Jeffrey Carter @ 2001-07-16 22:18 UTC (permalink / raw) Mark Lundquist wrote: > > > X := new X_Array_Type'((1 .. N => 0)); > > What about those double parenthesis... do those look funny? Well, they > really are required. This is incorrect. The syntax for a qualified expression is qualified_expression ::= subtype_mark'(expression) | subtype_mark'aggregate so the double parens are not required. > X := new X_Array_Type (1 .. N) := (others => 0); This is also incorrect. -- Jeffrey Carter ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 22:18 ` How to do it in Ada ? Jeffrey Carter @ 2001-07-17 4:06 ` tmoran 0 siblings, 0 replies; 13+ messages in thread From: tmoran @ 2001-07-17 4:06 UTC (permalink / raw) > qualified_expression ::= > subtype_mark'(expression) | subtype_mark'aggregate > > so the double parens are not required. Learn something new every day! :) It's interesting to see the variety of people's answers to the question. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 16:56 ` Mark Lundquist 2001-07-16 18:42 ` Nonsense (was Re: How to do it in Ada ?) Mark Lundquist 2001-07-16 22:18 ` How to do it in Ada ? Jeffrey Carter @ 2001-07-20 5:39 ` David Thompson 2 siblings, 0 replies; 13+ messages in thread From: David Thompson @ 2001-07-20 5:39 UTC (permalink / raw) Mark Lundquist <up.yerz@nospam.com> wrote : ... > Things to note: > > 1) No heap allocation is required. In C, the size in an array > declaration _has_ to be static. So in the original C example, the use of > malloc() is necessitated by the fact that we don't know at compile time how > many elements the array will have. In Ada, you can declare an object with a > non-static constraint. ... The recent revision C99 added, and gcc/GNU-C has long implemented as an extension, "auto" arrays and array types with bounds computed effectively at elaboration (although they don't call it that), somewhat unimaginatively called Variable Length Arrays. (They are still 0-based and not bounds-checked.) > 2) The "(others => 0)" thing is called an aggregate. Aggregates are to > composite types (arrays and records) what literals are to elementary types, > so you can use an aggregate to initialize an object of a composite type. So > for arrays, there is no need to code an iteration across the array elements. For a declared array in C, you can write an initializer which specifies only some, at minimum one, element(s), and all unspecified elements are initialized to 0 (or floating 0.0 or pointer NULL). In C99 you can select arbitrary elements using a Designated Initializer: int foo[10] = { [1] = 3, [7] = 4 }; /* [0,2..6,8,9] = 0 */ but you cannot use ranges (3..5 => 42) or have the "remainder" (others =>) case be anything other than "zero" as above. malloc'ed space is not initialized, except that by using calloc instead you can have it initialized to all-zero-BITS; this is not guaranteed to produce integer 0, floating 0.0, or pointer NULL, with the single exception of the type unsigned char, though on most if not all "normal" systems it does. Also on many popular current OSes all memory not explicitly (statically) loaded is initialized to zero-bits, including not-yet-used stack and heap, but to use this "safely" you must have control over all the code in your process from main down and even then it's easy to get wrong. Also new in C99 you can write a Compound Literal for an array or struct. But arrays still aren't first-class; you can't assign any array value, including such a literal, to an array object/variable, malloc'ed or not. You can memcpy() it, but this is easier to mess up. > Not only does this mean that you're programming at a higher level of > abstraction, it leaves freedom for the compiler to do it more efficiently, > if the compiler knows a better way then elementwise iteration. > Well, even if you write the loop, a good compiler can optimize it to something better. The important gain is source clarity. -- - David.Thompson 1 now at worldnet.att.net ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to do it in Ada ? 2001-07-16 6:51 ` tmoran 2001-07-16 16:56 ` Mark Lundquist @ 2001-07-16 17:37 ` Ken Garlington 1 sibling, 0 replies; 13+ messages in thread From: Ken Garlington @ 2001-07-16 17:37 UTC (permalink / raw) Heck, if I were going to do it the natural Ada way, I'd say: with Ada.Command_Line; with Ada.Text_Io; -- for debug only procedure Main is -- N is the first argument, if it is specified and "reasonable". -- Otherwise, it defaults to the value 1 (one array element). function N return Positive is subtype OK_Range is Positive range 1 .. 65_535; -- 65,535 can be replaced with whatever is "reasonable" -- for an upper limit, or the range eliminated altogether. begin return OK_Range'Value(Ada.Command_Line.Argument(1)); exception when others => return 1; end N; X : array (1 .. N) of Integer := (others => 0); begin Ada.Text_Io.Put_Line("Hey! You've got an array of" & Natural'Image(X'Length) & " element(s)!"); -- do what you gotta do end Main; ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2001-07-20 5:39 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2001-07-16 3:33 How to do it in Ada ? Tomasz Wegrzanowski 2001-07-16 5:31 ` Jeffrey Carter 2001-07-16 6:41 ` Al Christians 2001-07-16 6:51 ` tmoran 2001-07-16 16:56 ` Mark Lundquist 2001-07-16 18:42 ` Nonsense (was Re: How to do it in Ada ?) Mark Lundquist 2001-07-16 22:20 ` Jeffrey Carter 2001-07-17 0:13 ` Ken Garlington 2001-07-17 3:53 ` Robert Dewar 2001-07-16 22:18 ` How to do it in Ada ? Jeffrey Carter 2001-07-17 4:06 ` tmoran 2001-07-20 5:39 ` David Thompson 2001-07-16 17:37 ` Ken Garlington
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox