!standard 07.06(09) 05-03-17 AI95-00360/07 !standard D.07(04) !standard A.4.5(72) !standard A.5.2(15) !standard A.5.2(27) !standard A.8.1(16) !standard A.8.4(19) !standard A.10.1(85) !standard A.12.1(27) !class binding interpretation 03-10-08 !status Amendment 200Y 04-03-24 !status WG9 Approved 04-06-18 !status ARG Approved 8-0-0 04-03-07 !status work item 03-10-08 !status received 03-10-08 !priority Medium !difficulty Easy !subject Types that need finalization !summary Some types are defined to *need finalization*. The restriction No_Nested_Finalization is defined in terms of types that need finalization. A number of language-defined types are defined to need finalization. !question The restriction No_Nested_Finalization is expressed in terms of controlled types. However, there are a number of language-defined types which, while not visibly controlled, might well be implemented using controlled types by some implementations. Are such types affected by No_Nested_Finalization? (Yes, see list in the wording section.) Furthermore, the definition of No_Nested_Finalization doesn't take into account access discriminants, which can cause nested finalization to happen. Is this intended? (No.) !recommendation (See summary.) !wording Insert after 7.6(9): A type is said to *need finalization* if: o it is a controlled type, a task type or a protected type; or o it has a component that needs finalization; or o it is a limited type that has an access discriminant whose designated type needs finalization; or o it is one of a number of language-defined types that are explicitly defined to need finalization. AARM Note The fact that a type needs finalization does not require it to be implemented with a controlled type. It just has to be recognized by the No_Nested_Finalization restriction. Insert after A.4.5(72): The type Unbounded_String needs finalization (see 7.6). Insert after A.5.2(15): The type Generator needs finalization (see 7.6). Insert after A.5.2(27): The type Generator needs finalization (see 7.6) in every instantiation of Numerics.Discrete_Random. Insert after A.8.1(16): The type File_Type needs finalization (see 7.6) in every instantiation of Sequential_IO. Insert after A.8.4(19): The type File_Type needs finalization (see 7.6) in every instantiation of Direct_IO. Insert after A.10.1(85): The type File_Type needs finalization (see 7.6). Insert after A.12.1(27): The type File_Type needs finalization (see 7.6). Replace D.7(4/1) by: No_Nested_Finalization Objects of a type that needs finalization (see 7.6) and access types that designate a type that needs finalization shall be declared only at library level. Add in the Static Semantics of D.15 (AI-297): The type Timing_Event needs finalization (see 7.6). Add in the Static Semantics of D.14 (AI-307): The type Timer needs finalization (see 7.6). Add in the Static Semantics of AI-354: The type Group_Budget needs finalization (see 7.6). !discussion Note that the current wording of D.7(4) doesn't take into account the case of access discriminants designating controlled objects. For example: with Ada.Finalization.Controlled; package P is type T1 is new Ada.Finalization.Controlled with null record; type T2 (D : access T1) is limited null record; end P; with P; procedure Q is pragma Restrictions (No_Nested_Finalization); X : P.T2 (D => new P.T1); -- Legal? (No.) begin null; end Q; In this example the finalization of X causes the finalization of X.D, which is effectively a nested finalization. However, this case is not forbidden by the existing wording of D.7(4). !corrigendum 7.6(09) @dinsa A controlled type is a descendant of Controlled or Limited_Controlled. The (default) implementations of Initialize, Adjust, and Finalize have no effect. The predefined "=" operator of type Controlled always returns True, since this operator is incorporated into the implementation of the predefined equality operator of types derived from Controlled, as explained in 4.5.2. The type Limited_Controlled is like Controlled, except that it is limited and it lacks the primitive subprogram Adjust. @dinss A type is said to @i if: @xbullet @xbullet @xbullet @xbullet !corrigendum A.4.5(72) @dinsa @xcode<@b ... -- @ft<@i> @b Ada.Strings.Unbounded;> @dinst The type Unbounded_String needs finalization (see 7.6). !corrigendum A.5.2(15) @dinsa @xcode<@b ... -- @ft<@i> @b Ada.Numerics.Float_Random;> @dinst The type Generator needs finalization (see 7.6). !corrigendum A.5.2(27) @dinsa @xcode<@b ... -- @ft<@i> @b Ada.Numerics.Discrete_Random;> @dinst The type Generator needs finalization (see 7.6) in every instantiation of Numerics.Discrete_Random. !corrigendum A.8.1(16) @dinsa @xcode<@b ... -- @ft<@i> @b Ada.Sequential_IO;> @dinst The type File_Type needs finalization (see 7.6) in every instantiation of Sequential_IO. !corrigendum A.8.4(19) @dinsa @xcode<@b ... -- @ft<@i> @b Ada.Direct_IO;> @dinst The type File_Type needs finalization (see 7.6) in every instantiation of Direct_IO. !corrigendum A.10.1(85) @dinsa @xcode< Status_Error : @b IO_Exceptions.Status_Error; Mode_Error : @b IO_Exceptions.Mode_Error; Name_Error : @b IO_Exceptions.Name_Error; Use_Error : @b IO_Exceptions.Use_Error; Device_Error : @b IO_Exceptions.Device_Error; End_Error : @b IO_Exceptions.End_Error; Data_Error : @b IO_Exceptions.Data_Error; Layout_Error : @b IO_Exceptions.Layout_Error; @b ... -- @ft<@i> @b Ada.Text_IO;> @dinst The type File_Type needs finalization (see 7.6). !corrigendum A.12.1(27) @dinsa @xcode<@b ... -- @ft<@i> @b Ada.Streams.Stream_IO;> @dinst The type File_Type needs finalization (see 7.6). !corrigendum D.7(4) @drepl @xhang<@xterm Objects with controlled, protected, or task parts and access types that designate such objects, shall be declared only at library level.> @dby @xhang<@xterm Objects of a type that needs finalization (see 7.6) and access types that designate a type that needs finalization shall be declared only at library level.> !example !ACATS test !appendix From: Tucker Taft Sent: Wednesday, October 8, 2003 10:26 AM "Quasi-controlled" makes me feel queasy. How about just define the term "needs finalization"? I think that will be easier to stomach ;-). **************************************************************** From: Pascal Leroy Sent: Wednesday, October 8, 2003 2:49 PM > "Quasi-controlled" makes me feel queasy. I knew you wouldn't like it ;-) > How about just define the term "needs finalization"? I think that > will be easier to stomach ;-). Well, it's not exactly "needs finalization", because protected types and tasks need some kind of finalization, and they are not covered by restriction No_Nested_Finalization. What this restriction covers is really "controlled types and their buddies". Therefore I believe that the new term has to say "controlled" somewhere. However, I would welcome a better name... **************************************************************** From: Tucker Taft Sent: Wednesday, October 8, 2003 3:52 PM No, there you are wrong. No_Nested_Finalization *does* cover Task and Protected types. We made that change a while ago. So I think "needs finalization" is just about right. **************************************************************** From: Jean-Pierre Rosen Sent: Thursday, October 9, 2003 1:58 AM What about "potentially controlled" ? Reminds of "potentially blocking", and I think it grasps the idea, at least for things like Unbounded_String. The standard does not *require* Unbounded_String to be controlled, but we know damn well that they might be... **************************************************************** From: Tucker Taft Sent: Thursday, October 9, 2003 10:24 AM As I pointed out, in Ada 2000, No_Nested_Finalization includes no nested tasks and protected types as well. It sounds like you folks are using outdated manuals. For shame! **************************************************************** From: Pascal Leroy Sent: Friday, October 10, 2003 3:44 AM Yes, sorry, I was reading the original, obsolete RM, not the new fancy one updated by TC1. **************************************************************** From: Christoph Grein Sent: Friday, September 16, 2005 10:26 AM I do not understand the following sentences occurring at many places: XXX is defined to need finalization. If the restriction No_Nested_Finalization (see D.7) applies to the partition, and XXX does not have a controlled part, it will not be allowed in local objects in Ada 2005 whereas it would be allowed in Ada 95. Such code is not portable, as another Ada compiler may have a controlled part in XXX, and thus would be illegal. Shouldn't it be: If the restriction No_Nested_Finalization (see D.7) applies to the partition, and XXX has a controlled part, ... **************************************************************** From: Randy Brukardt Sent: Friday, September 16, 2005 6:34 PM No. As the comment says, that would make the application of the pragma (and thus the legality of the program) dependent on the precise implementation of the type. We don't want that, so we've introduced the concept of "needs finalization" and applied it to various language-defined types. (Perhaps there should also be a pragma to declare that for user-defined types, but that's another issue.) A type that "needs finalization" is one that *might* reasonably be implemented with a controlled part (thus type Integer doesn't need finalization). In general, we don't want the legality of programs to depend on what's in private parts, and that applies to restrictions as much as anything else. (It's not practical to do that for all restrictions, but it does make sense to insure that the language-defined types operate the same way for every implementation.) To take a specific example, the type Text_IO.File_Type is defined to "need finalization". Thus, the pragma No_Nested_Finalization applies to local objects of that type, whether or not the type actually uses a controlled part. For instance, Janus/Ada's implementation of File_Type (derived from our Ada 83 implementation) doesn't use a controlled part (although it logically does the same sort of things). Thus, in Ada 95, you could declare a local object of Text_IO.File_Type even when the No_Nested_Finalization restriction is enforce. But it's perfectly reasonable for some other implementation to use a controlled type for this implementation, in which case the program would be illegal. We want programs using the language-defined types to remain portable, and thus we want a common treatment. See AI-360 (as indexed from every one of the paragraphs you referenced) for a longer discussion of this issue. ****************************************************************