Unchecked_Conversion on different sized types -- problem? 
Author Message
 Unchecked_Conversion on different sized types -- problem?

To do some prototyping I'm extending Michael Feldman's ANSI screen package a
bit, to allow colors, etc, and I ran into a question.  I've enumerated
various attributes and set the enumerations to the corresponding ANSI codes,
and I'm using UC to convert the enumerated types to an Integer, to send via
Text_IO.Put().  I get a warning (GNAT 3.12p) that the types for the UC have
different sizes (not surprising), and I'm wondering if UC always does the
"right" thing here, i.e. zero-extending the smaller enum type when
converting to an Integer.

Here are some (reduced) relevant code bits:

type T is ( BLACK, WHITE );

for T use ( BLACK => 30, WHITE => 37 );

function T_to_int is new Unchecked_Conversion( T, Integer );

T_val : T := BLACK;

Text_IO.Put( Item => T_to_int( T_val )...

So, is T_to_int going to give me 30, as opposed to, say, all 32 bits
starting at the address of T_val?  Can somebody tell me where in the LRM it
talks about this?

(It works "as expected" in this case, but I'm wondering what the rules are)

Also, there's not a simpler way to do this that I'm overlooking, is there?

Mike



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?


Quote:
> To do some prototyping I'm extending Michael Feldman's ANSI screen
package a
> bit, to allow colors, etc, and I ran into a question.  I've enumerated
> various attributes and set the enumerations to the corresponding ANSI
codes,
> and I'm using UC to convert the enumerated types to an Integer, to
send via
> Text_IO.Put().  I get a warning (GNAT 3.12p) that the types for the
UC have
> different sizes (not surprising), and I'm wondering if UC always does
the
> "right" thing here, i.e. zero-extending the smaller enum type when
> converting to an Integer.

 The simple solution to this is to declare a set of integer constants,
not enumerated types. The constants will require no conversions at
all.

Jim Rogers
Colorado Springs, Colorado

Sent via Deja.com http://www.deja.com/
Before you buy.



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?


Adding the following will keep you design and eliminate any potential
errors:

Quote:
> type T is ( BLACK, WHITE );

> for T use ( BLACK => 30, WHITE => 37 );

for T'size use Integer'Size;

Quote:
> function T_to_int is new Unchecked_Conversion( T, Integer );

---
Jeffrey Blatt

Sent via Deja.com http://www.deja.com/
Before you buy.



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Quote:

> The simple solution to this is to declare a set of integer constants,
>not enumerated types. The constants will require no conversions at
>all.

Let me ask this then:  what value is it to be able to specify the
representation of an enumeration?  It seems to me that when you do this you
always want, at some point, to "get at" the value of an enumeration.  Maybe
the crux of my question (or confusion) is that while enumeration
representations are allowed, there doesn't seem to be any clean way to use
them (assuming that anything called "Unchecked_" isn't "clean").

Mike



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Quote:

> type T is ( BLACK, WHITE );

> for T use ( BLACK => 30, WHITE => 37 );

  for T'Size use Integer'Size;

Quote:

> function T_to_int is new Unchecked_Conversion( T, Integer );

> T_val : T := BLACK;

> Text_IO.Put( Item => T_to_int( T_val )...
> Mike

But why use a representation clause for Color?

  type Color is ( Black, White );
--  for Color use ( Black => 30, White => 37 );
  type String_Access is access String;
  Command : array (Color) of String_Access := (new String'("30"), new
String'("37"));
begin
  Text_Io.Put(Command(Color_Val).all);



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Quote:


>> type T is ( BLACK, WHITE );

>> for T use ( BLACK => 30, WHITE => 37 );

>  for T'Size use Integer'Size;

(Slapping head) Yep!

Quote:
>> function T_to_int is new Unchecked_Conversion( T, Integer );

>> T_val : T := BLACK;

>> Text_IO.Put( Item => T_to_int( T_val )...

>> Mike

>But why use a representation clause for Color?

Umm, because that's how I would have done it in C? (I know, that carries a
lot of weight here!)  So, as I asked in another reply, why *ever* use a
representation clause for an enumeration?  To me, it's like my key ring:
I've got a CAR_KEY and a HOUSE_KEY, and at some point I want to actually
pass the key's raw data pattern to the lock, and having the raw data pattern
encoded directly in the enumeration seems cleaner than using a 'case'
statement or a translation array.

Quote:

>  type Color is ( Black, White );
>--  for Color use ( Black => 30, White => 37 );
>  type String_Access is access String;
>  Command : array (Color) of String_Access := (new String'("30"), new
>String'("37"));
>begin
>  Text_Io.Put(Command(Color_Val).all);

This seems "busy", but my biggest objection would be having to enter the
same data twice (and keeping both sets consistent) -- isn't that always a
rich source of errors?

Mike



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Disregard the nonsense I just wrote -- I guess I wasn't paying close
attention to what I was responding to.  My *new* response is that such a
translation array just seems like an extra layer, but maybe it is a better
solution than UC.

Mike

Quote:
>This seems "busy", but my biggest objection would be having to enter the
>same data twice (and keeping both sets consistent) -- isn't that always a
>rich source of errors?

>Mike



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Quote:


>> The simple solution to this is to declare a set of integer constants,
>>not enumerated types. The constants will require no conversions at
>>all.

>Let me ask this then:  what value is it to be able to specify the
>representation of an enumeration?  It seems to me that when you do this you
>always want, at some point, to "get at" the value of an enumeration.  Maybe
>the crux of my question (or confusion) is that while enumeration
>representations are allowed, there doesn't seem to be any clean way to use
>them (assuming that anything called "Unchecked_" isn't "clean").

>Mike

There is nothing "unclean" about unchecked conversions. Use them as needed,
but use them with care. Uncheccked simply means that you will not get a lot
of
help from the compiler in doing the "right thing". If you convert values
that really
do not map well, the compiler may give you a warning, but will not prevent
you.

My solution was another approach that often ends up being simpler. Sometimes
it is even more efficient. I did not mean to imply that the use of
Unchecked_Conversion
was in any way intrinsically bad.  The use of enumeration representation is
often
useful when you need to follow a communication protocol. When you write the
stream representation of the enumeration value you will get close to the
value
you expect. If you use the GNAT compiler you will get the value you expect.

Jim Rogers
Colorado Springs, Colorado



Mon, 01 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?


Quote:
> To do some prototyping I'm extending Michael Feldman's ANSI screen
package a
> bit, to allow colors, etc, and I ran into a question.  I've enumerated
> various attributes and set the enumerations to the corresponding ANSI
codes,
> and I'm using UC to convert the enumerated types to an Integer, to
send via
> Text_IO.Put().  I get a warning (GNAT 3.12p) that the types for the
UC have
> different sizes (not surprising), and I'm wondering if UC always does
the
> "right" thing here, i.e. zero-extending the smaller enum type when
> converting to an Integer.

> Here are some (reduced) relevant code bits:

> type T is ( BLACK, WHITE );

> for T use ( BLACK => 30, WHITE => 37 );

> function T_to_int is new Unchecked_Conversion( T, Integer );

> T_val : T := BLACK;

> Text_IO.Put( Item => T_to_int( T_val )...

Text_Io works for Character and String, but not for Integer, so I'm
curious how you get this to work. Perhaps what you want is a conversion
from T to String, and you're using an intermediate Integer value to
obtain this, in which case a set of String constants seems to be the
easiest way to achieve this. Perhaps internally you would like to
declare (assuming a with and use of Ada.Strings.Unbounded)

type Conversion_List is array (T) of Unbounded_String:

Convert : constant Conversion_List :=
(Black => To_Unbounded_String ("30"), ...);

Text_Io.Put (Convert (Formal_Parameter_Of_Type_T) );

and get rid of the representation clause.

Quote:

> So, is T_to_int going to give me 30, as opposed to, say, all 32 bits
> starting at the address of T_val?  Can somebody tell me where in the
LRM it
> talks about this?

> (It works "as expected" in this case, but I'm wondering what the

rules are)

ARM 13.9(11) says this is implementation defined.

--
Jeff Carter
"Now go away or I shall taunt you a second time."
-- Monty python and the Holy Grail

Sent via Deja.com http://www.deja.com/
Before you buy.



Tue, 02 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?
Unchecked_Conversion gives you a different (type) view of the same object.
So both source and target should be of the same size.

In you case you should have

type T is ( BLACK, WHITE );
for T'Size use 32;                                    -- that was missing in
your code
for T use ( BLACK => 30, WHITE => 37 );

In this case size of T will be equal the size if Integer and your
unchecked coversion will be OK.

Regards,
Vladimir Olensky

Quote:

>To do some prototyping I'm extending Michael Feldman's ANSI screen package
a
>bit, to allow colors, etc, and I ran into a question.  I've enumerated
>various attributes and set the enumerations to the corresponding ANSI
codes,
>and I'm using UC to convert the enumerated types to an Integer, to send via
>Text_IO.Put().  I get a warning (GNAT 3.12p) that the types for the UC have
>different sizes (not surprising), and I'm wondering if UC always does the
>"right" thing here, i.e. zero-extending the smaller enum type when
>converting to an Integer.

>Here are some (reduced) relevant code bits:

>type T is ( BLACK, WHITE );

>for T use ( BLACK => 30, WHITE => 37 );

>function T_to_int is new Unchecked_Conversion( T, Integer );

>T_val : T := BLACK;

>Text_IO.Put( Item => T_to_int( T_val )...

>So, is T_to_int going to give me 30, as opposed to, say, all 32 bits
>starting at the address of T_val?  Can somebody tell me where in the LRM it
>talks about this?

>(It works "as expected" in this case, but I'm wondering what the rules are)

>Also, there's not a simpler way to do this that I'm overlooking, is there?

>Mike



Tue, 02 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Quote:

> But why use a representation clause for Color?

>   type Color is ( Black, White );
> --  for Color use ( Black => 30, White => 37 );

Better yet, why even use an enumeration type at all?

type Color is new Integer;

Black : constant Color := 30;
White : constant Color := 37;

Matt
--
Evolution is as well documented as any phenomenon in science, as
strongly as the earth's revolution around the sun rather than vice
versa.

Stephen Jay Gould, Time, 23 Aug 1999



Tue, 02 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Quote:


> Disregard the nonsense I just wrote -- I guess I wasn't paying close
> attention to what I was responding to.  My *new* response is that such a
> translation array just seems like an extra layer, but maybe it is a better
> solution than UC.

> Mike

> >This seems "busy", but my biggest objection would be having to enter the
> >same data twice (and keeping both sets consistent) -- isn't that always a
> >rich source of errors?

> >Mike

The purpose of the "extra" layer is to improve efficiency
(by avoiding the cost of repeated format conversion).  Note also
that your solution needs better format control to actually
work, because you don't want to send the leading blanks to the
ANSI terminal:

  Put(..., Width => 0);



Tue, 02 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?
I am a little surprised!

As far as i remember UNCHECKED_CONVERSION refused the
unchecked conversion between 2 different sized elements (Ada8x).

Is this new in Ada95?
Is this the new way of "Ada" thinking (to be similar to "C")?

Regards,
Werner

Mike Silva schrieb in Nachricht ...

Quote:
>To do some prototyping I'm extending Michael Feldman's ANSI screen package
a
>bit, to allow colors, etc, and I ran into a question.  I've enumerated
>various attributes and set the enumerations to the corresponding ANSI
codes,
>and I'm using UC to convert the enumerated types to an Integer, to send via
>Text_IO.Put().  I get a warning (GNAT 3.12p) that the types for the UC have
>different sizes (not surprising), and I'm wondering if UC always does the
>"right" thing here, i.e. zero-extending the smaller enum type when
>converting to an Integer.

>Here are some (reduced) relevant code bits:

>type T is ( BLACK, WHITE );

>for T use ( BLACK => 30, WHITE => 37 );

>function T_to_int is new Unchecked_Conversion( T, Integer );

>T_val : T := BLACK;

>Text_IO.Put( Item => T_to_int( T_val )...

>So, is T_to_int going to give me 30, as opposed to, say, all 32 bits
>starting at the address of T_val?  Can somebody tell me where in the LRM it
>talks about this?

>(It works "as expected" in this case, but I'm wondering what the rules are)

>Also, there's not a simpler way to do this that I'm overlooking, is there?

>Mike



Tue, 02 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?


Quote:
> I am a little surprised!

> As far as i remember UNCHECKED_CONVERSION refused the
> unchecked conversion between 2 different sized elements (Ada8x).

Depends on the compiler really. I have seen warnings and I have seen
errors in Ada83 in the case of 2 different sizes. I would think that if
the abstraction is "unchecked conversion" then checking size would be a
violation of that abstraction (albeit helpful).
---
Jeffrey Blatt

Sent via Deja.com http://www.deja.com/
Before you buy.



Tue, 02 Jul 2002 03:00:00 GMT  
 Unchecked_Conversion on different sized types -- problem?

Quote:

>...
>The purpose of the "extra" layer is to improve efficiency
>(by avoiding the cost of repeated format conversion).  Note also
>that your solution needs better format control to actually
>work, because you don't want to send the leading blanks to the
>ANSI terminal:

>  Put(..., Width => 0);

That's a very good point -- since I'm really only after a T-to-string
representation, there's no reason to have an intermediate integer in this
case.  Forest for the trees...

Mike



Tue, 02 Jul 2002 03:00:00 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Warning: types for unchecked conversion have different sizes

2. Different window sizes in different sceen resolutions

3. Generic type & Unchecked_Conversion

4. problem: resolution functions and different types

5. problems with toplevel on different types of displays

6. How to make a function work with different type and kind type argument

7. Constructing a modular type based on the size of an arbitrary type

8. Preview/Printed Page size is different thatn Report Definition

9. Window Size on Different Monitors.

10. BUTTONS--Graphic--different shapes and sizes

11. VO: Browser size different from system to system?

12. Font size varies in different Windows versions.

 

 
Powered by phpBB® Forum Software