comp.lang.ada
 help / color / mirror / Atom feed
* Access Type
@ 2010-12-24 16:36 kug1977
  2010-12-24 17:30 ` Robert A Duff
  0 siblings, 1 reply; 14+ messages in thread
From: kug1977 @ 2010-12-24 16:36 UTC (permalink / raw)


Hi,

this drives me crazy, because it makes me think that I don't get this
access concept in Ada ... hope someone can help here.

1. I've a Ada-function which use a string for calling a service, say
"open". This strings have to be LATIN1, so I've a type for this

       type t_OFW_Service_Name is array (Positive range <>) of
Character;

2. The calling Ada-function have to use a pointer to this array, to
call this function, so I use

       type t_OFW_Service_Name_Access is access t_OFW_Service_Name;

3. As this strings are all constant over the live-time of the
programm, I want them declare as a private constant like this

        open_SERVICE_NAME : aliased t_OFW_Service_Name (1 .. 5) :=
"open" & Ada.Characters.Latin_1.NUL;

4. In my Ada-function, I use record-set like this

     type Ci_Args is record
         Service                 : t_OFW_Service_Name_Access;
         Num_Of_Args        : Cell;
         Num_Of_Ret_Vals : Cell;
         Boot_Specifiers     : System.Address;
      end record;
      Arg   : Ci_Args;

    which I fill like this

    Arg.Service         := boot_Service_Name'Access;

Compilation failed with the following messages:

- object subtype must statically match designated subtype
- warning: aliased object has explicit bounds
- warning: declare without bounds (and with explicit initialization)
- warning: for use with unconstrained access

Brings me to the following questions.
- what mean this warnings and errors?
- how can I point to a constant string.
- Is there a easy to read tutorial about Pointers in Ada?

Thanks for your help.
kug1977








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

* Re: Access Type
  2010-12-24 16:36 Access Type kug1977
@ 2010-12-24 17:30 ` Robert A Duff
  2010-12-24 20:59   ` kug1977
  0 siblings, 1 reply; 14+ messages in thread
From: Robert A Duff @ 2010-12-24 17:30 UTC (permalink / raw)


kug1977 <kug1977@web.de> writes:

> this drives me crazy, because it makes me think that I don't get this
> access concept in Ada ... hope someone can help here.
>
> 1. I've a Ada-function which use a string for calling a service, say
> "open". This strings have to be LATIN1, so I've a type for this
>
>        type t_OFW_Service_Name is array (Positive range <>) of
> Character;

You could use String here.  Or if you prefer a new type,
you could say:

    type t_OFW_Service_Name is new String;

> 2. The calling Ada-function have to use a pointer to this array, to
> call this function, so I use
>
>        type t_OFW_Service_Name_Access is access t_OFW_Service_Name;
>
> 3. As this strings are all constant over the live-time of the
> programm, I want them declare as a private constant like this
>
>         open_SERVICE_NAME : aliased t_OFW_Service_Name (1 .. 5) :=
> "open" & Ada.Characters.Latin_1.NUL;

Leave out the (1..5), and let the compiler count
how long it is.  You're asking for a bug here --
you might count wrong.

And you forgot "constant", both on the access type,
and on the object.

> 4. In my Ada-function, I use record-set like this
>
>      type Ci_Args is record
>          Service                 : t_OFW_Service_Name_Access;
>          Num_Of_Args        : Cell;
>          Num_Of_Ret_Vals : Cell;
>          Boot_Specifiers     : System.Address;
>       end record;
>       Arg   : Ci_Args;
>
>     which I fill like this
>
>     Arg.Service         := boot_Service_Name'Access;

You might want to use an aggregate to fill it in.
That way, the compiler will make sure you didn't
miss any components.

> Compilation failed with the following messages:
>
> - object subtype must statically match designated subtype
> - warning: aliased object has explicit bounds
> - warning: declare without bounds (and with explicit initialization)
> - warning: for use with unconstrained access
>
> Brings me to the following questions.
> - what mean this warnings and errors?

Your type says "range <>", so it's unconstrained.
Your object says (1..5), so it has an explicit constraint.
You are not allowed to take 'Access of an object with
an explicit constraint, and returning an access to
unconstrained array.  Some people think that's a language
design flaw.  They are probably right.  You are not the
first person to be surprised and confused by this rule.

Anyway, the workaround is to remove the constraint,
which isn't needed anyway.  The compiler said
"declare without bounds", and that's what it means.
All array objects are constrained in Ada,
if not explicitly, then by the initial value.

Another thing you need to look out for:  If you are
passing this data to some other language (like C),
you need to make sure the representations match.
See pragma Import and Convention.  By default, GNAT
will represent an access-to-String as a fat pointer,
which won't match the C side.

- Bob



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

* Re: Access Type
  2010-12-24 17:30 ` Robert A Duff
@ 2010-12-24 20:59   ` kug1977
  2010-12-24 22:06     ` Simon Wright
  2010-12-27  1:50     ` Ludovic Brenta
  0 siblings, 2 replies; 14+ messages in thread
From: kug1977 @ 2010-12-24 20:59 UTC (permalink / raw)


> > this drives me crazy, because it makes me think that I don't get this
> > access concept in Ada ... hope someone can help here.
>
> Leave out the (1..5), and let the compiler count
> how long it is.  You're asking for a bug here --
> you might count wrong.

Good advise. It's a better job for the compile to count. Tend to be
inattentively in programming. That's why I like Ada most of the
time. ;-)

> And you forgot "constant", both on the access type, and on the object.

  type t_OFW_Service_Name is array (Positive range <>) of Character;
  type t_OFW_Service_Name_Access is access constant
t_OFW_Service_Name;
  open_SERVICE_NAME : aliased constant t_OFW_Service_Name := "open" &
Ada.Characters.Latin_1.NUL;

Now, the compiler stops teasing me. Need the array of Character for a
while, but will change it later to an new type of t_ofw_byte.

> > 4. In my Ada-function, I use record-set like this
>
> >      type Ci_Args is record
> >          Service                 : t_OFW_Service_Name_Access;
> >       end record;
> >       Arg   : Ci_Args;
>
> >     which I fill like this
>
> >     Arg.Service         := boot_Service_Name'Access;
>
> You might want to use an aggregate to fill it in.
> That way, the compiler will make sure you didn't
> miss any components.

One more thing learned today. I was looking for a construct makes sure
the compiler gets me, if I forget a component. So, that's the way.

> Your type says "range <>", so it's unconstrained.
> Your object says (1..5), so it has an explicit constraint.
> You are not allowed to take 'Access of an object with
> an explicit constraint, and returning an access to
> unconstrained array.  Some people think that's a language
> design flaw.  They are probably right.  You are not the
> first person to be surprised and confused by this rule.
>
> Anyway, the workaround is to remove the constraint,
> which isn't needed anyway.  The compiler said
> "declare without bounds", and that's what it means.
> All array objects are constrained in Ada,
> if not explicitly, then by the initial value.

I was thinking, I've to bound the unconstrained array, but never get
it, that the initial value will bound it. Pointers are an obstacle for
most newbies and it takes some time to understand the principle in the
first time. Now I've to learn it the Ada-way ...

> Another thing you need to look out for:  If you are
> passing this data to some other language (like C),
> you need to make sure the representations match.
> See pragma Import and Convention.  By default, GNAT
> will represent an access-to-String as a fat pointer,
> which won't match the C side.

I will pass this to Openfirmware which is like a 32-bit C. So I use

     type Ci_Args is record
         Service         : t_OFW_Service_Name_Access;
         ...
      end record;
      pragma Convention (C, Ci_Args); -- represent CI_Args as a C-
style struct

      Arg   : Ci_Args;

I hope this will prevent the compiler from using something else than a
32-bit Address
for the Service entry.

Thanks Bob for helping me out. Have nice holidays.

- kug1977



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

* Re: Access Type
  2010-12-24 20:59   ` kug1977
@ 2010-12-24 22:06     ` Simon Wright
  2010-12-27  1:50     ` Ludovic Brenta
  1 sibling, 0 replies; 14+ messages in thread
From: Simon Wright @ 2010-12-24 22:06 UTC (permalink / raw)


kug1977 <kug1977@web.de> writes:

> I will pass this to Openfirmware which is like a 32-bit C. So I use
>
>      type Ci_Args is record
>          Service         : t_OFW_Service_Name_Access;
>          ...
>       end record;
>       pragma Convention (C, Ci_Args); -- represent CI_Args as a C-
> style struct
>
>       Arg   : Ci_Args;
>
> I hope this will prevent the compiler from using something else than a
> 32-bit Address
> for the Service entry.

I think you should also add

   pragma Convention (C, t_OFW_Service_Name_Access);



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

* Re: Access Type
  2010-12-24 20:59   ` kug1977
  2010-12-24 22:06     ` Simon Wright
@ 2010-12-27  1:50     ` Ludovic Brenta
  2010-12-27 12:29       ` Simon Wright
  1 sibling, 1 reply; 14+ messages in thread
From: Ludovic Brenta @ 2010-12-27  1:50 UTC (permalink / raw)


kug1977 writes on comp.lang.ada:
> Pointers are an obstacle for most newbies and it takes some time to
> understand the principle in the first time. Now I've to learn it the
> Ada-way ...

The Ada way is not to use pointers at all... you can pass a string of
characters to a C function without pointers, like this:

with Interfaces.C;
procedure P is
   procedure C_Function (String : in Interfaces.C.char_array);
   pragma Import (C, C_Function, "foo");
begin
   C_Function (Interfaces.C.To_C ("Ada string"));
end P;

This will correctly append a null character to "Ada string" and pass the
address of the result to the C_Function.

Another idea: if you have a fixed number of service names, maybe you
should encapsulate them into a package of their own and only expose an
enumerated type and a getter function, like so:

with Interfaces.C;
package Services is

   type Service is (Open, ...);

   function Name (S : in Service) return Interfaces.C.char_array;

end Services;

with Interfaces.C.Strings;
package body Services is

   type String_Access is access String;

   All_Services : constant array (Service) of Interfaces.C.Strings.chars_ptr :=
     (Open => Interfaces.C.Strings.New_String ("open"),
      ...
     );

   function Name (S : in Service) return Interfaces.C.char_array is
   begin
      return Interfaces.C.Strings.Value (All_Services (S));
   end Name;

end Services;

HTH

-- 
Ludovic Brenta.



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

* Re: Access Type
  2010-12-27  1:50     ` Ludovic Brenta
@ 2010-12-27 12:29       ` Simon Wright
  2010-12-27 17:53         ` Ludovic Brenta
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Wright @ 2010-12-27 12:29 UTC (permalink / raw)


Ludovic Brenta <ludovic@ludovic-brenta.org> writes:

>    C_Function (Interfaces.C.To_C ("Ada string"));

Is there a potential memory leak lurking here?



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

* Re: Access Type
  2010-12-27 12:29       ` Simon Wright
@ 2010-12-27 17:53         ` Ludovic Brenta
  2010-12-27 18:15           ` Simon Wright
  0 siblings, 1 reply; 14+ messages in thread
From: Ludovic Brenta @ 2010-12-27 17:53 UTC (permalink / raw)


Simon Wright writes on comp.lang.ada:
> Ludovic Brenta <ludovic@ludovic-brenta.org> writes:
>
>>    C_Function (Interfaces.C.To_C ("Ada string"));
>
> Is there a potential memory leak lurking here?

No, the char_array is on the stack and passed as a char* to the C
function.

-- 
Ludovic Brenta.



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

* Re: Access Type
  2010-12-27 17:53         ` Ludovic Brenta
@ 2010-12-27 18:15           ` Simon Wright
  2010-12-27 20:03             ` Pascal Obry
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Wright @ 2010-12-27 18:15 UTC (permalink / raw)


Ludovic Brenta <ludovic@ludovic-brenta.org> writes:

> Simon Wright writes on comp.lang.ada:
>> Ludovic Brenta <ludovic@ludovic-brenta.org> writes:
>>
>>>    C_Function (Interfaces.C.To_C ("Ada string"));
>>
>> Is there a potential memory leak lurking here?
>
> No, the char_array is on the stack and passed as a char* to the C
> function.

I guess I was thinking of Interfaces.C.Strings.chars_ptr.



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

* Re: Access Type
  2010-12-27 18:15           ` Simon Wright
@ 2010-12-27 20:03             ` Pascal Obry
  2010-12-28 20:08               ` kug1977
  0 siblings, 1 reply; 14+ messages in thread
From: Pascal Obry @ 2010-12-27 20:03 UTC (permalink / raw)
  To: Simon Wright

Le 27/12/2010 19:15, Simon Wright a �crit :
> I guess I was thinking of Interfaces.C.Strings.chars_ptr.

No, there is no memory leak. To_C returns a standard array, there is no
dynamic allocation in sight.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|    http://www.obry.net  -  http://v2p.fr.eu.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver keys.gnupg.net --recv-key F949BD3B




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

* Re: Access Type
  2010-12-27 20:03             ` Pascal Obry
@ 2010-12-28 20:08               ` kug1977
  2010-12-28 23:52                 ` Simon Wright
  0 siblings, 1 reply; 14+ messages in thread
From: kug1977 @ 2010-12-28 20:08 UTC (permalink / raw)


Hi,

after solving the first problem with access, I'm running into the next
one. SORRY, I'm a beginner in Ada and stupid question pave my way of
learning.

For my programm I need a type like System.Address but with a
definitive size of 32-bits. So I've create one

   type t_OFW_vAddress is mod t_Cell_Size;
	for t_OFW_vAddress'Size use 32 ;
	pragma Assert (t_OFW_vAddress'Size = 32);
	pragma Assert (t_OFW_vAddress'Alignment = 4) ;

   OFW_Null_vAddress : constant t_OFW_vAddress := 0;

I've now a record I will pass to a C-like function looks like this:

	type Chain_CI_Args is record
         ...
		Another_Clients_Entry     : t_OFW_vAddress := OFW_Null_vAddress;
		Another_Clients_Arguments : t_OFW_vAddress := OFW_Null_vAddress;
         ...
	end record;
	pragma Convention (C, Chain_CI_Args);

'Another_Clients_Entry' will hold the address of a procedure I defined
by this:

	type Client_Entry is access procedure;
	pragma Convention (C, Client_Entry);

and
'Another_Clients_Arguments' will be an array

        type t_OFW_Buffer     is array (Positive range <>) of
t_OFW_Byte;

In my procedure I fill this record by

   procedure Chain
     (Virtual_Address           : in t_OFW_vAddress;
      Free_Number_Of_Bytes      : in Cell;
      Another_Clients_Entry     : in Client_Entry;
      Another_Clients_Arguments : in t_OFW_Buffer)
	is
      Arg : Chain_CI_Args :=
               (...
		Another_Clients_Entry            =>
t_OFW_vAddress'(Another_Clients_Entry), -- ???
		Another_Clients_Arguments        => Another_Clients_Arguments
(Another_Clients_Arguments'First)'Address, -- ??
		...
               );
   ...

I'm sure you'll see by first looking, that this doesn't work. Maybe
some conversion is needed, but I don't know how.

King regards, kug1977

PS: I know, that this isn't something a beginner in Ada should start
with, but I like to finnish porting this from C to Ada.



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

* Re: Access Type
  2010-12-28 20:08               ` kug1977
@ 2010-12-28 23:52                 ` Simon Wright
  2010-12-29  8:46                   ` kug1977
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Wright @ 2010-12-28 23:52 UTC (permalink / raw)


kug1977 <kug1977@web.de> writes:

> For my programm I need a type like System.Address but with a
> definitive size of 32-bits. So I've create one
>
>    type t_OFW_vAddress is mod t_Cell_Size;
> 	for t_OFW_vAddress'Size use 32 ;
> 	pragma Assert (t_OFW_vAddress'Size = 32);
> 	pragma Assert (t_OFW_vAddress'Alignment = 4) ;
>
>    OFW_Null_vAddress : constant t_OFW_vAddress := 0;

You shouldn't need the first Assert, because if the compiler can't
honour the "for t_OFW_vAddress'Size use 32;" it should refuse the
compilation.

Similarly, replace the second Assert by "for t_OFW_vAddress'Alignment
use 4;".

But .. are you using GNAT? because, being built on GCC, its natural
tendency is to use the same representations as C would. In any case, I
think you're making things more complicated than they need to be.

Assuming that both your Ada and C compilers are 32-bit (you have big
problems ahead if they are different!), type System.Address is going to
be 32-bits and 4-byte aligned anyway.

So why not just use System.Address? (I guess in that case it would make
sense to assert that System.Address'Size is 32, etc. Though the main
thing is to be sure that your compilers and system libraries agree!)

> I've now a record I will pass to a C-like function looks like this:
>
> 	type Chain_CI_Args is record
>          ...
> 		Another_Clients_Entry     : t_OFW_vAddress := OFW_Null_vAddress;
> 		Another_Clients_Arguments : t_OFW_vAddress := OFW_Null_vAddress;
>          ...
> 	end record;
> 	pragma Convention (C, Chain_CI_Args);
>
> 'Another_Clients_Entry' will hold the address of a procedure I defined
> by this:
>
> 	type Client_Entry is access procedure;
> 	pragma Convention (C, Client_Entry);
>
> and
> 'Another_Clients_Arguments' will be an array
>
>         type t_OFW_Buffer     is array (Positive range <>) of
> t_OFW_Byte;

If "type Client_Entry is" just "access procedure", how come it has
arguments?

> In my procedure I fill this record by
>
>    procedure Chain
>      (Virtual_Address           : in t_OFW_vAddress;
>       Free_Number_Of_Bytes      : in Cell;
>       Another_Clients_Entry     : in Client_Entry;
>       Another_Clients_Arguments : in t_OFW_Buffer)
> 	is
>       Arg : Chain_CI_Args :=
>                (...
> 		Another_Clients_Entry            =>
> t_OFW_vAddress'(Another_Clients_Entry), -- ???
> 		Another_Clients_Arguments        => Another_Clients_Arguments
> (Another_Clients_Arguments'First)'Address, -- ??
> 		...
>                );

I would define the Entry item by just

   type Chain_CI_Args is record
      ...
      Another_Clients_Entry : Client_Entry;

The Arguments part is a bit more tricky. It's a bad idea to try passing
indefinite items like a t_OFW_Buffer via a single thin pointer; GNAT
does it using a two-component (fat) pointer. You'll need either to pass
another element saying how many bytes there are in the Arguments, or to
have it terminated somehow.

I'd then try

   type Chain_CI_Args is record
      ...
      Another_Clients_Entry : Client_Entry;
      Another_Clients_Arguments : System.Address;
      Another_Clients_Args_Len : Integer;
      ...

so you'd write

      ...
      Another_Clients_Entry => Another_Clients_Entry,
      Another_Clients_Arguments => 
         Another_Clients_Arguments
      (Another_Clients_Arguments'First)'Address,
      Another_Clients_Args_Len => Another_Clients_Arguments'Length,
      ...

which does assume that the elements of t_OFW_Buffer are contiguous and
that Integer is OK to be passed in a C struct (both pretty good guesses
for any normal compiler, I'd say).

> PS: I know, that this isn't something a beginner in Ada should start
> with, but I like to finnish porting this from C to Ada.

You start from wherever you happen to be!


Hope that helps; my laptop's battery is running out & it's bedtime!



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

* Re: Access Type
  2010-12-28 23:52                 ` Simon Wright
@ 2010-12-29  8:46                   ` kug1977
  2010-12-29 15:18                     ` Simon Wright
  0 siblings, 1 reply; 14+ messages in thread
From: kug1977 @ 2010-12-29  8:46 UTC (permalink / raw)


On 29 Dez., 00:52, Simon Wright <si...@pushface.org> wrote:
> kug1977 <kug1...@web.de> writes:
> > For my programm I need a type like System.Address but with a
> > definitive size of 32-bits. So I've create one
>
> >    type t_OFW_vAddress is mod t_Cell_Size;
> >    for t_OFW_vAddress'Size use 32 ;
> >    pragma Assert (t_OFW_vAddress'Size = 32);
> >    pragma Assert (t_OFW_vAddress'Alignment = 4) ;
>
> >    OFW_Null_vAddress : constant t_OFW_vAddress := 0;
>
> You shouldn't need the first Assert, because if the compiler can't
> honour the "for t_OFW_vAddress'Size use 32;" it should refuse the
> compilation.
>
> Similarly, replace the second Assert by "for t_OFW_vAddress'Alignment
> use 4;".
>
> But .. are you using GNAT? because, being built on GCC, its natural
> tendency is to use the same representations as C would. In any case, I
> think you're making things more complicated than they need to be.
>
> Assuming that both your Ada and C compilers are 32-bit (you have big
> problems ahead if they are different!), type System.Address is going to
> be 32-bits and 4-byte aligned anyway.
>
> So why not just use System.Address? (I guess in that case it would make
> sense to assert that System.Address'Size is 32, etc. Though the main
> thing is to be sure that your compilers and system libraries agree!)

I've to give you more information about the project. The thing will be
a bootloader for IEEE1275 aka Open Firmware (OFW) (used in Apple Mac
PPC's). So, my Ada programm is using the OFW client interface which is
defined in the standard usign 32-bit wide Cells on 4-Byte boundaries
some hold natural numbers, others pointer to X but all are 32-bit. So,
the damn thing are not allowed to use 64-Bit wide System.Address.

So, you suggest to use an System.Address, an assert for the 32-bit and
compiler options to make sure every thing is 32-bit? Sounds easy.

> If "type Client_Entry is" just "access procedure", how come it has
> arguments?

OFW need a pointer to the procedure and a pointer to an array which
holds the arguments. OFW will call the procedure with the arguments.
But, you are right, if I have a procedure X without arguments defined,
the call sequence will be without space for that pointer.

> I would define the Entry item by just
>
>    type Chain_CI_Args is record
>       ...
>       Another_Clients_Entry : Client_Entry;
>
> The Arguments part is a bit more tricky. It's a bad idea to try passing
> indefinite items like a t_OFW_Buffer via a single thin pointer; GNAT
> does it using a two-component (fat) pointer. You'll need either to pass
> another element saying how many bytes there are in the Arguments, or to
> have it terminated somehow.

There's a length field in the structure I pass to OFW. SO that thing
is handled.

>
> I'd then try
>
>    type Chain_CI_Args is record
>       ...
>       Another_Clients_Entry : Client_Entry;
>       Another_Clients_Arguments : System.Address;
>       Another_Clients_Args_Len : Integer;
>       ...
>
> so you'd write
>
>       ...
>       Another_Clients_Entry => Another_Clients_Entry,
>       Another_Clients_Arguments =>
>          Another_Clients_Arguments
>       (Another_Clients_Arguments'First)'Address,
>       Another_Clients_Args_Len => Another_Clients_Arguments'Length,
>       ...
>
> which does assume that the elements of t_OFW_Buffer are contiguous and
> that Integer is OK to be passed in a C struct (both pretty good guesses
> for any normal compiler, I'd say).
>
> > PS: I know, that this isn't something a beginner in Ada should start
> > with, but I like to finnish porting this from C to Ada.
>
> You start from wherever you happen to be!
>
> Hope that helps; my laptop's battery is running out & it's bedtime!

Simon, I really appreciate your help and hope you don't stop. Learned
a lot in the last days. I start learning Ada with to many knowledge in
low level programming (M68k und PPC ASM) but less knowledge in high
level languages. So, most of the time I've a good understanding what I
want in the end, but get confused by my own demand on programming type
save.

King regards, kug1977



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

* Re: Access Type
  2010-12-29  8:46                   ` kug1977
@ 2010-12-29 15:18                     ` Simon Wright
  2010-12-29 15:27                       ` Ludovic Brenta
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Wright @ 2010-12-29 15:18 UTC (permalink / raw)


kug1977 <kug1977@web.de> writes:

> On 29 Dez., 00:52, Simon Wright <si...@pushface.org> wrote:
>> kug1977 <kug1...@web.de> writes:
>> > For my programm I need a type like System.Address but with a
>> > definitive size of 32-bits. So I've create one
>>
>> >    type t_OFW_vAddress is mod t_Cell_Size;
>> >    for t_OFW_vAddress'Size use 32 ;
>> >    pragma Assert (t_OFW_vAddress'Size = 32);
>> >    pragma Assert (t_OFW_vAddress'Alignment = 4) ;
>>
>> >    OFW_Null_vAddress : constant t_OFW_vAddress := 0;
>>
>> You shouldn't need the first Assert, because if the compiler can't
>> honour the "for t_OFW_vAddress'Size use 32;" it should refuse the
>> compilation.
>>
>> Similarly, replace the second Assert by "for t_OFW_vAddress'Alignment
>> use 4;".
>>
>> But .. are you using GNAT? because, being built on GCC, its natural
>> tendency is to use the same representations as C would. In any case, I
>> think you're making things more complicated than they need to be.
>>
>> Assuming that both your Ada and C compilers are 32-bit (you have big
>> problems ahead if they are different!), type System.Address is going to
>> be 32-bits and 4-byte aligned anyway.
>>
>> So why not just use System.Address? (I guess in that case it would make
>> sense to assert that System.Address'Size is 32, etc. Though the main
>> thing is to be sure that your compilers and system libraries agree!)
>
> I've to give you more information about the project. The thing will be
> a bootloader for IEEE1275 aka Open Firmware (OFW) (used in Apple Mac
> PPC's). So, my Ada programm is using the OFW client interface which is
> defined in the standard usign 32-bit wide Cells on 4-Byte boundaries
> some hold natural numbers, others pointer to X but all are 32-bit. So,
> the damn thing are not allowed to use 64-Bit wide System.Address.
>
> So, you suggest to use an System.Address, an assert for the 32-bit and
> compiler options to make sure every thing is 32-bit? Sounds easy.

Broadly, yes.

It's possible to have one compiler generate both 32- and 64-bit code;
for an Intel target you can use -m32/-m64 (for example) provided the
compiler was built with that ability. Whenever I've built a compiler
it's been for one architecture only; if for no other reason than that
the Ada build process in GCC doesn't support multilibs. (Well, that's
what the documentation seemed to be saying ...)

I don't remember whether GNAT for PowerPC supports 64-bit, don't think
so???

It sounds as though your argument list ought to be an array of ints (or
Integers), not bytes?

One thing you'll need to be careful of: some Ada features (eg exception
handling, functions returing indefinite objects, tasking ...) rely on
runtime support that may not be available, or may not be properly
initialized, in the OFW environment. I'm not familiar with how to get
over this sort of problem.

> Simon, I really appreciate your help and hope you don't stop.

You're welcome.



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

* Re: Access Type
  2010-12-29 15:18                     ` Simon Wright
@ 2010-12-29 15:27                       ` Ludovic Brenta
  0 siblings, 0 replies; 14+ messages in thread
From: Ludovic Brenta @ 2010-12-29 15:27 UTC (permalink / raw)


Simon Wright writes:
> It's possible to have one compiler generate both 32- and 64-bit code;
> for an Intel target you can use -m32/-m64 (for example) provided the
> compiler was built with that ability. Whenever I've built a compiler
> it's been for one architecture only; if for no other reason than that
> the Ada build process in GCC doesn't support multilibs. (Well, that's
> what the documentation seemed to be saying ...)

Multilib support for libgnat was introduced in GCC 4.4.  This means the
ability to build both a 32-bit and a 64-bit version of libgnat and to
link the program against either.

Multiarch support was introduced earlier than that.  This means support
for -m32/-m64 and the ability to emit either 32- or 64-bit object code.

> I don't remember whether GNAT for PowerPC supports 64-bit, don't think
> so???

Yes, it does.

> It sounds as though your argument list ought to be an array of ints
> (or Integers), not bytes?

I'd rather call them "words".

> One thing you'll need to be careful of: some Ada features (eg
> exception handling, functions returing indefinite objects, tasking
> ...) rely on runtime support that may not be available, or may not be
> properly initialized, in the OFW environment. I'm not familiar with
> how to get over this sort of problem.

Right.  Since a bootloader runs without an underlying operating system,
I'd suggest adding the following configuration pragma to one of the
source files:

pragma No_Run_Time;

Then all you need is a 32-bit compiler.  Beware that memory management
will no longer be available (i.e. "new" and Unchecked_Deallocation
probably won't work).

If the host machine and OS are 64-bit then you need a multiarch compiler
(supporting 32-bit code as the target) but you do not need multilib.

-- 
Ludovic Brenta.



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

end of thread, other threads:[~2010-12-29 15:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-24 16:36 Access Type kug1977
2010-12-24 17:30 ` Robert A Duff
2010-12-24 20:59   ` kug1977
2010-12-24 22:06     ` Simon Wright
2010-12-27  1:50     ` Ludovic Brenta
2010-12-27 12:29       ` Simon Wright
2010-12-27 17:53         ` Ludovic Brenta
2010-12-27 18:15           ` Simon Wright
2010-12-27 20:03             ` Pascal Obry
2010-12-28 20:08               ` kug1977
2010-12-28 23:52                 ` Simon Wright
2010-12-29  8:46                   ` kug1977
2010-12-29 15:18                     ` Simon Wright
2010-12-29 15:27                       ` Ludovic Brenta

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