Version 1.1 of ais/ai-00314.txt
!standard C.5 (00) 02-09-30 AI95-00314/00
!class amendment 02-09-30
!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 <underlying_int_type>'Image/Value/Width
for <enum_type>'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.
****************************************************************
Questions? Ask the ACAA Technical Agent