comp.lang.ada
 help / color / mirror / Atom feed
* data types & efficiency
@ 2004-03-05  8:02 Davide
  2004-03-05  9:23 ` Vinzent 'Gadget' Hoefler
  2004-03-05 10:22 ` Jean-Pierre Rosen
  0 siblings, 2 replies; 11+ messages in thread
From: Davide @ 2004-03-05  8:02 UTC (permalink / raw)


hello everybody,

speaking in general, if I have a *XX-bit* architecture for which I'm
developing software in Ada, and I need to declare some *scalar* (not records
nor arrays etc.) variable eg. integer: what should be better to do:

1) always declare that variable as the *smallest* data type that will hold
the highest value of its possible range (example: if it can assume values
from 0 to 150 then declare it as an 8-bit integer);

2) tend to declare the variable as the machine "native" data type,  i.e.
XX-bit represented.

I think considerations should be made about efficiency and memory occupation
*but* (maybe) taking into account memory alignment (that could vanify
considerations made at point 1...maybe).

Waiting for your opinions,

thanks in advance.






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

* Re: data types & efficiency
  2004-03-05  8:02 data types & efficiency Davide
@ 2004-03-05  9:23 ` Vinzent 'Gadget' Hoefler
  2004-03-05  9:57   ` Davide
  2004-03-05 10:22 ` Jean-Pierre Rosen
  1 sibling, 1 reply; 11+ messages in thread
From: Vinzent 'Gadget' Hoefler @ 2004-03-05  9:23 UTC (permalink / raw)


Davide wrote:

>speaking in general, if I have a *XX-bit* architecture for which I'm
>developing software in Ada, and I need to declare some *scalar* (not records
>nor arrays etc.) variable eg. integer: what should be better to do:
>
>1) always declare that variable as the *smallest* data type that will hold
>the highest value of its possible range (example: if it can assume values
>from 0 to 150 then declare it as an 8-bit integer);
>
>2) tend to declare the variable as the machine "native" data type,  i.e.
>XX-bit represented.

3) Declare the type by specifying its range and let the compiler
figure out what could be more efficient on the hardware.


Vinzent.



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

* Re: data types & efficiency
  2004-03-05  9:23 ` Vinzent 'Gadget' Hoefler
@ 2004-03-05  9:57   ` Davide
  2004-03-05 12:00     ` Vinzent 'Gadget' Hoefler
  0 siblings, 1 reply; 11+ messages in thread
From: Davide @ 2004-03-05  9:57 UTC (permalink / raw)



"Vinzent 'Gadget' Hoefler" wrote:

>3) Declare the type by specifying its range and let the compiler
>figure out what could be more efficient on the hardware.

unfortunately I *must* specify the 'SIZE of each data type or subtype.





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

* Re: data types & efficiency
  2004-03-05  8:02 data types & efficiency Davide
  2004-03-05  9:23 ` Vinzent 'Gadget' Hoefler
@ 2004-03-05 10:22 ` Jean-Pierre Rosen
  1 sibling, 0 replies; 11+ messages in thread
From: Jean-Pierre Rosen @ 2004-03-05 10:22 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 772 bytes --]


"Davide" <ppp@ppp.it> a �crit dans le message de news:c29c7h$hbq$1@e3k.asi.ansaldo.it...
> 1) always declare that variable as the *smallest* data type that will hold
> the highest value of its possible range (example: if it can assume values
> from 0 to 150 then declare it as an 8-bit integer);
>
Note the following very useful feature, if you want a type that includes *at least* a certain range:
   type Required is range 0..150;
   subtype Extended is Required'Base;

Extended will provide you with the underlying base type, which should be the minimal hardware efficient type that includes your
requirements.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr





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

* Re: data types & efficiency
  2004-03-05  9:57   ` Davide
@ 2004-03-05 12:00     ` Vinzent 'Gadget' Hoefler
  2004-03-05 15:54       ` Davide
  0 siblings, 1 reply; 11+ messages in thread
From: Vinzent 'Gadget' Hoefler @ 2004-03-05 12:00 UTC (permalink / raw)


Davide wrote:

>"Vinzent 'Gadget' Hoefler" wrote:
>
>>3) Declare the type by specifying its range and let the compiler
>>figure out what could be more efficient on the hardware.
>
>unfortunately I *must* specify the 'SIZE of each data type or subtype.

Why? If you're interfacing to some external (hardware) interface you
have to specify a certain size independent from the
target-architecture, but if you don't need this I don't see why you
should *have* to specify some size at all.


Vinzent.



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

* Re: data types & efficiency
  2004-03-05 12:00     ` Vinzent 'Gadget' Hoefler
@ 2004-03-05 15:54       ` Davide
  2004-03-05 20:53         ` tmoran
  2004-03-08  8:58         ` Vinzent 'Gadget' Hoefler
  0 siblings, 2 replies; 11+ messages in thread
From: Davide @ 2004-03-05 15:54 UTC (permalink / raw)



>"Vinzent 'Gadget' Hoefler" wrote:

>Why? If you're interfacing to some external (hardware) interface you
>have to specify a certain size independent from the
>target-architecture, but if you don't need this I don't see why you
>should *have* to specify some size at all.

Well, requirements are to "redefine" the predefined types as Boolean,
Integerer, etc...
to enforce the indepence from compiler in terms of their internal
representation.
So I will define for example:

type UNSIGNED_INT_32_TYPE is range 0..(2**32)-1:
for  UNSIGNED_INT_32_TYPE'SIZE use 32;

to be used instead of the predefined Integer type.

One thing that I don't know is if I define:

subtype SMALLER_INT_TYPE is UNSIGNED_INT_32_TYPE range 0..150;

then, generally, the compiler can still optimize the representation in spite
of  the clause:
for  UNSIGNED_INT_32_TYPE'SIZE use 32;

?
What do you know about this?

Thanks.

P.S.:

My compiler's (Adamulti) manual is not clear about this. I made an
experiment with GNAT and it seems that it represents
SMALLER_INT_TYPE  as a byte. So this compiler still optimizes the subtype.
In this case your answer:

>3) Declare the type by specifying its range and let the compiler
>figure out what could be more efficient on the hardware.

would make sense also for my particular case.

I hope I've been clear...sorry for my bad english...and also please consider
I'm just beginning with Ada development.








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

* Re: data types & efficiency
  2004-03-05 15:54       ` Davide
@ 2004-03-05 20:53         ` tmoran
  2004-03-08  9:28           ` Davide
  2004-03-08  8:58         ` Vinzent 'Gadget' Hoefler
  1 sibling, 1 reply; 11+ messages in thread
From: tmoran @ 2004-03-05 20:53 UTC (permalink / raw)


> to enforce the indepence from compiler in terms of their internal
> representation.
> So I will define for example:
>
> type UNSIGNED_INT_32_TYPE is range 0..(2**32)-1:
> for  UNSIGNED_INT_32_TYPE'SIZE use 32;
>
> to be used instead of the predefined Integer type.
  Usually people want their program to *run* the same regardless of
which compiler compiled it.  You seem to want its data area to be
the same size, the maximum size any compiler might use.  Why is that?
  Thus a program to play cards might define
    type Suite is (Clubs, Diamonds, Hearts, Spades);
A memory optimizing compiler on a suitably addressable architecture
might use 2 bits.  Another compiler on another machine might use 32.
Why do you require that they both use 32 bits to represent the four
possible values?
  For Integer, don't use the predefined type and assume it's, say, 32
bits.  Instead declare your own
  type home_thermostat_F_settings is range 55.. 90;
  type person_numbers is range 0 .. 50_000_000_000;
and let different compilers on different architectures use different
storage arrangements - your data values will never fall outside those
ranges so any extra bits are immaterial to the correct running of
your program.



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

* Re: data types & efficiency
  2004-03-05 15:54       ` Davide
  2004-03-05 20:53         ` tmoran
@ 2004-03-08  8:58         ` Vinzent 'Gadget' Hoefler
  2004-03-08 10:53           ` Davide
  2004-03-08 15:27           ` Robert I. Eachus
  1 sibling, 2 replies; 11+ messages in thread
From: Vinzent 'Gadget' Hoefler @ 2004-03-08  8:58 UTC (permalink / raw)


Davide wrote:

>Well, requirements are to "redefine" the predefined types as Boolean,
>Integerer, etc...
>to enforce the indepence from compiler in terms of their internal
>representation.

Hmm, strange requirements. Sounds a little bit like someone just wants
<stdint.h> in Ada. ;)

>So I will define for example:
>
>type UNSIGNED_INT_32_TYPE is range 0..(2**32)-1:
>for  UNSIGNED_INT_32_TYPE'SIZE use 32;
>
>to be used instead of the predefined Integer type.

Ok, that's clear.

>One thing that I don't know is if I define:
>
>subtype SMALLER_INT_TYPE is UNSIGNED_INT_32_TYPE range 0..150;
>
>then, generally, the compiler can still optimize the representation in spite
>of  the clause:
>for  UNSIGNED_INT_32_TYPE'SIZE use 32;

No, it can't (at least I think so). It can do this if you derive a
"new" type from it, but not for a subtype. A subtype always has the
same representation as its base type.

Hmm, at least that's *my* interpretation of the RM, so it can be
totally wrong. :)

>My compiler's (Adamulti) manual is not clear about this. I made an
>experiment with GNAT and it seems that it represents
>SMALLER_INT_TYPE  as a byte.

Hmm. No, not exactly:

|with Ada.Text_IO;
|
|procedure t is
|   type Unsigned_32 is range 0 .. 2**32 - 1;
|   for Unsigned_32'Size use 32;
|
|   subtype Smaller_Int is Unsigned_32 range 0 .. 63;
|   -- for Smaller_Int'Size use 32;
|   x : Unsigned_32;
|   y : Smaller_Int;
|   z : Smaller_Int;
|   for z'Size use 8;
|begin
|   Ada.Text_IO.Put_Line (Integer'Image (Unsigned_32'Size));
|   Ada.Text_IO.Put_Line (Integer'Image (Smaller_Int'Size));
|
|   Ada.Text_IO.Put_Line (Integer'Image (x'Size));
|   Ada.Text_IO.Put_Line (Integer'Image (y'Size));
|   Ada.Text_IO.Put_Line (Integer'Image (z'Size));
|end t;

Output is:

| 32
| 6
| 32
| 32
| 8

So, yes, for the subtype it "optimizes" the size (it simply spits out
the minimum size needed to represent the specified range) ->
Smaller_Int'Size gives 6 here.

But for an actual object of that subtype it uses that of the base
type, of course (y'Size gives 32, too) - unless you specify a
different size for the object itself (z'Size gives 8).

To be honest, my understanding of RM 13.3(39-57) is not very good. So
it is perhaps better to delegate this question to the real language
lawyers here in c.l.a. :)

>So this compiler still optimizes the subtype.
>In this case your answer:
>
>>3) Declare the type by specifying its range and let the compiler
>>figure out what could be more efficient on the hardware.
>
>would make sense also for my particular case.

Well, it seems you can't define a representation for a subtype, only
for an object of that subtype.

Given that, your "requirements" don't make much sense too me, because
even if you define a representation for each of the "redefined" types,
you still can change for each object declared, if you need to do so.

And BTW, "independence from the compiler in terms of internal
representation" really sounds quite unportable to me. For instance, if
you try to do that on a 24-bit DSP, there is no 32-bit representation
available at all, simply because the target-architecture can't do that
(it must be either 24 or 48 bits). But the possibility of defining an
Integer that can represent 2**32 different values is still there.

So IMO doing such things would break more that it could possibly fix.


Vinzent.



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

* Re: data types & efficiency
  2004-03-05 20:53         ` tmoran
@ 2004-03-08  9:28           ` Davide
  0 siblings, 0 replies; 11+ messages in thread
From: Davide @ 2004-03-08  9:28 UTC (permalink / raw)


thank you everybody,

all your answers was really helpful. I think I had some confusion in my
mind, but I come from C++ and Ada typing philosophy is completely different,
so I apologize for my trivial observations and hope my next posts will be
more interesting...

thank you again.





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

* Re: data types & efficiency
  2004-03-08  8:58         ` Vinzent 'Gadget' Hoefler
@ 2004-03-08 10:53           ` Davide
  2004-03-08 15:27           ` Robert I. Eachus
  1 sibling, 0 replies; 11+ messages in thread
From: Davide @ 2004-03-08 10:53 UTC (permalink / raw)



Vinzent 'Gadget' Hoefler wrote:

>Hmm, strange requirements. Sounds a little bit like someone just wants
>stdint.h> in Ada. ;)

Okay, I thanks all the newsgroup in a previous post (including also you, of
course) before receiving this post.
And I found this post very interesting.
Yes, for what concerns C heritage, this depends on me, I'm a "C++"er and Ada
typing philosophy is ...ehm..just a little bit different...

>So, yes, for the subtype it "optimizes" the size (it simply spits out
>the minimum size needed to represent the specified range) ->
>Smaller_Int'Size gives 6 here.
>
>But for an actual object of that subtype it uses that of the base
>type, of course (y'Size gives 32, too) - unless you specify a
>different size for the object itself (z'Size gives 8).

Thanks a lot for this contribution. My experiment was misleading.

>To be honest, my understanding of RM 13.3(39-57) is not very good. So
>it is perhaps better to delegate this question to the real language
>lawyers here in c.l.a. :)

Now I'm curious.
I hope some language lawyers will answer.

>Given that, your "requirements" don't make much sense too me, because
>even if you define a representation for each of the "redefined" types,
>you still can change for each object declared, if you need to do so.
>
>And BTW, "independence from the compiler in terms of internal
>representation" really sounds quite unportable to me. For instance, if
>you try to do that on a 24-bit DSP, there is no 32-bit representation
>available at all, simply because the target-architecture can't do that
>(it must be either 24 or 48 bits). But the possibility of defining an
>Integer that can represent 2**32 different values is still there.

>So IMO doing such things would break more that it could possibly fix.

I must apologize. Your reasoning is perfect. I misunderstood the
requirements. As you said, forcing the representation makes sense only if
the interested type has to map some data on some external hardware. For the
other types the only right thing to do is to let the compiler be free to
optimize. Indeed my requirements meant to say that, in general, I shall not
use predefined LONG_INTEGER, SHORT_INTEGER,... types but I shall specify the
range explicitely. The range, not the size. This is to avoid different
*ranges* associated to the same predefined type for different compilers.
This is my new understanding of requirements, that were not written so
clear...unfortunately :((

Anyway from this discussion I learned a lot of things, and I thank you.

Davide







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

* Re: data types & efficiency
  2004-03-08  8:58         ` Vinzent 'Gadget' Hoefler
  2004-03-08 10:53           ` Davide
@ 2004-03-08 15:27           ` Robert I. Eachus
  1 sibling, 0 replies; 11+ messages in thread
From: Robert I. Eachus @ 2004-03-08 15:27 UTC (permalink / raw)


Vinzent 'Gadget' Hoefler wrote:

> No, it can't (at least I think so). It can do this if you derive a
> "new" type from it, but not for a subtype. A subtype always has the
> same representation as its base type.
> 
> Hmm, at least that's *my* interpretation of the RM, so it can be
> totally wrong. :)

Correct, your interpretation is totally wrong. ;-)  You can specify 
different sizes for both objects RM 13.3(39..43) and subtypes RM 
13.3(44..56).  But notice the note at RM 13.3(58): "A component_clause 
or Component_Size clause can override a specified Size. A pragma Pack 
cannot."

In other words, a 'Size clause for a subtype can be overridden.

> So, yes, for the subtype it "optimizes" the size (it simply spits out
> the minimum size needed to represent the specified range) ->
> Smaller_Int'Size gives 6 here.

Correct, RM 13.3(55) recommends that if the size of the subtype is NOT 
specified, S'Size should return the minimum size required for an 
unbiased representation.  Note that an implementation will often use a 
larger size for objects of the subtype whose size is unspecified, and 
may allow a smaller size to be used in records (fierce packing).

I think GNAT has another attribute that returns the size that will be 
used for standalone object of the type.

> But for an actual object of that subtype it uses that of the base
> type, of course (y'Size gives 32, too) - unless you specify a
> different size for the object itself (z'Size gives 8).
> 
> To be honest, my understanding of RM 13.3(39-57) is not very good. So
> it is perhaps better to delegate this question to the real language
> lawyers here in c.l.a. :)

This is/was not a good time for that, there was an ARG meeting this weekend.

> Well, it seems you can't define a representation for a subtype, only
> for an object of that subtype.

No, see above.

> Given that, your "requirements" don't make much sense too me, because
> even if you define a representation for each of the "redefined" types,
> you still can change for each object declared, if you need to do so.
> 
> And BTW, "independence from the compiler in terms of internal
> representation" really sounds quite unportable to me. For instance, if
> you try to do that on a 24-bit DSP, there is no 32-bit representation
> available at all, simply because the target-architecture can't do that
> (it must be either 24 or 48 bits). But the possibility of defining an
> Integer that can represent 2**32 different values is still there.
> 
> So IMO doing such things would break more that it could possibly fix.

If what you want is for the compiler to reject programs when it can't 
implement the required sizes, well that is what you asked for.  If you 
want to force overflow when an intermediate value is out of bounds, this 
doesn't work.  What you need to do in that case is either specific 
assignments, or better, subtype conversions where you want to be sure 
that an intermediate is a value of the subtype.  Converting to a subtype 
does a range check, RM 4.6(51), that cannot be optimized away by RM 
11.6(5). (Explicit conversions are not operations...)

However, note that no check is performed for a subtype conversion of an 
out parameter RM 4.6(62).  This is to prevent the passing of an 
uninitiallized value as an out parameter from raising Constraint_Error. 
  (When you think about it, this should be a non-issue, the check is 
only omitted for values that can't be used anyway.  However, there are 
some cases in generics where the effect can be surprising.)

In practice what most people who are trying to write portable software 
do is to carefully specify (sub)types that are used for input or output, 
and let the compiler use the most efficient types internally.  And yes, 
this sometimes means that the (sub)types used for I/O are different from 
those used internally. This way, if there is a difficult or expensive 
conversion, it only occurs as part of the I/O.

-- 
                                           Robert I. Eachus

"The only thing necessary for the triumph of evil is for good men to do 
nothing." --Edmund Burke




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

end of thread, other threads:[~2004-03-08 15:27 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-05  8:02 data types & efficiency Davide
2004-03-05  9:23 ` Vinzent 'Gadget' Hoefler
2004-03-05  9:57   ` Davide
2004-03-05 12:00     ` Vinzent 'Gadget' Hoefler
2004-03-05 15:54       ` Davide
2004-03-05 20:53         ` tmoran
2004-03-08  9:28           ` Davide
2004-03-08  8:58         ` Vinzent 'Gadget' Hoefler
2004-03-08 10:53           ` Davide
2004-03-08 15:27           ` Robert I. Eachus
2004-03-05 10:22 ` Jean-Pierre Rosen

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