comp.lang.ada
 help / color / mirror / Atom feed
* Novice help with types and de-allocation.
@ 2002-11-18  6:40 Stapler
  2002-11-18 11:05 ` Colin Paul Gloster
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Stapler @ 2002-11-18  6:40 UTC (permalink / raw)


Alright, I have a package which more or less works but I'm having trouble
in a couple spots. I've placed comments where I'm having trouble.


with Ada.Unchecked_Deallocation;
generic
	Size : Positive;
	
package int_buff is
	
	type Int_Buffer is limited private;
	type Buff_Ptr is limited private;
	type Buff_Out is array(Positive range <>) of Integer;
	
	procedure Insert( X : in Integer; Y : in out Int_Buffer);
	procedure Clear_Buff( Y : in out Int_Buffer; Z : in out Buff_Ptr);
	procedure Ditch_Buff( Y : in out Int_Buffer; Z : in out Buff_Ptr);
	
	function Read_Buff( Y : in Int_Buffer; Read_length : in Natural; Loc :in Natural) return Buff_Out;  
	function Sum_Buff( Y : in Int_Buffer) return Integer;
	
private

	Buff_Indexer : Positive range 1..Size;
	
	type Int_Buffer is array(1..Size) of Integer;
	pragma Pack( Int_Buffer );
	type Buff_Ptr is access Int_Buffer;
	procedure Free_Buff is new Ada.Unchecked_Deallocation(Int_Buffer, Buff_Ptr);
	
end int_buff;
	
package body int_buff is

	procedure Insert(X : in Integer; Y : in out Int_Buffer) is
	
	begin
		Buff_Indexer := X;
		Y(Buff_Indexer) := X;
		
	end Insert;
	
	procedure Clear_Buff( Y : in out Int_Buffer; Z : in out Buff_Ptr) is
		X : Int_Buffer;
	-- This procedure obviously needs more work.
	-- It's suppose to de-allocate the old buffer and create a new one.
	begin
		
		Free_Buff(Z);
		Y := X;
		
	end Clear_Buff;
	
	function Read_Buff(Y : in Int_Buffer; Read_Length : in Natural; Loc : in Natural) return Buff_Out is
	
		Ret_Buff : Buff_Out(1..Read_Length);
	begin
		-- For some reason, the compiler expects Y to be of type Buff_Out.
		-- Do I need to use Unchecked_Conversion here?
		Ret_Buff := Y(Loc .. Read_Length - 1);
	
		return Ret_Buff;
		
	end Read_Buff;
	
	function Sum_Buff( Y : in Int_Buffer) return Integer is
	
		Sum : Integer := 0;
		
	begin
	
		for I in Y'range loop
		
			Sum := Sum + Y(I);
			
		end loop;
		
		return Sum;
		
	end Sum_Buff;
	
	procedure Ditch_Buff(Y : in out Int_Buffer; Z : in out Buff_Ptr) is
	
	begin
	
		Free_Buff(Z);
		
	end Ditch_Buff;
	
end int_buff;
	
	
Try not to laugh to hard. I'm still a newb. Any pointers would be
appreciated.
		

Stapler
"Still tilting at WindMills."



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Novice help with types and de-allocation.
  2002-11-18  6:40 Novice help with types and de-allocation Stapler
@ 2002-11-18 11:05 ` Colin Paul Gloster
  2002-11-18 15:29 ` Ted Dennison
  2002-11-18 19:06 ` Jeffrey Carter
  2 siblings, 0 replies; 6+ messages in thread
From: Colin Paul Gloster @ 2002-11-18 11:05 UTC (permalink / raw)


The thread starter had:

--snip

package int_buff is
        
        type Int_Buffer is limited private;
--snip
        type Buff_Out is array(Positive range <>) of Integer;

--snip

        function Read_Buff( Y : in Int_Buffer; Read_length : in Natural;
Loc :in Natural) return Buff_Out;
--snip

private

--snip
        type Int_Buffer is array(1..Size) of Integer;
--snip

end int_buff;

package body int_buff is

--snip
        function Read_Buff(Y : in Int_Buffer; Read_Length : in Natural;
Loc : in Natural) return Buff_Out is
        
                Ret_Buff : Buff_Out(1..Read_Length);
        begin
                -- For some reason, the compiler expects Y to be of type
Buff_Out.
                -- Do I need to use Unchecked_Conversion here?
                Ret_Buff := Y(Loc .. Read_Length - 1);
        
                return Ret_Buff;
                
        end Read_Buff;

--snip

end int_buff;

The compiler expects Y to be of type Buff_Out because you are assigning
a slice of Y (all or part of the array Y) to something which is of type
Buff_Out. Buff_Out is also an array of integers, but even if the slice
was the same size as the size of your Buff_Out array, this would be
illegal (arrays which just happen to have the same size in Ada of the
same component types are not the same array array types unless they were
actually declared to be of the same type).

Unchecked_Conversion can be nasty, so can this replacement line:
Ret_Buff := Buff_Out(Y(Loc .. Read_Length - 1));
which is also a conversion. Just make sure it is safe (e.g. that Y(Loc
.. Read_Length - 1) is not longer than Ret_Buff and that if it is
shorter than Ret_Buf, that you are happy with the unfilled in parts
being the way that they are).



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Novice help with types and de-allocation.
  2002-11-18  6:40 Novice help with types and de-allocation Stapler
  2002-11-18 11:05 ` Colin Paul Gloster
@ 2002-11-18 15:29 ` Ted Dennison
  2002-11-18 21:33   ` Stapler
  2002-11-18 23:34   ` Stapler
  2002-11-18 19:06 ` Jeffrey Carter
  2 siblings, 2 replies; 6+ messages in thread
From: Ted Dennison @ 2002-11-18 15:29 UTC (permalink / raw)


Stapler <spam.magnet@yahoo.com> wrote in message news:<sX%B9.65239$NH2.4291@sccrnsc01>...
> Alright, I have a package which more or less works but I'm having trouble
> in a couple spots. I've placed comments where I'm having trouble.

> 	type Buff_Out is array(Positive range <>) of Integer;
...
> 	type Int_Buffer is array(1..Size) of Integer;
...
> 	function Read_Buff(Y : in Int_Buffer; Read_Length : in Natural; Loc : in Natural) return Buff_Out is
> 	
> 		Ret_Buff : Buff_Out(1..Read_Length);
> 	begin
> 		-- For some reason, the compiler expects Y to be of type Buff_Out.
> 		-- Do I need to use Unchecked_Conversion here?
> 		Ret_Buff := Y(Loc .. Read_Length - 1);

The "some reason" is that the object you are assigning Y into is of
that type. Unlike some other languages, in Ada you can't assign
objects of one type into objects of a another type, just because both
types have similar contents. You defined Int_Buffer and Buff_Out to be
different types, so they are truly considered unrelated types.

Probably the best way out would be to make Int_Buffer a *subtype* of
Buff_Out, instead of a type in its own right. If you don't like that
solution, then the next best thing would be to make the private
definition of "Int_Buffer" a "new Buff_Out". That would allow you to
use a simple type conversion.

Do *not* used Unchecked_Conversion for this. Unchecked_Conversion is
not for bailing yourself out of a badly-designed type system. Use it
for when you truly have multiple different ways of looking at the data
(eg: A complicated record that requires a CRC at the end, so it must
also be an array of unsigned bytes).



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Novice help with types and de-allocation.
  2002-11-18  6:40 Novice help with types and de-allocation Stapler
  2002-11-18 11:05 ` Colin Paul Gloster
  2002-11-18 15:29 ` Ted Dennison
@ 2002-11-18 19:06 ` Jeffrey Carter
  2 siblings, 0 replies; 6+ messages in thread
From: Jeffrey Carter @ 2002-11-18 19:06 UTC (permalink / raw)


Stapler wrote:
> with Ada.Unchecked_Deallocation;
> generic
> 	Size : Positive;
> 	
> package int_buff is

...

> private
> 
> 	Buff_Indexer : Positive range 1..Size;
> 	
> 	type Int_Buffer is array(1..Size) of Integer;
> 	pragma Pack( Int_Buffer );
> 	type Buff_Ptr is access Int_Buffer;
> 	procedure Free_Buff is new Ada.Unchecked_Deallocation(Int_Buffer, Buff_Ptr);

Why is Free_Buff here rather than in the body?

> 	
> end int_buff;
> 	
> package body int_buff is
> 
> 	procedure Insert(X : in Integer; Y : in out Int_Buffer) is
> 	
> 	begin
> 		Buff_Indexer := X;
> 		Y(Buff_Indexer) := X;
> 		
> 	end Insert;

This is clearly not going to do anything useful.

> 	
> 	procedure Clear_Buff( Y : in out Int_Buffer; Z : in out Buff_Ptr) is
> 		X : Int_Buffer;
> 	-- This procedure obviously needs more work.
> 	-- It's suppose to de-allocate the old buffer and create a new one.
> 	begin
> 		
> 		Free_Buff(Z);
> 		Y := X;
> 		
> 	end Clear_Buff;

There is no relationship between Y and Z.

> 	
> 	function Read_Buff(Y : in Int_Buffer; Read_Length : in Natural; Loc : in Natural) return Buff_Out is
> 	
> 		Ret_Buff : Buff_Out(1..Read_Length);
> 	begin
> 		-- For some reason, the compiler expects Y to be of type Buff_Out.
> 		-- Do I need to use Unchecked_Conversion here?
> 		Ret_Buff := Y(Loc .. Read_Length - 1);
> 	
> 		return Ret_Buff;
> 		
> 	end Read_Buff;

Ret_Buff has type Buff_Out and Y has type Int_Buffer. You can only 
assign a value of type Buff_Out to a variable of type Out_Buff.

What happens if Loc or Read_Length are not in the range of Y?

> 	
> 	function Sum_Buff( Y : in Int_Buffer) return Integer is
> 	
> 		Sum : Integer := 0;
> 		
> 	begin
> 	
> 		for I in Y'range loop
> 		
> 			Sum := Sum + Y(I);
> 			
> 		end loop;
> 		
> 		return Sum;
> 		
> 	end Sum_Buff;

You may be referencing uninitialized components of Y.

> 	
> 	procedure Ditch_Buff(Y : in out Int_Buffer; Z : in out Buff_Ptr) is
> 	
> 	begin
> 	
> 		Free_Buff(Z);
> 		
> 	end Ditch_Buff;

Why must the user supply Y?

> 	
> end int_buff;
> 	
> 	
> Try not to laugh to hard. I'm still a newb. Any pointers would be
> appreciated.

There's no need for access types in what you're doing here. So instead 
of "any pointers" I would recommend "no pointers".

-- 
Jeff Carter
"When danger reared its ugly head, he bravely
turned his tail and fled."
Monty Python and the Holy Grail




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Novice help with types and de-allocation.
  2002-11-18 15:29 ` Ted Dennison
@ 2002-11-18 21:33   ` Stapler
  2002-11-18 23:34   ` Stapler
  1 sibling, 0 replies; 6+ messages in thread
From: Stapler @ 2002-11-18 21:33 UTC (permalink / raw)


On Mon, 18 Nov 2002 10:29:53 -0500, Ted Dennison wrote:
 
> Probably the best way out would be to make Int_Buffer a *subtype* of
> Buff_Out, instead of a type in its own right. If you don't like that
> solution, then the next best thing would be to make the private
> definition of "Int_Buffer" a "new Buff_Out". That would allow you to use
> a simple type conversion.


 I've taken your guys advise, and it works. I'm making it a point to put
a lot more forethought into my type system.

Thanks.

Stapler
"One day at a time and we'll never get there."



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Novice help with types and de-allocation.
  2002-11-18 15:29 ` Ted Dennison
  2002-11-18 21:33   ` Stapler
@ 2002-11-18 23:34   ` Stapler
  1 sibling, 0 replies; 6+ messages in thread
From: Stapler @ 2002-11-18 23:34 UTC (permalink / raw)


On Mon, 18 Nov 2002 10:29:53 -0500, Ted Dennison wrote:

 
> The "some reason" is that the object you are assigning Y into is of that
> type. Unlike some other languages, in Ada you can't assign objects of
> one type into objects of a another type, just because both types have
> similar contents. You defined Int_Buffer and Buff_Out to be different
> types, so they are truly considered unrelated types.


Now that I reflect on it, it only makes sense. With a type declaration
like I was trying to use, what's to stop me from attempting to read past
the end of the Buffer array? If this was C, it would have been all hunky dory,
but the Ada compiler wouldn't even let it past the compile stage.

Now, I dont suppose that after entering my Read funtion I could do
something like the following ...

assuming I've did this in the spec...
subtype Return_Buffer is Buffer;

function Read( Y : in Buffer; Loc, Length : in Natural ) return
Return_Buffer is

	Check : Natural
begin

	Check := Loc + Length;
	if Loc > Buffer'Last then
		raise Exception;
	else if Length > Buffer'range then
		raise Exception;
	else if Check > Buffer'Last then
		raise Exception;
	else
		declare
			subtype Return_Buffer is Buffer(1..Length)
		begin

			-- process data here --

			return Return_Buffer;
		end;
	end if;
end Read;


Now, I'm hoping that this deals with the underyling issue of this
particular type declaration. However I'm still not sure if the compiler
would let that fly. (Gonna try compiling it when I get home from work.)

I suppose another option would be to create specific set of Input
procedures that would check to make sure that the values are always
within the range of the Buffer type.

I've been humbled by GNAT. What's a psuedo-developer to do? Heh.

Stapler



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2002-11-18 23:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-18  6:40 Novice help with types and de-allocation Stapler
2002-11-18 11:05 ` Colin Paul Gloster
2002-11-18 15:29 ` Ted Dennison
2002-11-18 21:33   ` Stapler
2002-11-18 23:34   ` Stapler
2002-11-18 19:06 ` Jeffrey Carter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox