type Item_Ptr is access all Item;
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr;
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
type Item_Ptr is access all Item;
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr;
What I don't see is how you can implement this, never mind any other problems.
On 2021-09-29 13:05, Simon Wright wrote:
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
type Item_Ptr is access all Item;What I don't see is how you can implement this, never mind any other
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr;
problems.
A naive, but wrong due to 7.6.1 (11.1/3) nonsense, implementation would be:
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr is
type Ptr is access Item;
for Ptr'Storage_Pool use Pool;
Object : Ptr := new Item (Text'Length);
begin
Object.Text := Text;
return Object.all'Unchecked_Access;
end New_Item;
On 2021-09-29 13:05, Simon Wright wrote:
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
type Item_Ptr is access all Item;
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr;
What I don't see is how you can implement this, never mind any other
problems.
A naive, but wrong due to 7.6.1 (11.1/3) nonsense, implementation would
be:
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr is
type Ptr is access Item;
for Ptr'Storage_Pool use Pool;
Object : Ptr := new Item (Text'Length);
begin
Object.Text := Text;
return Object.all'Unchecked_Access;
end New_Item;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
On 2021-09-29 13:05, Simon Wright wrote:
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
type Item_Ptr is access all Item;What I don't see is how you can implement this, never mind any other
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr;
problems.
A naive, but wrong due to 7.6.1 (11.1/3) nonsense, implementation would be: >>
function New_Item
( Pool : in out Root_Storage_Pool'Class;
Text : String
) return Item_Ptr is
type Ptr is access Item;
for Ptr'Storage_Pool use Pool;
Object : Ptr := new Item (Text'Length);
begin
Object.Text := Text;
return Object.all'Unchecked_Access;
end New_Item;
OK, that code compiles.
What you'd need to happen when the returned Item_Ptr is freed would be
for the mechanism of the actual pool to be invoked. But Item_Ptr was
declared without any pool specified, so uses the default, and when the returned Item_Ptr is freed it uses the default pool's mechanism.
But of course what actually happens with this code is that the returned Item_Ptr is left dangling; my test
with P;
with System.Pool_Local; -- GNAT special
with Ada.Text_IO; use Ada.Text_IO;
procedure Test is
use P;
Pool : System.Pool_Local.Unbounded_Reclaim_Pool;
Ptr : Item_Ptr := New_Item (Pool, "hello");
begin
Put_Line (Ptr.Text);
Free (Ptr);
end Test;
manages flukily to print "hello" before crashing at the Free (Ptr).
I don't see how what you want can be achieved without every access type containing a reference to the pool the object was allocated from.
It's surely wrong, because you have to deallocate from the same pool as you allocated. And you have no way to save such a thing. There is no capability in Ada to use multiple pools with one access type.
At best, you could directly call Allocate and Deallocate for this purpose, but it is impossible to use anything built-in.
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
It should print it twice, because Finalize must be called twice. Once
inside New_Item, then in Free.
That's in your implementation of Finalize, which you haven't shown us
It should print it twice, because Finalize must be called twice. Once
inside New_Item, then in Free.
On 29.09.21 11:09, Dmitry A. Kazakov wrote:
For Ada programmers who wonder what it is,What's the reasoning behind run-time selection of storage pools?
For Ada programmers who wonder what it is,What's the reasoning behind run-time selection of storage pools?
On 2021-09-30 20:23, G.B. wrote:
On 29.09.21 11:09, Dmitry A. Kazakov wrote:
For Ada programmers who wonder what it is,What's the reasoning behind run-time selection of storage pools?
It happens quite frequently. Here is an example without controlled
objects, just an illustration of a dynamically selected storage pool.
Consider a JSON parser. It is be an Ada object with a buffer inside which size is a discriminant. On top of the buffer sits an arena pool. The parts
of the parsed JSON object are allocated in the arena. After parsing the result can be used until the next parsing that will sweep the arena, no Unchecked_Deallocate.
In this case the collection rule will have no effect since JSON objects do not require controlled components (or tasks, yet another thing killed by
the collection).
Yes, every general access type that permits instantiation of Unchecked_Dellocation must indicate the target object's pool, directly,
e.g. per fat pointer, or indirectly by some other schema. I see nothing in
RM that allows a different implementation. But it is could be a bug by omission and I am not a language lawyer anyway.
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:sj3r7l$pla$2@gioia.aioe.org...
...
Yes, every general access type that permits instantiation of
Unchecked_Dellocation must indicate the target object's pool, directly,
e.g. per fat pointer, or indirectly by some other schema. I see nothing in >> RM that allows a different implementation. But it is could be a bug by
omission and I am not a language lawyer anyway.
Each access type has only one pool, and all allocations and deallocations
for that access type use that pool. You can see at RM 13.11(13) that you can retrieve the storage pool of T, that wouldn't be possible if it could have multiple pools. Allocation for T uses T'Storage_Pool (RM 13.11(16)), and deallocation for T also uses T'Storage_Pool (13.11.2(9/3) - I see this wording isn't as clear as it could be, but "the storage_pool" here is the
one for the type T. It is clear, however, from 13.11.2(16/3) that it is erroneous to deallocate an object for some other pool than the pool of the access type passed to the instance of Unchecked_Deallocation.
Surely no one would expect the pool to be associated with the object -- it would be impossible to interface to C or most other languages that way. Note that GNAT insists that all access types are C-compatible.
As I've said repeatedly, if you want the behavior of multiple pools with a single access type, you have to use the subpool mechanism somehow.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 366 |
Nodes: | 16 (2 / 14) |
Uptime: | 13:17:25 |
Calls: | 7,819 |
Calls today: | 2 |
Files: | 12,927 |
Messages: | 5,767,804 |