!standard 11.5(1-8) 99-12-13 AI95-00224/02 !standard 11.5(27) !class amendment 99-11-19 !status work item 99-11-19 !status received 99-11-19 !priority Medium !difficulty Medium !subject pragma Unsuppress !summary A pragma is introduced to require checking in a declarative region, irrespective of the use of pragma Suppress. !problem Ada code sometimes depends on the canonical checking semantics of the language. Consider, for instance, an integer saturation arithmetic package. The multiply operation might look like: function "*" (Left, Right : Saturation_Type) return Saturation_Type is begin return Integer(Left) * Integer(Right); exception when Constraint_Error => return Saturation_Type'Last; end "*"; This function will not work properly without overflow checking. Ada 95 does not provide a way to indicate this to the compiler and programmers. !proposal A new pragma Unsuppress is defined. pragma Unsuppress (identifier [, [On =>] name]); The arguments of Unsuppress are the same as Suppress. Unsuppress can be used in the same places as Suppress, with the same scoping rules. Pragma Unsuppress revokes the permission to suppress a check, that is, it means that the given check must be performed. !wording Define "Checking pragmas" and add pragma Suppress to 11.5(1) ("Checking pragmas" is in italics): Checking pragmas give an implementation instructions on handling language-defined checks. A pragma Suppress gives permission to an implementation to omit certain language-defined checks, while a pragma Unsuppress revokes the permission to make omit checks. Add pragma Unsuppress to 11.5(3-4): The forms of checking pragmas are as follows: pragma Suppress(identifier [, [On =>] name]); pragma Unsuppress(identifier [, [On =>] name]); Change 11.5(5) to apply to checking pragmas: A checking pragma is allowed only immediately within a declarative_part, immediately within a package_specification, or as a configuration pragma. Change 11.5(7) to apply to checking pragmas: For a checking pragma that is immediately within a package_specification and includes a name, the name shall denote an entity (or several overloaded subprograms) declared immediately within the package_specification. Change 11.5(8) to define the meaning of pragma UnSuppress: A checking pragma applies to the named check from the place of the pragma to the end of the innermost enclosing declarative region, or, if the pragma is given in a package_specification and includes a name, to the end of the scope of the named entity. If the pragma includes a name, the pragma applies only to the named entity, or, for a subtype, on objects and values of its type. Otherwise, the pragma applies to all entities. A pragma Suppress gives permission to an implementation to omit the named check for any entities to which it applies. A pragma Unsuppress revokes the permission to omit the named check for any entities to which it applies. If there is no such permission at the point of a pragma Unsuppress, then the pragma has no effect. If permission has been given to suppress a given check, the check is said to be suppressed. Change 11.5(27) to apply to checking pragmas: An implementation is allowed to place restrictions on checking pragmas, subject only to the requirement that pragma Unsuppress shall allow any arguments supported by pragma Suppress. An implementation is allowed to add additional check names, with implementation-defined semantics. When Overflow_Check has been suppressed, an implementation may also suppress an unspecified subset of the Range_Checks. Add after 11.5(27): If more than one checking pragma which apply to the same check are given as configuration pragmas in different compilations, it is implementation-defined whether the check is suppressed. Add an additional note after 11.5(29): It is possible to give both a pragma Suppress and Unsuppress for the same check in the same declarative region. In that case, the last pragma given determines whether or not the check is suppressed. Similarly, it is possible to resuppress a check which has been unsuppressed by giving a pragma Suppress in an inner declarative region. !example We can use pragma Unsuppress to insure that checking occurs in the saturation multiply function given earlier: function "*" (Left, Right : Saturation_Type) return Saturation_Type is pragma Unsuppress (Overflow_Check); begin return Integer(Left) * Integer(Right); exception when Constraint_Error => return Saturation_Type'Last; end "*"; If there is a pragma Suppress for Overflow_Check effective in "*", the Unsuppress will revoke the permission to omit the checks, thus requiring the checks to be made. If there is no pragma Suppress, then the pragma Unsuppress is ignored. !discussion Ada 95 provides an easy way to suppress checking over large areas of program text. Pragma Suppress can be used in a package specification to apply to an entire package, or even as a configuration pragma to apply to the entire program. It is common for production versions of applications to be delivered with checking suppressed (perhaps for better performance or smaller code size). If pragma Suppress is applied to an entire package or program, code that requires checking will start to fail. Ada code that depends on the canonical checking semantics is not common, but it occurs frequently enough that most Ada programmers have been bitten by this problem at one time or another. The problem is made worse by the fact that Ada 95 does not provide any way to turn off pragma Suppress over a smaller, inner region of the program. Therefore, fixing the problem requires moving the pragma Suppresses to individual packages and/or subprograms, which is clearly error-prone. The pragma proposed here can be used both as a preventative measure (to insure that the code continues to work if a later programmer applies Suppress to the unit) and as a repair when checks are suppressed where they are required. Note that the pragma Suppress that causes problems may not be explicit; many compilers include an option switch that effectively adds pragma Suppress to the start of each compilation unit. The presence of pragma Unsuppress has no effect on compiler optimization of checks. A compiler is still allowed to remove checks that it can prove will not fail. This is why the wording is expressed in terms of "revoking the permission to omit" rather than "requiring" checks. This proposal allows nested suppression of checks. That is, checks can be "resuppressed" inside of a region where checks are "unsuppressed" (required). This is necessary to prevent problems with code where the correctness depends on suppression of checks. (While such code is technically erroneous, in actual practice such does exist. We do not want to break it by being pedantic.) Such code would include a pragma Suppress. If checks could not be resuppressed, this code would fail if it was nested inside of a construct that contains an Unsuppress pragma, or if a Unsuppress configuration pragma was used. This would essentially be the current problem all over again, so the model where Unsuppress has precedence over Suppress was rejected. Both pragmas Suppress and Unsuppress can be used as configuration pragmas. While it may it may seems that Unsuppress would be useless as a configuration pragma, it can be useful in conjunction with a Suppress pragma. For instance, the following pragmas would suppress all checks except storage checks in the entire program: pragma Suppress (All_Checks); pragma Unsuppress (Storage_Check); The exact meaning of a checking pragma when there is more than one in a particular declarative region depends on the order that it is given in. For example, reversing the order of the pragmas in the above example would simply suppress all checks. This poses a problem for configuration pragmas, though, as the order of configuration pragmas depends on the compilation model of the implementation. Of course, pragmas given in a single compilation have a well-defined order, so this gives us a solution which both allows the portable use of the pragmas without adding implementation burden. That is, we say that the meaning of conflicting checking pragmas given as configuration pragmas is implementation-defined unless the pragmas are given in the same compilation. Restrictions can be placed on pragma Unsuppress. This is necessary to avoid burdening implementations. For instance, some implementations cannot support fine-grained suppression of single objects, and we don't want to start requiring that. We do require that anything supported for Suppress is also supported for Unsuppress, because it is important to be able to unsuppress checks suppressed over a larger area. Note that the reverse is not true; implementations can support more of Unsuppress than of Suppress if they desire. Implementations should not produce warnings for usages of pragma Unsuppress which have no effect. (This is varies from common practice for other pragmas.) It is not an error to use a pragma Unsuppress where nothing is suppressed. Such a usage may very well be a "preventative" pragma, inserted to insure that checks are made in a unit that requires checks. Alternative names (in particular "Require") were considered for this pragma. The name Unsuppress has two problems: First, it is a dubious English word; Ada pragmas are usually English words or phrases. Secondly, the preventative use of this pragma is very important, but "Unsuppress" appears to denote something that can only be used when checks actually are suppressed. This would likely lead to the under-use of the pragma as a preventative. Irregardless, we use "Unsuppress" as the name of the pragma. There were two main factors for this. First, Unsuppress implies a relationship with Suppress, which other names cannot do. Second, Unsuppress is in current use as an extension in several compilers, and standardizing existing practice is usually better than inventing new ideas. !appendix ************************************************************* From: Randy Brukardt Sent: Friday, November 19, 1999 7:34 PM I've created this AI based on the discussion at the last ARG meeting. I made one major change: based on the problem statement, the name "Unsuppress" is the wrong name. In its intended use, we do not necessarily know that a pragma Suppress has been applied to a region. Therefore, I renamed the pragma to the more meaningful name "Require". I expect to catch some flak for this. I find the preventative use of Require quite important, and quite in keeping with the philosophy of Ada (make sure problems don't happen in the first place). It seems wrong to use a hypothetical pragma Unsuppress as a preventative: it isn't undoing anything! Indeed, Ada users could imagine that it isn't allowed unless there is a Suppress pragma to undo, and in that case, they would not use it as a preventative. I wonder if this entire clause shouldn't be renamed; it now is more about controlling checks than about suppressing them. One interesting issue: should pragma Require be allowed as a configuration pragma? I have left it in, as that would allow effectively preventing the adding of any pragma Suppresses to a program. That might be useful to some paranoid organization. It also takes more words to disallow it than to allow it. Another interesting issue: should we allow "resuppression" of checks? I don't feel strongly either way, but selected the current write-up because it was more natural for pragma Require. The only way I see to support "resuppression" is to write paragraph 8 in terms of "revoking the permission" to suppress checks, which would complicate the description and would fit a pragma named Unsuppress much better. It would also mean that a pragma Require would be meaningless as a configuration pragma, as it would have no effect. Having the pragma have no effect in some circumstances might be a impediment to using it as a preventive, as a naive implementation of Ada might spew out a warning everytime such a pragma occurs. I don't think we can say "don't warn about this" in the reference manual, but without some guidance in this area, I can see implementors going through the RM and implementing each pragma in the "obvious" way [Janus/Ada, for instance, warns on any pragma that has no effect], which would be the wrong thing to do in this case. Randy. ************************************************************* From: Robert Dewar Sent: Monday, November 22, 1999 1:58 PM This is as far as I can tell exactly the same semantics as pragma Unsuppress in GNAT, and indeed these are the obvious semantics, since they derive directly from Suppress. I see no point whatsoever in changing the name a) People are used to pragma Unsuppress and are using it now b) the name is FAR more obvious, Require?? Require what? Sure you could make the same question for Suppress, but we know suppress already. I would strongly oppose changing the name, and most certainly we will not implement it under the name Require in GNAT, because this would be unnecessary duplication. ************************************************************* From: Randy Brukardt Sent: Monday, November 22, 1999 7:16 PM > This is as far as I can tell exactly the same semantics as pragma > Unsuppress in GNAT, and indeed these are the obvious semantics, > since they derive directly from Suppress. No, not exactly. The GNAT documentation that Ed handed out says "If there is no corresponding pragma Suppress in effect, it [Unsuppress] has no effect." The natural (to me) wording changes ended up with slightly different semantics, that is that Suppress has no effect in a region where Require is given. The difference is that Require can be given first -- it essentially is which is given precedence. > I see no point whatsoever in changing the name > > a) People are used to pragma Unsuppress and are using it now > > b) the name is FAR more obvious, Require?? Require what? Sure you could > make the same question for Suppress, but we know suppress already. Require the argument, just like Suppress is "Suppress the argument". I.e. pragma Require (Overflow_Check); > I would strongly oppose changing the name. OK, fair enough. In that case, I think that the answers to the two questions I posed (does the pragma have an effect if no Suppress has been given, and should "resuppression" be supported) should be different. And the pragma then has no use as a preventative measure (both because it makes no sense to "Unsuppress" if nothing is "Suppress"ed, and because a normally correct implementation of Ada 95 will complain about such pragmas). > and most certainly we will not implement it under the name Require in GNAT, > because this would be unnecessary duplication. Well, this sounds very much like a Jean Ishbiah temper-tantrum: "If I can't have my way, I'm going to take my ball and go home." I don't think this attitude is a way to get useful work done (or to sway technical differences of opinion, either). In any case, GNAT /= Ada. We want new features in Ada to be as useful as possible to all users of Ada, not just to the customers of one particular compiler. Randy. ************************************************************* From: Robert Dewar Sent: Monday, November 22, 1999 9:40 PM <> I think this is a bad choice, I prefer everything to nest, so that you can nest Suppress/Unsuppress to any depth, and the innermost one is what has the effect. This is the way GNAT works. ************************************************************* From: Robert Dewar Sent: Monday, November 22, 1999 9:41 PM incidentally, although I would argue for the more natural semantics that Suppress can undo Unsuppress and vice versa to any depth, I don't really care. It is obviously more work to implement Randy's suggested semantics, but in practice it is completely unimportant, the probability of ever having more than one level of these pragmas is zero in any case. ************************************************************* From: Randy Brukardt Sent: Monday, November 22, 1999 10:12 PM I agree that it doesn't matter much (the AI says as much). I'm surprised that you say it would "obviously" take more work. I can see it taking the same amount of work, but I don't see how it could take more. Indeed, I would think it could take less work, because a stack isn't necessary to handle it. If others think it would take more work in their compilers, I'll junk the whole AI and start over (the wording and discussion would have to be totally rewritten to use a stacking semantics). Randy. ************************************************************* From: John Barnes Sent: Tuesday, November 23, 1999 4:37 AM I don't like the word Require either. It's a perfectly good word that might be useful elsewhere whereas Unsuppress is a nasty word that is most unlikely to be confused with anything else. I would like to feel that the words have some symmetry. John ************************************************************* From: Stephen Michell Sent: Tuesday, November 23, 1999 7:19 AM John Barnes wrote: > I don't like the word Require either. It's a perfectly good word that > might be useful elsewhere whereas Unsuppress is a nasty word that is > most unlikely to be confused with anything else. > An excellent point. Then Ada could be the language with the nastiest keywords in town. No one would DARE critisize us then (at least - not to our faces). > I would like to feel that the words have some symmetry. > It does seem clear that "unsuppress" is now in current usage and in the lexicon of the community, so that is the way it must remain. It is also clear to me that one can never permanently override the effects of the other, once it has been selected. It may be reasonable, however, to create a pragma "require" that is a configuration pragma. Such a pragma couldn't override pragma suppress in code, it would just fail the compile. That could be a useful way of ensuring that there are no checks suppressed in your 5 million line program. ...stephen ************************************************************* From: Robert Dewar Sent: Tuesday, November 23, 1999 8:28 AM Obviously the non-nesting semantics would take more work in GNAT, since it is already done using stacking semantics. That was what I meant. We implemented the stacking semantics because it seems clearly preferable. ************************************************************* From: Robert Dewar Sent: Tuesday, November 23, 1999 8:27 AM I find a stacking semantics far more natural here, and in fact the more I think about it, the more I think your non-stacking semantics is fundamentally flawed. If I write a little section of code which depends on correctness on the fact that checks are suppressed, say for performance reasons in the context of a particular compiler, it should not be possible to destroy the correctness of this code by nesting it within a construct that contains an Unsuppress and knows nothing about the code nested within it. ************************************************************* From: Robert Dewar Sent: Tuesday, November 23, 1999 8:38 AM One more point on stacking semantics It seems clear to me that Suppress and Unsuppress should be symmetrical in their semantics. Anything else would be a surprise. Given that it seems clear that a higher level Suppress cannot mask a lower level Unsuppress, indeed in some sense that's the whole point of Unsuppress (to undo a higher level Suppress). So it would indeed seem odd if a Suppress cannot undo the effect of a higher level Unsuppress. I think part of the problem here is that Randy may have been trying to solve a problem that Unsuppress is definitely NOT intended to address, and one which to me is a non-problem, namely trying to ensure that checks are not suppressed anywhere in your program. Why do I think that is a non-problem? Simply because I have never run into a customer requirement or an internal requirement for such a feature. Unsuppress was put there solely for local control in situations which need local control. Thus the stacking semantics seems much more natural to me. ************************************************************* From: Robert Dewar Sent: Tuesday, November 23, 1999 8:18 AM <> This seems overkill to me, I am really not aware of any requirements here. After all Ada is full of deliberate loopholes to get around "checks", most notably unchecked conversion and address clauses, why get all upset about some local use of Suppress? ************************************************************* From: Stephen Michell Sent: Tuesday, November 23, 1999 11:33 AM Sure, and the first thing that real projects do is write coding standards that break peoples' fingers if they dare use one of those. Just ask me - I came back Sunday from a week in the UK where those were some of the project's major topics, and some people walked away with bandaged fingers :). Incidently, this project does extremely heavy numeric calculations, numerical integrations of transcendental functions, we do not suppress any checks, and performance is not an issue. The point is that Ada's loopholes are a real problem for real projects. We have to do a lot of work to make sure that they are not used. Sure one can build external tools to check for such things, but then one could code on C and rely on external tools - right? Our community believes that the compilation environment is the best line of defence for these issue, so let's seriously consider ones that provide a real benefit. A thought - The Annex H "pragma Restrictions" is helpful for many of the significant issues, such as No_Allocation, No_Unchecked_Conversion, but "no_pragma_suppress" is not one of the restrictions. Maybe that is the solution. ************************************************************* From: Randy Brukardt Sent: Tuesday, November 23, 1999 2:02 PM > I find a stacking semantics far more natural here, and in fact the > more I think about it, the more I think your non-stacking semantics > is fundamentally flawed. > > If I write a little section of code which depends on correctness on > the fact that checks are suppressed, say for performance reasons in > the context of a particular compiler, it should not be possible to > destroy the correctness of this code by nesting it within a construct > that contains an Unsuppress and knows nothing about the code nested > within it. I find this a pretty compelling argument in practice (even though a "correct" program can't depend on Suppress). I couldn't think of a case where it would matter when I wrote the AI. I've thought about it some more, and while the "stacking" semantics is easy to describe informally, a formal description seems difficult. I don't think that any of the existing Ada pragmas work this way (can anyone think of a counter-example)? Any suggestions of how to word this? All I can think of is "revoking the permission to suppress checks", but that is a double negative. I'll rewrite the AI and repost it sometime after Thanksgiving. Randy. ************************************************************* From: Randy Brukardt Sent: Tuesday, November 23, 1999 2:45 PM > I think part of the problem here is that Randy may have been trying to solve > a problem that Unsuppress is definitely NOT intended to address, and one > which to me is a non-problem, namely trying to ensure that checks are not > suppressed anywhere in your program. Well, actually, I was trying to provide a way to insure (typically in a local section of code) that checking *is* done. That's because the person who writes the code is lot more likely to know the requirements of the code. That has to work no matter what configuration pragmas, compiler options, or whatever happen. "Unsuppress" seems to be the wrong name for this purpose, because it does not necessarily have anything to do with a Suppress. (I can live with it though). The non-stacking part came from two issues: the difficulty of writing wording to explain stacking formally, and to give meaning to the pragma when given as a configuration pragma. (Remember that Suppress can be a configuration pragma). The GNAT Unsuppress appears to be always ignored when given as a configuration pragma. I'm not very excited about requiring compilers to implement a pragma that will always be ignored. An interesting question: if both a Suppress and Unsuppress are given in the same scope, what happens? Does the order matter. For instance, procedure ... pragma Suppress (All_Checks); pragma Unsuppress (Storage_Check); Does this Suppress all checks except Storage_Check? procedure ... pragma Unsuppress (Storage_Check); pragma Suppress (All_Checks); Does this Suppress all checks including Storage_Check? The problem is that configuration pragmas really don't have an order, so we can't tell which came first. If the meaning depends in the order that they're seen in, then using both Suppress and Unsuppress as configuration pragmas is implementation-dependent. Ugh. Randy. ************************************************************* From: Jean-Pierre Rosen Sent: Wednesday, November 24, 1999 1:44 AM > I've thought about it some more, and while the "stacking" semantics is easy > to describe informally, a formal description seems difficult. I don't think > that any of the existing Ada pragmas work this way (can anyone think of a > counter-example)? Any suggestions of how to word this? All I can think of is > "revoking the permission to suppress checks", but that is a double negative. > What's the problem ? The pragma applies to the declarative region where it appears. In the case of nesting, the innermost wins. Just state that you cannot have a suppress and an unsuppress in the same declarative region for the same check (on the same object). This is the natural Ada semantics. ************************************************************* From: Robert I. Eachus Sent: Friday, November 26, 1999 4:24 PM I personally would find a non-stacking version of Unsuppress to be a problem, even if it is never used in a stacking situation. This is for code verification reasons. With the GNAT version, you just have to look at the closest nested pragma, and if it matters to the logic of the code, the author will located it as close as possible to the affected code to make verification easy. Also, in the case of generics and in-line code, the fact that the code depended on exceptions would need to be made visible to the user. Robert I. Eachus ************************************************************* From: Robert Dewar Sent: Monday, November 29, 1999 5:09 AM <> We don't have any such restriction in GNAT, and a) I see no reason for such a restriction, the semantics is natural, a suppress cancels a previous unsuppress and vice versa. b) This is used in practice sometimes to just unsuppress checks for an individual statement or suppress them for an individual statement. Yes you could declare a block for this, but why require this. It would require extra mechanism to enforce such a restriction, since it would mean that you not only have to have a flag indicating the restriction, but also another flag indicating whether it was explicitly set in the current scope. ************************************************************* From: Randy Brukardt Sent: Monday, November 29, 1999 9:55 AM >Jean-Pierre says: > What's the problem ? The pragma applies to the declarative region where it > appears. How do you describe what Unsuppress does??? In this semantics, it doesn't do anything by itself. It can only be described in terms of some (outer?) Suppress; which leads to the double negative wording. > In the case of nesting, the innermost wins. > Just state that you cannot have a suppress and an unsuppress in the same > declarative region for the same check (on the same object). Given that the language-defined checks include some that overlap (the obvious one is All_Checks and everything else), this could be quite difficult to do. > This is the natural Ada semantics. Yes, if you make that restriction. But the restriction isn't natural, and it isn't easy to describe. --- >Robert Dewar says: >We don't have any such restriction in GNAT, and >a) I see no reason for such a restriction, the semantics is natural, a >suppress cancels a previous unsuppress and vice versa. I agree, except that the "order" of the pragmas is not well-defined when they are used as configuration pragmas. We could prevent the use of Unsuppress as a configuration pragma, but this seems like an unnatural restriction. >b) This is used in practice sometimes to just unsuppress checks for an >individual statement or suppress them for an individual statement. Yes >you could declare a block for this, but why require this. Something is wrong with this. By 11.5(5), Suppress (and presumably Unsuppress) is only allowed in a declarative_part, package specification, or as a configuration pragma. That makes it impossible to use "around a statement" without an enclosing block. >It would require extra mechanism to enforce such a restriction, since >it would mean that you not only have to have a flag indicating the >restriction, but also another flag indicating whether it was explicitly >set in the current scope. Right. Plus you would have to deal with overlapping checks like All_Checks. But without the restriction, it takes a lot more words to describe what happens. This appears to be a case of "we know what we want, but we don't know how to describe it". Randy. ************************************************************* From: Tucker Taft Sent: Monday, November 29, 1999 10:48 AM Randy mentioned some concern about Unsuppress used as a configuration pragma, as it seemed useless with the "stacking" interpretation. However, if we consider a command-line parameter as the "outermost" level, then a library-wide configuration pragma, then a compilation-wide configuration pragma, then a scope-specific pragma, it seems like configuration pragmas would fit into the "stacking" hierarchy in a reasonable way. For example, if you gave a "suppress-all" on the command line, but had an Unsuppress for tag check in a library-wide configuration pragma, that would seem meaningful and perhaps useful. ************************************************************* From: Robert Dewar Sent: Monday, November 29, 1999 9:12 PM I definitely agree, we have seen this standard and useful application of Unsuppress used, and use it ourselves sometimes. ************************************************************* From: Randy Brukardt Sent: Monday, November 29, 1999 1:31 PM Tucker says: > For example, if you gave a "suppress-all" on the command line, but > had an Unsuppress for tag check in a library-wide > configuration pragma, that would seem meaningful and perhaps useful. Yes, but the problem is that it has been suggested that the order that Suppress and Unsuppress pragmas is significant. That is, pragma Suppress (All_Checks); pragma UnSuppress (Overflow_Check); (which suppresses all but Overflow_Check) means something different than pragma UnSuppress (Overflow_Check); pragma Suppress (All_Checks); (which suppresses all checks), the UnSuppress being ignored. The problem is that configuration pragmas are not given in a clearly defined order. Since they can be compiled separately, and compilation order is not an Ada 95 concept, the pragmas could occur in either order or simultaneously. Similarly, we cannot say that compiler options occur before or after "real" configuration pragmas. So how do we determine which of these are meant? This means that the definition of configuration pragmas cannot depend on the order of appearance. Yet, I've been told to write wording for UnSuppress which *does* depend on the order that the pragmas appear. So, we have a problem. If we get rid of the significance of the order (at least within a single scope), we get rid of the problem, but that the cost of complicating things (and I suspect that Robert won't go along with any such semantics). [That is, in a scope, UnSuppress has precedence over Suppress.] We could also prevent multiple pragmas in the same scope, but that is a problem because of overlapping sets of checks. Or we could simply eliminate UnSuppress as a configuration pragma, which would prevent the problem from occurring. None of these look like particularly good choices. Randy. ************************************************************* From: Robert A Duff Sent: Monday, November 29, 1999 4:03 PM > The problem is that configuration pragmas are not given in a clearly defined > order. Have you considered making it implementation defined in that case? - Bob ************************************************************* From: Robert Dewar Sent: Monday, November 29, 1999 9:45 PM <> Sounds reasonable to me, it depends on which is processed last, which is indeed impl defined. ************************************************************* From: Randy Brukardt Sent: Monday, November 29, 1999 6:48 PM Not seriously. That seems like a last resort: punt! Such a definition would not be useful to people who need portable code, and of course would be untestable. ************************************************************* From: Robert Dewar Sent: Monday, November 29, 1999 10:16 PM Don't dance on pin heads :-) Who cares if there are multiple conflicting pragmas in the configuration pragmas, this simply won't happen in practice. Don't undermiune the utility of USEFUL applications by worrying about things that are useless! ************************************************************* From: Randy Brukardt Sent: Tuesday, November 30, 1999 11:10 AM I would agree, except that multiple conflicting pragmas are USEFUL: they provide an easy way to turn off all but one check: pragma Suppress (All_Checks); pragma Unsuppress (Storage_Check); (But of course the order is significant). This is what I use in release code where size is an issue: the only check that I find critical is Stack and Heap checking (because the results are so catastrophic if they are omitted). I want to have a way to do this as a configuration pragma/option in any implementation that I'm using. Making it implementation-defined eliminates that possibility (unless all of the vendors support it in the same way, which is very unlikely). Randy. ************************************************************* From: Tucker Taft Sent: Tuesday, November 30, 1999 3:59 PM Randy Brukardt wrote: > > > > The problem is that configuration pragmas are not given in a clearly defined > > > order. > > > > Have you considered making it implementation defined in that case? > > Not seriously. That seems like a last resort: punt! Such a definition would > not be useful to people who need portable code, and of course would be > untestable. I would make it well defined if the configuration pragmas are all in the same file (i.e., the last one applies). If the configuration pragmas are in separate files, then it is implementation-defined what order these end up in when conceptually combined. They will be combined in some order, so there are a finite number of distinct orders possible, and so it is testable. If a programmer wants portability, they would put all the configuration pragmas in the same file. Hence, if they wanted to suppress everything but tag_check, they could write: pragma Suppress(All_Checks); pragma Unsuppress(Tag_Check); That seems pretty intuitive. ************************************************************* From: Ted Baker Sent: Tuesday, November 30, 1999 7:07 PM After hearing a lot of talk on this one, I believe that as a user I would view the nesting of Suppress and Unsuppress pragmas as unwise, and so would prefer for an implementation to at least give a warning when this occurs. However, if nesting is allowed, the innermost nested region should certainly retain the effect of the pragma given for that region. ************************************************************* From: Robert Dewar [dewar@GNAT.COM] Sent: Tuesday, November 30, 1999 7:30 PM YOu don't want a warning for all cases of nesting, otherwise every use of Unsuppress in a typically suppressed region would generate a warning. Since this kind of use is the principle utility o Unsuppress, it seems wrong to warn unconditionally. For example, we generally compile the GNAT runtim elibrary with checks off (i.e. the equivalent of a pragma Suppress at the configuration level). Individual little sections of the runtime that rely on checks (e.g. converting Constraint_Error into Time_Error in Calendar) do an Unsuppress. ************************************************************* From: Robert Dewar Sent: Tuesday, November 30, 1999 5:40 PM <> I agree with this, and cannot imagine that it in fact does not hold already for all existing compilers. ************************************************************* From: Tucker Taft Sent: Thursday, December 02, 1999 10:23 AM Randy Brukardt wrote: > I would agree, except that multiple conflicting pragmas are USEFUL: they > provide an easy way to turn off all but one check: > > pragma Suppress (All_Checks); > pragma Unsuppress (Storage_Check); > > (But of course the order is significant). This is what I use in release code > where size is an issue: the only check that I find critical is Stack and > Heap checking (because the results are so catastrophic if they are omitted). > > I want to have a way to do this as a configuration pragma/option in any > implementation that I'm using. Making it implementation-defined eliminates > that possibility (unless all of the vendors support it in the same way, > which is very unlikely). I trust you received the earlier message where this would be well-defined if they are all in the same compilation. If the configuration pragmas are in separate (unit-less) compilations, then the order in which the configuration pragmas are combined is implementation-defined (or perhaps even "unspecified"). That would seem to address your concern. In general, having multiple unit-less compilations with configuration pragmas is a bit confusing anyway, I would say (though our front end supports it ;-). *************************************************************