From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,aeab6b16387b2612 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-07-16 10:01:46 PST Path: archiver1.google.com!newsfeed.google.com!sn-xit-03!supernews.com!cyclone2.usenetserver.com!howland.erols.net!news-out.worldnet.att.net.MISMATCH!wn3feed!worldnet.att.net!24.0.0.38!newshub2.rdc1.sfba.home.com!news.home.com!news1.sttls1.wa.home.com.POSTED!not-for-mail From: "Mark Lundquist" Newsgroups: comp.lang.ada References: <9itna2$i5b$1@news.tpi.pl> Subject: Re: How to do it in Ada ? X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Message-ID: Date: Mon, 16 Jul 2001 16:56:15 GMT NNTP-Posting-Host: 24.248.56.237 X-Complaints-To: abuse@home.net X-Trace: news1.sttls1.wa.home.com 995302575 24.248.56.237 (Mon, 16 Jul 2001 09:56:15 PDT) NNTP-Posting-Date: Mon, 16 Jul 2001 09:56:15 PDT Organization: Excite@Home - The Leader in Broadband http://home.com/faster Xref: archiver1.google.com comp.lang.ada:10001 Date: 2001-07-16T16:56:15+00:00 List-Id: 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