From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: A bad counterintuitive behaviour of Ada about OO
Date: Wed, 06 Aug 2014 00:51:18 +0300
Date: 2014-08-06T00:51:18+03:00 [thread overview]
Message-ID: <c4d1ujFghdnU1@mid.individual.net> (raw)
In-Reply-To: <lrrgvu$6mh$1@speranza.aioe.org>
On 14-08-06 00:06 , Victor Porton wrote:
> Simon Wright wrote:
>
>> Victor Porton <porton@narod.ru> writes:
>>
>>> http://freesoft.portonvictor.org/binaries/ada-obj-test.tar.gz
>>>
>>> contains a tiny Ada program which prints 0 despite intuition suggests
>>> that it should print 123, because it just copies (using Adjust) an object
>>> holding 123.
>>>
>>> In this program Handle_Type models some handle provided by an external
>>> API, where 0 is an undefined handle. Base_Object is a tagged record which
>>> holds a handle inside itself and can copy or destroy the handle
>>> automatically (as Base_Object is a controlled object).
>>>
>>> Example_Record is a derived type of Base_Object which imitates a behavior
>>> of a simple library which operates over some handles. For example, in
>>> this example copying a handle preserves it unchanged.
>>>
>>> This tiny program was created by me as a model of my real Ada bindings
>>> for Raptor C library, which produces a wrong behavior.
>>>
>>> Why Ada behaves in this counter-intuitive way?
>>>
>>> What should I do in similar situations when developing real Ada software?
>>
>> I think what is happening is that in
>>
>> function From_Handle(Handle: Handle_Type) return Base_Object is
>> begin
>> return (Ada.Finalization.Controlled with Handle=>Handle);
>> end;
>>
>> the aggregate is created and copied to the function's result as a
>> Base_Object, so that when
>>
>> procedure Adjust(Object: in out Base_Object) is
>> begin
>> if Object.Handle /= 0 then
>> Object.Handle := Copy_Handle(Base_Object'Class(Object),
>> Object.Handle);
>> end if;
>> end;
>>
>> is called during the copy,
>>
>> function Copy_Handle(Object: Base_Object; Handle: Handle_Type) return
>> Handle_Type is begin
>> return 0;
>> end;
>>
>> returns 0, as you've seen.
>>
>>
>> (1) If all you wanted to do was copy the Handle over, you don't need to
>> do anything, because that's the default behaviour (i.e., copies the
>> bits).
>>
>> (2) Normally, From_Handle wouldn't be inherited, so you'd have had to
>> write your own; because Example_Object has a null extension, it can be
>> inherited.
>
> I've added in example_record.ads:
>
> function From_Handle(Handle: Handle_Type) return Example_Object;
>
> and in example_record.adb:
>
> function From_Handle(Handle: Handle_Type) return Example_Object is
> begin
> return (Base_Object'(From_Handle(Handle)) with null record);
> end;
>
> It prints "0" not as it was before.
(I assume the "not" above is a mistake, and you mean that it prints "0"
just as before.)
That happens because in your new From_Handle for Example_Object, the
part Base_Object'(From_Handle(Handle)) returns an object of type
Base_Object, which is then assigned into the parent part of the
extension aggregate, and this assignment operation invokes the Adjust
operation for Base_Object, which invokes Copy_Handle for Base_Object,
which returns a zero handle.
> What to do? I write a real software project and need to make a decision what
> to do in this situation.
Alternatives:
1. Write a sensible Copy_Handle for Base_Object (preferred solution), or
2. make Example_Record a child package of Handled_Record, which makes
the internal structure of Base_Object visible, and lets you write
function From_Handle(Handle: Handle_Type) return Example_Object is
begin
return (Ada.Finalization.Controlled with Handle => Handle);
end;
and therefore lets you create Example_Objects without going through a
Base_Object and its handle-destroying Copy_Handle.
By the way, Dmitry's advice not to use re-dispatching is his personal
opinion, shared by some people on comp.lang.ada but not by me; you
should consider the pros and cons yourself.
Re-dispatching is what happens in your Adjust operation when you convert
the Object to Base_Type'Class and then invoke Copy_Handle. The
conversion forces the call to be a dispatching call. Without conversion,
the call is statically bound to the Copy_Handle of Base_Object.
Re-dispatching plays no role in your problem. The problem is that by
making Base_Object private, and Example_Record not a child of
Handled_Record, you have made it impossible to create an Example_Object
without first creating a Base_Object and therefore invoking the Adjust
and Copy_Handle for Base_Object.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
next prev parent reply other threads:[~2014-08-05 21:51 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-05 20:09 A bad counterintuitive behaviour of Ada about OO Victor Porton
2014-08-05 20:58 ` Simon Wright
2014-08-05 21:06 ` Victor Porton
2014-08-05 21:51 ` Niklas Holsti [this message]
2014-08-05 22:13 ` Victor Porton
2014-08-05 22:35 ` Victor Porton
2014-08-05 23:25 ` Adam Beneschan
2014-08-05 20:59 ` Dmitry A. Kazakov
2014-08-05 21:07 ` Victor Porton
2014-08-05 22:39 ` Shark8
2014-08-05 21:11 ` Victor Porton
2014-08-06 7:26 ` Dmitry A. Kazakov
2014-08-07 7:41 ` Maciej Sobczak
2014-08-07 8:50 ` Dmitry A. Kazakov
2014-08-08 7:54 ` Maciej Sobczak
2014-08-08 8:14 ` Dmitry A. Kazakov
2014-08-08 13:06 ` Maciej Sobczak
2014-08-08 13:22 ` Dmitry A. Kazakov
2014-08-08 22:32 ` Randy Brukardt
2014-08-09 16:11 ` Maciej Sobczak
2014-08-09 16:48 ` Dmitry A. Kazakov
2014-08-10 20:55 ` Maciej Sobczak
2014-08-11 7:41 ` Dmitry A. Kazakov
2014-08-11 7:58 ` Maciej Sobczak
2014-08-11 8:23 ` Dmitry A. Kazakov
2014-08-12 7:50 ` Maciej Sobczak
2014-08-11 11:35 ` G.B.
2014-08-08 22:26 ` Randy Brukardt
2014-08-08 8:34 ` Shark8
2014-08-08 12:59 ` Maciej Sobczak
2014-08-08 22:37 ` Randy Brukardt
2014-08-08 22:53 ` Jeffrey Carter
2014-08-07 8:58 ` J-P. Rosen
2014-08-07 9:40 ` Dmitry A. Kazakov
2014-08-07 11:17 ` J-P. Rosen
2014-08-07 12:28 ` Dmitry A. Kazakov
2014-08-07 13:34 ` J-P. Rosen
2014-08-07 16:10 ` Dmitry A. Kazakov
2014-08-07 18:14 ` Robert A Duff
2014-08-07 19:41 ` Dmitry A. Kazakov
2014-08-07 20:53 ` Robert A Duff
2014-08-08 7:43 ` Dmitry A. Kazakov
2014-08-08 8:18 ` Shark8
2014-08-08 7:45 ` J-P. Rosen
2014-08-08 8:04 ` Dmitry A. Kazakov
2014-08-08 8:55 ` J-P. Rosen
2014-08-08 9:13 ` Dmitry A. Kazakov
2014-08-08 10:01 ` J-P. Rosen
2014-08-08 10:53 ` Dmitry A. Kazakov
2014-08-08 10:56 ` Victor Porton
2014-08-08 12:00 ` J-P. Rosen
2014-08-08 13:11 ` Dmitry A. Kazakov
2014-08-08 13:53 ` J-P. Rosen
2014-08-08 20:23 ` Dmitry A. Kazakov
2014-08-07 20:29 ` Shark8
2014-08-08 7:49 ` J-P. Rosen
2014-08-08 8:12 ` Shark8
2014-08-08 8:26 ` Dmitry A. Kazakov
2014-08-08 11:10 ` Shark8
2014-08-08 11:20 ` Dmitry A. Kazakov
2014-08-08 19:34 ` Shark8
2014-08-08 20:23 ` Dmitry A. Kazakov
2014-08-07 15:03 ` Jeffrey Carter
2014-08-08 7:48 ` Maciej Sobczak
2014-08-08 8:51 ` J-P. Rosen
2014-08-08 13:25 ` Maciej Sobczak
2014-08-08 13:34 ` J-P. Rosen
2014-08-08 13:52 ` Dmitry A. Kazakov
2014-08-08 14:21 ` J-P. Rosen
2014-08-08 20:23 ` Dmitry A. Kazakov
2014-08-08 22:08 ` Randy Brukardt
2014-08-08 22:18 ` Randy Brukardt
2014-08-06 4:50 ` Per Sandberg
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox