!standard C.5 (00) 02-09-30 AI95-00314/00 !class amendment 02-09-30 !status No Action (8-2-0) 02-10-13 !status received 02-09-16 !priority Low !difficulty Medium !subject Standardize Discard_Names !summary !problem !proposal !discussion !examples !ACATS test !appendix !topic A Proposal: Standardize pragma Discard_Names for Enumeration Types !reference RM95-C.5 !from Michael Yoder 02-09-16 !keywords Discard_Names !discussion This is a proposal for a standard handling of pragma Discard_Names for enumeration types. The effect of Discard_Names, when applied to an enumeration type, shall be that the Wide_Image function for that type returns a string comprised of the uppercase character 'X' followed by some number of uppercase hexadecimal digits. The number of digits is determined by the position N of the enumeration literal, as follows: 0 <= N < 16: 1 digit 16 <= N < 256: 2 digits 256 <= N < 65536: 4 digits otherwise: 8 digits The hexadecimal digits represent the position of the literal in the obvious manner. The effect of Image, Wide_Value, and Value are derivable from the above. It follows from the above that the Wide_Width and Width attributes for a non-null range are equal to the length of the image of the upper bound of the range, and are always equal to 2, 3, 5, or 9. (End of proposal.) The Wide_Image function must use position values, not representation values, because it mustn't change for derived types with different representations. The function doesn't try to homogenize lengths entirely within an enumeration type. This is intentional: it allows extensible enumeration types to be treated without special cases, and maximizes code sharing. An uppercase letter was chosen for the initial character so that the Enumeration_IO generic packages in Text_IO and Wide_Text_IO would need no special cases. A primary goal of the above is to allow the combined code and data for Image, Value, Width, Wide_Image, Wide_Value, and Wide_Width to be small for all such enumeration types together. **************************************************************** !topic A Proposal: Standardize pragma Discard_Names for Tagged Types and Exceptions !reference RM95-C.5 !from Michael Yoder 02-09-16 !keywords Discard_Names !discussion This is a proposal for a standard handling of pragma Discard_Names for tagged types and exceptions. The effect of Discard_Names, when applied to a tagged type, shall be that the function Tags.Expanded_Name returns a value comprised of the uppercase character 'T' followed by some number of hexadecimal digits. The number of digits shall be the minimum number needed to represent all possible values of System.Storage_Elements.Integer_Address. The digits are obtained, for any such tagged type, by applying System.Storage_Elements.To_Integer to the address of the run-time information associated with the tagged type. The digits are determined by representing the integer in hexadecimal in the usual fashion, with any negative values being represented as in a twos-complement representation. The effect of Discard_Names when applied to an exception shall be that the function Exceptions.Exception_Name returns a value comprised of the uppercase character 'E' followed by the same number of hexadecimal digits. The digits are obtained as for a tagged type, except that the address in this case is the run-time information associated with the exception (with the name removed or made to be length 0). If the entire run-time information associated with an exception is normally its name, the name shall instead be replaced with one of length 1 containing the first letter of the exception's name. (end of proposal) These two cases are separated from enumeration types because they have a different feel. The intent is that the two functions not return the same value for distinct types or exceptions that exist concurrently. I realize that some of the above provisos aren't readily testable. Michael Yoder **************************************************************** From: Robert Dewar Sent: Tuesday, September 17, 2002 8:58 PM A proposal like this should be accompanied by an account of what current compilers do. In practice I suspect that this proposal will generate a lot of inconvenient effective incompatibilities among current users with very little gain. **************************************************************** From: Randy Brukardt Sent: Wednesday, September 25, 2002 6:03 PM Re: A Proposal: Standardize pragma Discard_Names Mike, when submitting a proposal, you need to include some justification for the change. There is none whatsoever in your current proposal. This is especially true since the proposal changes the intent of the pragma as expressed in the AARM - it essentially says that C.5(8.b) is wrong, and that only the first of the options listed makes sense. You will need to provide some proof of that. Your proposal asks most, if not all, implementations to change to a "standard" version for the results of the various name functions. This seems to fly in the face of the intent (at least as I see it) of this pragma. The point of this pragma is to allow a programmer to say that they do not depend on the stored name (that is, they don't use External_Name, Exception_Name, or 'Image), and thus the compiler shouldn't generate the space for it. No one should care what happens if the programmer violates their promise. Your proposal eliminates all of the flexibility currently available, which includes eliminating all overhead and raising exceptions, or ignoring the pragma if there is no substantial savings. C.5(8.b) makes it clear that this flexibility was intended. For instance, Janus/Ada effectively ignores the pragma for tagged types and exceptions. That's because there isn't enough possible space savings to justify the work of supporting it. In both cases, the runtime requires a string in that position. Indeed, to support your proposal, we would have to add code to generate the string you are requiring rather than the default one. This might make the code larger, and rarely would have any significant impact on the code size (most programs do not have many tagged type and/or exception declarations). For our customers, there simply isn't a need, especially as the programmer can explicitly set the names of tagged types (if they really want to save space, just set them to "T1", "T2", etc. -- that will save quite a bit more space than the proposal would). Similarly, Janus/Ada usually raises Program_Error if an attempt to use 'Image is made on a type which has Discard_Names applied to it. (This behavior was inherited from our Ada 83 compiler; we did not want 'Image returning the 'wrong' answer in any case). More formally: -- If the expression can be evaluated at compile-time, the correct answer is returned; -- Otherwise, 'Image of a type with Discard_Names applied to it is a bounded error. Either Program_Error is raised, or the position number is returned as an integer literal. (The choice exists so that the code for shared generics doesn't need extra overhead for this case.) In conclusion, this proposal is a bad idea, because it is incompatible with existing practice, because encourages a bad programming practice (depending on Discarded names), and because it changes the clear intent of the standard without justification. **************************************************************** From: Robert A. Duff Sent: Thursday, September 26, 2002 5:49 PM > Re: A Proposal: Standardize pragma Discard_Names > > Mike, when submitting a proposal, you need to include some justification for > the change. I think the ARG *directed* Mike to propose these changes. There was some talk at some previous meetings to nail down the semantics of previously impl-def stuff. >... There is none whatsoever in your current proposal. I agree the proposal should at least parrot back the ARG's intentions, but please don't think that Mike's proposal came out of the blue. **************************************************************** From: Randy Brukardt Sent: Thursday, September 26, 2002 6:38 PM Bob wrote: > > Mike, when submitting a proposal, you need to include some justification > > for the change. > I think the ARG *directed* Mike to propose these changes. > There was some talk at some previous meetings to nail down the semantics > of previously impl-def stuff. Both Bob and Pascal noted that this was in fact part of Mike's "homework". So I should be happy that some homework has been accomplished, but... > >... There is none whatsoever in your current proposal. > I agree the proposal should at least parrot back the ARG's intentions, > but please don't think that Mike's proposal came out of the blue. ...just because the ARG asked for a proposal does not obviate the need to provide a justification. Especially in a case like this where implementations are going to be asked to make incompatible changes with their previous versions. There has to be a strong, tangible benefit to this change beyond simply eliminating some implementation-defined stuff. After all, we presume that the Ada 9x team didn't make things imp-def without good reasons. And we don't want to introduce incompatibilities for no reason. If we really want to get rid of the implementation-defined behavior, then the use of these things needs to be defined as a bounded error. But I really don't see any point in doing that. **************************************************************** From: Robert Dewar Sent: Thursday, September 26, 2002 10:49 PM By the way, we recently added a pragma Keep_Names that can override Discard_Names for specific types. **************************************************************** From: Randy Brukardt Sent: Thursday, September 26, 2002 11:14 PM > By the way, we recently added a pragma Keep_Names that can override > Discard_Names for specific types. Interesting. The original Janus/Ada pragma for this (which dates back at least to 1984; it was in the first set of pragmas we implemented) is Enumtab. Enumtab takes an On or Off parameter, and take effect syntactically. Thus the standard way to use it is something like: package Whatever is pragma Enumtab(Off); ... pragma Enumtab(On); type We_want_names is (Yes, Good, ...); pragma Enumtab(Off); ... end Whatever; I mention this not because we would want to copy this pragma in any way, but rather to show that being able to turn discarding off is a good thing, and we've often taken advantage of it in our compiler (which is written in Ada, of course). The issue is very similar to Suppress, which needs Unsuppress. **************************************************************** From: Robert Dewar Sent: Thursday, September 26, 2002 11:20 PM Here is the documentation for Keep_Names: @findex Keep_Names @item pragma Keep_Names @noindent Syntax: @smallexample pragma Keep_Names ([On =>] enumeration_first_subtype_LOCAL_NAME); @end smallexample @noindent @var{enumeration_type_NAME} must refer to an enumeration first subtype in the current declarative part. The effect is to retain the enumeration literal names for use by @code{Image} and @code{Value} even if a global @code{Discard_Names} pragma applies. This is useful when you want to generally suppress enumeration literal names and for example you therefore use a @code{Discard_Names} pragma in the @file{gnat.adc} file, but you want to retain the names for specific enumeration types. By the way, just for fun, since it is right after Keep_Names in the list. Here is a pragma that I suspect would *not* be considered of general use (but you never know :-) @findex License @item pragma License @cindex License checking @noindent Syntax: @smallexample pragma License (Unrestricted | GPL | Modified_GPL | Restricted); @end smallexample @noindent This pragma is provided to allow automated checking for appropriate license conditions with respect to the standard and modified GPL@. A pragma @code{License}, which is a configuration pragma that typically appears at the start of a source file or in a separate @file{gnat.adc} file, specifies the licensing conditions of a unit as follows: @itemize @bullet @item Unrestricted This is used for a unit that can be freely used with no license restrictions. Examples of such units are public domain units, and units from the Ada Reference Manual. @item GPL This is used for a unit that is licensed under the unmodified GPL, and which therefore cannot be @code{with}'ed by a restricted unit. @item Modified_GPL This is used for a unit licensed under the GNAT modified GPL that includes a special exception paragraph that specifically permits the inclusion of the unit in programs without requiring the entire program to be released under the GPL@. This is the license used for the GNAT run-time which ensures that the run-time can be used freely in any program without GPL concerns. @item Restricted This is used for a unit that is restricted in that it is not permitted to depend on units that are licensed under the GPL@. Typical examples are proprietary code that is to be released under more restrictive license conditions. Note that restricted units are permitted to @code{with} units which are licensed under the modified GPL (this is the whole point of the modified GPL). @end itemize @noindent Normally a unit with no @code{License} pragma is considered to have an unknown license, and no checking is done. However, standard GNAT headers are recognized, and license information is derived from them as follows. @itemize @bullet A GNAT license header starts with a line containing 78 hyphens. The following comment text is searched for the appearence of any of the following strings. If the string ``GNU General Public License'' is found, then the unit is assumed to have GPL license, unless the string ``As a special exception'' follows, in which case the license is assumed to be modified GPL@. If one of the strings ``This specification is adapated from the Ada Semantic Interface'' or ``This specification is derived from the Ada Reference Manual'' is found then the unit is assumed to be unrestricted. @end itemize @noindent These default actions means that a program with a restricted license pragma will automatically get warnings if a GPL unit is inappropriately @code{with}'ed. For example, the program: @smallexample with Sem_Ch3; with GNAT.Sockets; procedure Secret_Stuff is @dots{} end Secret_Stuff @end smallexample @noindent if compiled with pragma @code{License} (@code{Restricted}) in a @file{gnat.adc} file will generate the warning: @smallexample 1. with Sem_Ch3; | >>> license of withed unit "Sem_Ch3" is incompatible 2. with GNAT.Sockets; 3. procedure Secret_Stuff is @end smallexample @noindent Here we get a warning on @code{Sem_Ch3} since it is part of the GNAT compiler and is licensed under the GPL, but no warning for @code{GNAT.Sockets} which is part of the GNAT run time, and is therefore licensed under the modified GPL@. **************************************************************** From: Tucker Taft Sent: Friday, September 27, 2002 4:41 PM For what it's worth, for compilers based on the AdaMagic front end, the result of discard names on an enumeration type is to subsititute 'Image/Value/Width for 'Image/Value/Width. This is very simple to define and implement, and would be my recommendation (for obvious reasons ;-). **************************************************************** From: Tucker Taft Sent: Friday, September 27, 2002 4:45 PM We use the first letter of the exception identifier as the Exception_Name when discard_names applies. We currently don't shorten the Expanded_Name or External_Tag in the presence of discard_names. **************************************************************** From: Robert Dewar Sent: Friday, September 27, 2002 7:31 PM We give the image of the Pos value which seems much cleaner, I don't like the semantics of Image being affected by rep clauses. ****************************************************************