!standard 11.4.1(10.1/2) 07-06-15 AI05-0043-1/01 !standard 11(2) !class binding interpretation 07-03-27 !status ARG Approved 8-0-2 07-06-03 !status work item 07-03-27 !status received 07-01-19 !priority Low !difficulty Easy !qualifier Omission !subject The Exception_Message for failed language-defined checks. !summary The introduction to Section 11 is incorrect. The Exception_Message for cases not spelled out in 11.4.1(10.1/2) is unspecified. !question (1) 11(2) says "An exception is raised initially either by a raise_statement or by the failure of a language-defined check." But this isn't correct any more, since an exception can also be raised initially by a Raise_Exception call. (2) 11.4.1(10.1/2) describes the operation of Ada.Exceptions.Exception_Message. It seems to intend to list all of the possible ways for a message to be created. But it doesn't mention an exception raised by a language-defined check. Nor does it mention an exception raised in a calling task (9.5.2(24), which is noted in the AARM as a new occurrence). !recommendation (See Summary.) !wording (1) Modify 11(2): An exception is raised initially either by a raise_statement{, by a call to Raise_Exception,} or by the failure of a language-defined check. (2) Add to 11.4.1(10.1/2): For an occurrence originally raised for some other reason, the message is an unspecified string. AARM Note: There is Implementation Advice about the contents of this string for language-defined checks. !discussion We could say more about occurrences created due to the raising of exceptions in the calling task (that is, 9.5.2(24)), and possibly about occurrences which are created by a stream attribute, but it doesn't seem worthwhile. Implementers will do the most useful thing for their customers, which is likely to be to preserve the most information. And this feature is intended as a debugging aid, not as an information source, so strong rules are not required. !corrigendum 11(2) @drepl An exception is raised initially either by a @fa or by the failure of a language-defined check. @dby An exception is raised initially either by a @fa, by a call to Raise_Exception, or by the failure of a language-defined check. !corrigendum 11.4.1(10.1/2) @drepl Exception_Message returns the message associated with the given Exception_Occurrence. For an occurrence raised by a call to Raise_Exception, the message is the Message parameter passed to Raise_Exception. For the occurrence raised by a @fa with an @I@fa and a @I@fa, the message is the @i@fa. For the occurrence raised by a @fa with an @i@fa but without a @i@fa, the message is a string giving implementation-defined information about the exception occurrence. In all cases, Exception_Message returns a string with lower bound 1. @dby Exception_Message returns the message associated with the given Exception_Occurrence. For an occurrence raised by a call to Raise_Exception, the message is the Message parameter passed to Raise_Exception. For the occurrence raised by a @fa with an @I@fa and a @I@fa, the message is the @i@fa. For the occurrence raised by a @fa with an @i@fa but without a @i@fa, the message is a string giving implementation-defined information about the exception occurrence. For an occurrence originally raised for some other reason, the message is an unspecified string. In all cases, Exception_Message returns a string with lower bound 1. !ACATS test Since this is unspecified, no useful ACATS test can be constructed. !appendix From: Adam Benschan Date: Friday, January 19, 2007 2:15 PM !topic Exception_Message and exceptions raised in accept statements !reference RM05 11.4.1(10.1/2), 9.5.2(24) !from Adam Beneschan 07-01-19 !discussion RM05 contains a new paragraph, 11.4.1(10.1), describing Ada.Exceptions.Exception_Message: Exception_Message returns the message associated with the given Exception_Occurrence. For an occurrence raised by a call to Raise_Exception, the message is the Message parameter passed to Raise_Exception. For the occurrence raised by a raise_statement with an exception_name and a string_expression, the message is the string_expression. For the occurrence raised by a raise_statement with an exception_name but without a string_expression, the message is a string giving implementation-defined information about the exception occurrence. In all cases, Exception_Message returns a string with lower bound 1. One possible objection is that since Exception_Message seems to want to list all the cases (raised by Raise_Exception, raised by a raise_statement with a string_expression, raised by a raise_statement with an exception name but without a string_expression), then why did it leave out the case of an occurrence raised by the failure of a language-defined check? This is a very minor nit, I suppose. The implementation advice in 11.4.1(19) says that Exception_Message should return "something useful for debugging", so it probably can be assumed that Exception_Message "should" return a string giving some implementation-defined information about why the exception was raised. It probably ought to be explicit in 11.4.1(10.1), in my opinion. However, one case that I think needs to be spelled out is the exception raised in a calling task, during an entry call, when the accept statement propagates an exception. 9.5.2(24) says that the same exception is raised by the execution of the corresponding entry_call_statement, and AARM 9.5.2(24.b) makes it clear that this is considered a *new* exception occurrence. So what happens when Exception_Message is called on this new exception occurrence---especially when the exception in the accept was raised by a Raise_Exception or by a raise statement with a string_exception? Is the message for the occurrence in the calling task the same as that for the raise statement, or is it simply something implementation-defined (same as for a check failure)? I don't think the answer is clear from the RM. One other nitpick: 11(2) says "An exception is raised initially either by a raise_statement or by the failure of a language-defined check." But this isn't correct any more, since an exception can also be raised initially by a Raise_Exception call. Of course, this is a very minor problem. **************************************************************** From: Randy Brukardt Date: Monday, January 22, 2007 11:33 PM ... > One possible objection is that since Exception_Message seems to want > to list all the cases (raised by Raise_Exception, raised by a > raise_statement with a string_expression, raised by a raise_statement > with an exception name but without a string_expression), then why did > it leave out the case of an occurrence raised by the failure of a > language-defined check? This is a very minor nit, I suppose. The > implementation advice in 11.4.1(19) says that Exception_Message should > return "something useful for debugging", so it probably can be assumed > that Exception_Message "should" return a string giving some > implementation-defined information about why the exception was raised. > It probably ought to be explicit in 11.4.1(10.1), in my opinion. We don't put "should"s in normative text. We keep them separate in Implementation Advice sections. Moreover, there is a difference between saying "For the occurrence raised by the failure of a language-defined check, the message is a string giving implementation-defined information about the language-defined check." and what the Implementation Advice says. That's because there is a requirement to document everything implementation defined, while there is only a requirement to document whether Implementation Advice is followed. The latter can be done by simply saying "Yes, we do" (without details), while the latter means that the contents of every string should be documented. (Since Documentation Requirements aren't checked in any way, I'm not sure there is any functional difference, but there is a different intent.) OTOH, we really do need to say something about occurrences that come from other places. You mentioned two (language-defined checks, and accept statements), but I wouldn't be stunned if there are others. Probably the best thing would be to add a sentence like: For an occurrence originally raised for some other reason, the message is an unspecified string. (I said "originally" so this would not be construed to cover reraises.) One could argue that it already is unspecified (because it doesn't say), but the appearance of complete-appearing list makes it odd that other cases aren't mentioned. > However, one case that I think needs to be spelled out is the > exception raised in a calling task, during an entry call, when the > accept statement propagates an exception. 9.5.2(24) says that the > same exception is raised by the execution of the corresponding > entry_call_statement, and AARM 9.5.2(24.b) makes it clear that this is > considered a *new* exception occurrence. So what happens when > Exception_Message is called on this new exception > occurrence---especially when the exception in the accept was raised by > a Raise_Exception or by a raise statement with a string_exception? Is > the message for the occurrence in the calling task the same as that > for the raise statement, or is it simply something > implementation-defined (same as for a check failure)? I don't think > the answer is clear from the RM. Well, I think it is clear that it is unspecified, and that actually is perfectly OK for this case. Although I'm not completely convinced that it is actually a new raise; I'd expect it to be a copy of the existing occurrence (i.e. new but equal). The normative wording is "also raised", which doesn't clearly state anything whatsoever about the occurrence in question. The AARM note says something about the intent that it is a new occurrence, but it gives no clues as to what might be in that occurrence. Which I guess is the definition of unspecified. ;-) One could try to nail down this stuff, but then we have to try to figure out every possible way that an occurrence can be created. (Such as streaming one in - does that have to preserve the message? Always, or only when it has a defined result?) It doesn't seem worth the effort to me; do implementers actually try to make this stuff useless??? > One other nitpick: 11(2) says "An exception is raised initially either > by a raise_statement or by the failure of a language-defined check." > But this isn't correct any more, since an exception can also be raised > initially by a Raise_Exception call. Of course, this is a very minor > problem. Another ancient problem. I don't think anyone looked for Ada 95 wording bugs this time; we assumed that was already correct. ****************************************************************