From: Fionn Mac Cumhaill <invisible@hiding.from.spam>
Subject: Re: Exceptions and out procedure arguments (using GNAT GPL)
Date: Tue, 19 Jun 2007 05:23:51 GMT
Date: 2007-06-19T05:23:51+00:00 [thread overview]
Message-ID: <drle731ukcmhlt5km966imoudr5s92napd@4ax.com> (raw)
In-Reply-To: 1182181497.595409.300500@a26g2000pre.googlegroups.com
On Mon, 18 Jun 2007 08:44:57 -0700, Adam Beneschan <adam@irvine.com>
wrote:
>On Jun 15, 6:05 pm, Fionn Mac Cumhaill <invisi...@hiding.from.spam>
>wrote:
>> Consider a procedure that starts like this:
>>
>> procedure My_Procedure (
>> O: out integer
>> )
>> is
>> begin
>>
>> -- various statements follow
>>
>> O := 999;
>>
>> -- more statements follow
>>
>> raise My_Exception;
>>
>> I'm using GNAT GPL.
>>
>> My question is:
>>
>> Is the routine which calls My_Procedure guaranteed to get a value if
>> it does something like this?
>>
>> X := 0;
>> My_Procedure(X);
>>
>> and has an exception handler
>>
>> exception
>> when My_Exception =>
>> null;
>>
>> Will X get a value of 999?
>
>No. When My_Procedure completes abnormally, due to an exception
>raise, X should have the value that it had before My_Procedure was
>called. An Ada compiler that causes X to be 999 here (if it wasn't
>999 before) is incorrect. This isn't a matter of "is the compiler
>allowed to optimize" or "all bets are off" or "you can't rely on the
>value"; rather, the semantics *require* that X be unchanged. This is
>because O is a by-copy parameter (6.2(3)), which means that inside the
>subprogram, O denotes a *separate* object from X (6.2(2)), and O is
>copied back to X only on *normal* completion of the subprogram
>(6.4.1(17)), but an exception raise causes My_Procedure to be
>completed abnormally (7.6.1(2)).
>
>By-reference parameters work differently. If, for example, your OUT
>parameter were a tagged record, and you had assigned a component of it
>to 999, it should still be 999 even after the exception in
>My_Procedure is raised. As I interpret the rules in 11.6, this might
>not be the case if the exception raise is due to a language-defined
>check; if, after you assign the component to 999, you do an array
>access on a nonexistent element, so that Constraint_Error is raised,
>this is a language-defined check, and now I think the compiler may be
>allowed to optimize in a way so that the assignment of the component
>to 999 might not take place. But in your example, you have an
>explicit raise of a user-defined exception, and 11.6 doesn't apply to
>those, as I read it. The same would apply in an access parameter
>case; if My_Procedure is abandoned due to a raise of a user-defined
>exception, you can count on any assignments that you've already done
>through the access value, but you can't count on assignments done
>before My_Procedure is abandoned due to a language-defined check.
>
>Hope this helps,
> -- Adam
>
It does indeed help, and convinces me that GNAT GPL 2007 has a bug.
The example I gave is a highly condensed version of a problem I had
while working on upgrading the MySQL binding in GNADE to work with
MySQL 5. I found after posting my first message that the situation is
even more confusing than I thought it was.
Having (more or less) completed the work on the binding, I proceeded
to lay another package on top of it so that I could have something
that closely resembled the database package in GWindows. This would
greatly simplify the task of moving a lot of Windows software to
Linux. The sample is a highly condensed version of my Query procedure
which raises an exception when a query sent to the MySQL database
server returns no rows. The O argument in my sample is actually a
handle whisch is used by other routines which extract data from the
columns in the returned row set.The routine that uses My_Procedure to
set the value of X is a procedure in the additional package. Let's
call it My_Outer_Procedure. I have two test programs that use a query
which returns no rows.
What I have found is, in effect, that whether X is 0 or 999 depends on
something in the routine that calls My_Outer_Procedure. I have two
test programs which use a query which produces no rows, which means
that My_Procedure always raises an exception. In one of the test
programs, X is 0, and in the other it is 999, which makes no sense to
me.
I eliminated the problem by modifying the offending procedure to not
raise exceptions. It now returns a status code in an additional out
argument.
next prev parent reply other threads:[~2007-06-19 5:23 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-16 1:05 Exceptions and out procedure arguments (using GNAT GPL) Fionn Mac Cumhaill
2007-06-16 1:53 ` Anh Vo
2007-06-16 2:50 ` Brian May
2007-06-16 3:08 ` Randy Brukardt
2007-06-16 6:55 ` Dmitry A. Kazakov
2007-06-18 15:44 ` Adam Beneschan
2007-06-19 5:23 ` Fionn Mac Cumhaill [this message]
2007-06-19 7:34 ` Maciej Sobczak
2007-06-19 15:21 ` Adam Beneschan
2007-06-19 20:07 ` Dmitry A. Kazakov
2007-06-19 21:20 ` Adam Beneschan
2007-06-20 6:16 ` Georg Bauhaus
2007-06-20 8:01 ` Dmitry A. Kazakov
2007-06-20 8:45 ` Georg Bauhaus
2007-06-20 9:29 ` Dmitry A. Kazakov
2007-06-20 6:21 ` Georg Bauhaus
2007-06-20 8:02 ` Dmitry A. Kazakov
2007-06-20 8:46 ` Georg Bauhaus
2007-06-20 9:29 ` Dmitry A. Kazakov
2007-06-20 10:13 ` Georg Bauhaus
2007-06-20 12:58 ` Dmitry A. Kazakov
2007-06-20 14:16 ` Georg Bauhaus
2007-06-20 18:22 ` Dmitry A. Kazakov
2007-06-20 19:16 ` Georg Bauhaus
2007-06-20 20:40 ` Dmitry A. Kazakov
2007-06-21 9:52 ` Georg Bauhaus
2007-06-21 13:48 ` Dmitry A. Kazakov
2007-06-22 18:15 ` Georg Bauhaus
2007-06-22 19:45 ` Dmitry A. Kazakov
2007-06-20 15:15 ` Fionn Mac Cumhaill
2007-06-19 21:40 ` Randy Brukardt
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox