comp.lang.ada
 help / color / mirror / Atom feed
* Static expressions and using 'Size
@ 1996-03-22  0:00 Geert Bosch
  1996-03-22  0:00 ` Norman H. Cohen
  1996-03-22  0:00 ` Robert A Duff
  0 siblings, 2 replies; 3+ messages in thread
From: Geert Bosch @ 1996-03-22  0:00 UTC (permalink / raw)


Currently I'm writing a GC compatible allocator for GNAT and I found
some Ada-related problems for which I didn't find a nice work-around
yet. Maybe somebody can give some hints.

One part of the allocator (which is working fine BTW) is the Page_Manager
which maintains some administration about the virtual memory that has
been allocated, is behind write-barriers etc. 

Because of some comments from others I try to make the code suitable
for systems that use other page-sizes than 4 kB, 32-bit addresses etc.
One of the problems is that the sizes of some data-structures depend
on sizes of others.

Because of portability, readability and safety I'd like not to calculate
all record-sizes etc. myself, but have the compiler do that for me. The
problem is however that expressions involving the 'Size attribute are
not static and for that reason cannot be used in constants.

This is annoying because I'd rather write
   Page_Info_Bytes     : constant := Page_Info'Size / Byte'Size;
than
   Page_Info_Bytes     : Positive := Page_Info'Size / Byte'Size;
because the value of Page_Info_Bytes is known at compile-time and won't
change during execution of the program (I hope ;-)

Things become worse when I want declare types that depend on these
'constants'. Would I really have to explicitly specify all record-sizes
and stuff myself, with all problems when size of data-structures change?
I *must* overlook something, but I can't think of it. If I indeed need
to specify everything myself, I think this is contrary to the 
'Ada-philosophy'

Thanks in advance for any reactions!

   Geert

--- Here comes some of the relevant Ada-code --------------------------

package Page_Manager is

   -- (Edited, stripped down version)

   -- All XXX_Size identifiers denote sizes in bytes rather than bits

   VM_Size              : constant := 2 ** 29;  -- 512 MB Virtual Memory
   Page_Size            : constant := 2 ** 12;  -- 4 kB VM pages
   
   type Page_Nr is range 0.. VM_Size / Page_Size - 1; -- 2 ** 17 pages

   -- Every VM page has a Page_Info record
   
   type Page_Info is record
      ...
   end record;
   
   -- Here are subprograms for Set_Page_Info, Get_Page_Info etc.
   
end Page_Manager;

package body Page_Manager is

   -- This is illegal Ada'95 code !!!
   Page_Info_Size          : constant := Page_Info'Size / Byte'Size;
   Page_Map_Size           : constant := Page_Map'Size / Byte'Size;
   
   Map_Entries_Per_VM_Page : constant := Page_Size / Page_Info_Size;
   Map_Pages               : constant := Page_Nr'Last / Map_Entries_Per_VM_Page;
   
   type Map_Page_Nr is range 0..Map_Pages - 1;

   -- Rest deleted

end Page_Manager;

-- 
E-Mail: geert@sun3.iaf.nl *** Real programers don't document their code: if ***
 Phone: +31-53-4303054    ** it was hard to write, it should be hard to read **





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

* Re: Static expressions and using 'Size
  1996-03-22  0:00 Static expressions and using 'Size Geert Bosch
  1996-03-22  0:00 ` Norman H. Cohen
@ 1996-03-22  0:00 ` Robert A Duff
  1 sibling, 0 replies; 3+ messages in thread
From: Robert A Duff @ 1996-03-22  0:00 UTC (permalink / raw)


In article <4isu7e$4d0@fozzie.sun3.iaf.nl>,
Geert Bosch <geert@fozzie.sun3.iaf.nl> wrote:
>Because of portability, readability and safety I'd like not to calculate
>all record-sizes etc. myself, but have the compiler do that for me. The
>problem is however that expressions involving the 'Size attribute are
>not static and for that reason cannot be used in constants.

You are confusing "named numbers" and "constants".  The former need to
be static; the latter do not.  (S'Size *is* static, by the way, if S is
a static (scalar) subtype.)  Even if an expression is non-static, a good
compiler will calculate it at compile time in *some* cases.

>This is annoying because I'd rather write
>   Page_Info_Bytes     : constant := Page_Info'Size / Byte'Size;
>than
>   Page_Info_Bytes     : Positive := Page_Info'Size / Byte'Size;

You can do this:

   Page_Info_Bytes : constant Positive := Page_Info'Size / Byte'Size;
                     ^^^^^^^^

Better yet, I suggest you define a type like Size_In_Bytes, different
from Positive, and use that.

>   -- All XXX_Size identifiers denote sizes in bytes rather than bits

I suggest you use the type system to reflect the above comment.

>   VM_Size              : constant := 2 ** 29;  -- 512 MB Virtual Memory
>   Page_Size            : constant := 2 ** 12;  -- 4 kB VM pages

And make these be of type Size_In_Bytes, too.

>   type Page_Nr is range 0.. VM_Size / Page_Size - 1; -- 2 ** 17 pages

I suggest you delete the comment "-- 2 ** 17 pages", because it is a
maintenance problem.  The whole point of saying "VM_Size / Page_Size" is
that if VM_Size or Page_Size changes, you *don't* have to change
Page_Nr.  But because of that comment, you *do* have to change the
declaration of Page_Nr.  Or, you might forget, and leave a wrong
comment, which is always worse than no comment.  (It's not so bad in
*this* case, because the related code is nearby, but still...)

- Bob




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

* Re: Static expressions and using 'Size
  1996-03-22  0:00 Static expressions and using 'Size Geert Bosch
@ 1996-03-22  0:00 ` Norman H. Cohen
  1996-03-22  0:00 ` Robert A Duff
  1 sibling, 0 replies; 3+ messages in thread
From: Norman H. Cohen @ 1996-03-22  0:00 UTC (permalink / raw)


In article <4isu7e$4d0@fozzie.sun3.iaf.nl>, geert@fozzie.sun3.iaf.nl
(Geert Bosch) writes: 

|> Currently I'm writing a GC compatible allocator for GNAT
...

And I hope that in short order we'll see the garbage collector with which
it's compatible! ;-)

|> Because of portability, readability and safety I'd like not to calculate
|> all record-sizes etc. myself, but have the compiler do that for me. The
|> problem is however that expressions involving the 'Size attribute are
|> not static and for that reason cannot be used in constants.
|>
|> This is annoying because I'd rather write
|>    Page_Info_Bytes     : constant := Page_Info'Size / Byte'Size;
|> than
|>    Page_Info_Bytes     : Positive := Page_Info'Size / Byte'Size;
|> because the value of Page_Info_Bytes is known at compile-time and won't
|> change during execution of the program (I hope ;-)

The first declaration is not for a constant, but for a named number.
Nonstatic values can be used to initialize constants: 

   Page_Info_Bytes : constant Positive := Page_Info'Size / Byte'Size;
                     ^^^^^^^^^^^^^^^^^

Even though Page_Info'Size is not static from a language lawyer's point
of view (because Page_Info is a record type rather than a scalar type),
it is possible in principle for a compiler to evaluate it at compile time
if the record components all belong to static subtypes.  Some compilers
may do this.  Of course if this declaration resides in a library package,
it will be elaborated once, so this should not be a concern.

|> Things become worse when I want declare types that depend on these
|> 'constants'.

Note that the bounds in an array-type declaration need not be static,
so something like

   type Page_Info_As_Bytes is array (0 .. Page_Info_Bytes-1) of Byte;
   pragma Pack (Page_Info_As_Bytes);

would be legal.  (On the other hand,

   for Page_Info_As_Bytes'Size use Page_Info'Size;

or

   for Page_Info_As_Bytes'Size use Page_Info_Bytes * Byte'Size;

would not be.) :-(

--
Norman H. Cohen    ncohen@watson.ibm.com




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

end of thread, other threads:[~1996-03-22  0:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-03-22  0:00 Static expressions and using 'Size Geert Bosch
1996-03-22  0:00 ` Norman H. Cohen
1996-03-22  0:00 ` Robert A Duff

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