comp.lang.ada
 help / color / mirror / Atom feed
* 'Size hack for enumerated types
@ 2014-07-05 20:32 Victor Porton
  2014-07-05 21:47 ` Simon Wright
  2014-07-06 13:21 ` sbelmont700
  0 siblings, 2 replies; 26+ messages in thread
From: Victor Porton @ 2014-07-05 20:32 UTC (permalink / raw)


I have written the following code:

   type Flag_Type is (Libxml_Error_Save,
                      Libxml_Structured_Error_Save,
		      URI_Interning,
                      WWW_Skip_Init_Finish);
   for Flag_Type'Size use Interfaces.C.int'Size; -- hack
   for Flag_Type use (Libxml_Error_Save => 1,
                      Libxml_Structured_Error_Save => 2,
		      URI_Interning => 3,
                      WWW_Skip_Init_Finish => 4);

The code above is intended to be able to pass flag variables into certain C 
functions (accepting enum types).

But it seems that the above code has the drawback of storing in 4 or 8 bytes 
instead of one byte.

What is a better way to do this?

-- 
Victor Porton - http://portonvictor.org

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

* Re: 'Size hack for enumerated types
  2014-07-05 20:32 'Size hack for enumerated types Victor Porton
@ 2014-07-05 21:47 ` Simon Wright
  2014-07-05 22:11   ` Victor Porton
  2014-07-06 13:21 ` sbelmont700
  1 sibling, 1 reply; 26+ messages in thread
From: Simon Wright @ 2014-07-05 21:47 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> I have written the following code:
>
>    type Flag_Type is (Libxml_Error_Save,
>                       Libxml_Structured_Error_Save,
> 		      URI_Interning,
>                       WWW_Skip_Init_Finish);
>    for Flag_Type'Size use Interfaces.C.int'Size; -- hack
>    for Flag_Type use (Libxml_Error_Save => 1,
>                       Libxml_Structured_Error_Save => 2,
> 		      URI_Interning => 3,
>                       WWW_Skip_Init_Finish => 4);
>
> The code above is intended to be able to pass flag variables into
> certain C functions (accepting enum types).
>
> But it seems that the above code has the drawback of storing in 4 or 8
> bytes instead of one byte.

Well, you specified 'Size to be (almost certainly) 32 bits, so it's not
surprising that that's what the compiler does.

But there's a difference between the minimum number of bits required to
hold a *value* of the type (3 in your example) and the number of bits
the compiler uses when holding an *object* of the type, which will be
what is most efficient. GNAT has 'Object_Size.

> What is a better way to do this?

Just use convention C:

   type Flag_Type is (Libxml_Error_Save,
                      Libxml_Structured_Error_Save,
                      URI_Interning,
                      WWW_Skip_Init_Finish) with Convention => C;

and let the compiler worry about sizes.

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

* Re: 'Size hack for enumerated types
  2014-07-05 21:47 ` Simon Wright
@ 2014-07-05 22:11   ` Victor Porton
  2014-07-05 22:18     ` Victor Porton
  2014-07-06  7:22     ` Simon Wright
  0 siblings, 2 replies; 26+ messages in thread
From: Victor Porton @ 2014-07-05 22:11 UTC (permalink / raw)


Simon Wright wrote:
>> What is a better way to do this?
> 
> Just use convention C:
> 
>    type Flag_Type is (Libxml_Error_Save,
>                       Libxml_Structured_Error_Save,
>                       URI_Interning,
>                       WWW_Skip_Init_Finish) with Convention => C;

Your code does not allow to assign particular numbers to the enumeration 
literals. :-(

> and let the compiler worry about sizes.

-- 
Victor Porton - http://portonvictor.org

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

* Re: 'Size hack for enumerated types
  2014-07-05 22:11   ` Victor Porton
@ 2014-07-05 22:18     ` Victor Porton
  2014-07-05 22:23       ` Victor Porton
  2014-07-06 20:59       ` Simon Wright
  2014-07-06  7:22     ` Simon Wright
  1 sibling, 2 replies; 26+ messages in thread
From: Victor Porton @ 2014-07-05 22:18 UTC (permalink / raw)


I tried to implement it in a memory savvy way. But GNAT does not compile it. 
It would be good if a future version of Ada supported it.

-- rds.ads
package RDF is
end RDF;

-- rdf-auxilary.ads
with Interfaces.C;

package RDF.Auxilary is

   generic
      type Enum_Type is range <>;
   package Convert_Enum is
      function To_C(Argument: Enum_Type) return Interfaces.C.int;
      function From_C(Argument: Interfaces.C.int) return Enum_Type;
   end;

end RDF.Auxilary;

-- rdf-auxilary.adb
with Ada.Unchecked_Conversion;

package body RDF.Auxilary is

   package body Convert_Enum is
      
      type Small is mod 2**(Enum_Type'Size);
      
      function To_C_Internal is
        new Ada.Unchecked_Conversion (Source => Enum_Type, Target => Small);

      function From_C_Internal is
        new Ada.Unchecked_Conversion (Source => Small, Target => Enum_Type);
      
      function To_C(Argument: Enum_Type) return Interfaces.C.int is
      begin
         return Interfaces.C.int(To_C_Internal(Argument));
      end;
            
      function From_C(Argument: Interfaces.C.int) return Enum_Type is
      begin
         return From_C_Internal(Small(Argument));
      end;

   end;

end RDF.Auxilary;

gnatmake -q -c -gnatc -u -P/home/porton/Projects/redland-
bindings/ada/test.gpr -XRUNTIME=full -XMODE=Install rdf-auxilary.adb
rdf-auxilary.adb:7:25: non-static expression used for modular type bound
rdf-auxilary.adb:7:38: size attribute is only static for static scalar type 
(RM 4.9(7,8))
gnatmake: "/home/porton/Projects/redland-bindings/ada/src/rdf-auxilary.adb" 
compilation error


-- 
Victor Porton - http://portonvictor.org

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

* Re: 'Size hack for enumerated types
  2014-07-05 22:18     ` Victor Porton
@ 2014-07-05 22:23       ` Victor Porton
  2014-07-06 16:25         ` Victor Porton
  2014-07-06 20:59       ` Simon Wright
  1 sibling, 1 reply; 26+ messages in thread
From: Victor Porton @ 2014-07-05 22:23 UTC (permalink / raw)


Victor Porton wrote:

> I tried to implement it in a memory savvy way. But GNAT does not compile
> it. It would be good if a future version of Ada supported it.
> 
> -- rds.ads
> package RDF is
> end RDF;
> 
> -- rdf-auxilary.ads
> with Interfaces.C;
> 
> package RDF.Auxilary is
> 
>    generic
>       type Enum_Type is range <>;
>    package Convert_Enum is
>       function To_C(Argument: Enum_Type) return Interfaces.C.int;
>       function From_C(Argument: Interfaces.C.int) return Enum_Type;
>    end;
> 
> end RDF.Auxilary;
> 
> -- rdf-auxilary.adb
> with Ada.Unchecked_Conversion;
> 
> package body RDF.Auxilary is
> 
>    package body Convert_Enum is
>       
>       type Small is mod 2**(Enum_Type'Size);

Sorry, need also multiply with byte size in bits. BTW, how to get it?

>       function To_C_Internal is
>         new Ada.Unchecked_Conversion (Source => Enum_Type, Target =>
>         Small);
> 
>       function From_C_Internal is
>         new Ada.Unchecked_Conversion (Source => Small, Target =>
>         Enum_Type);
>       
>       function To_C(Argument: Enum_Type) return Interfaces.C.int is
>       begin
>          return Interfaces.C.int(To_C_Internal(Argument));
>       end;
>             
>       function From_C(Argument: Interfaces.C.int) return Enum_Type is
>       begin
>          return From_C_Internal(Small(Argument));
>       end;
> 
>    end;
> 
> end RDF.Auxilary;
> 
> gnatmake -q -c -gnatc -u -P/home/porton/Projects/redland-
> bindings/ada/test.gpr -XRUNTIME=full -XMODE=Install rdf-auxilary.adb
> rdf-auxilary.adb:7:25: non-static expression used for modular type bound
> rdf-auxilary.adb:7:38: size attribute is only static for static scalar
> type (RM 4.9(7,8))
> gnatmake:
> "/home/porton/Projects/redland-bindings/ada/src/rdf-auxilary.adb"
> compilation error
> 
> 
-- 
Victor Porton - http://portonvictor.org


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

* Re: 'Size hack for enumerated types
  2014-07-05 22:11   ` Victor Porton
  2014-07-05 22:18     ` Victor Porton
@ 2014-07-06  7:22     ` Simon Wright
  1 sibling, 0 replies; 26+ messages in thread
From: Simon Wright @ 2014-07-06  7:22 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> Simon Wright wrote:
>>> What is a better way to do this?
>> 
>> Just use convention C:
>> 
>>    type Flag_Type is (Libxml_Error_Save,
>>                       Libxml_Structured_Error_Save,
>>                       URI_Interning,
>>                       WWW_Skip_Init_Finish) with Convention => C;
>
> Your code does not allow to assign particular numbers to the
> enumeration literals. :-(

I just didn't put that in since you already had it.

   with Ada.Text_IO; use Ada.Text_IO;
   procedure Enums is
      type Flag_Type is (Libxml_Error_Save,
                         Libxml_Structured_Error_Save,
                         URI_Interning,
                         WWW_Skip_Init_Finish) with Convention => C;
      for Flag_Type use (Libxml_Error_Save => 1,
                         Libxml_Structured_Error_Save => 2,
                         URI_Interning => 3,
                         WWW_Skip_Init_Finish => 4);
      F : Flag_Type;
      I : Integer with Address => F'Address, Import => Ada;
   begin
      Put_Line ("'Size:       " & Flag_Type'Size'Img);
      Put_Line ("'Object_Size:" & Flag_Type'Object_Size'Img);
      Put_Line ("F'Size:      " & F'Size'Img);
      F := URI_Interning;
      Put_Line ("F:            " & F'Img);
      Put_Line ("I:           " & I'Img);
   end Enums;

(sorry about the hidden unchecked conversion) resulting in

   $ ./enums 
   'Size:        3
   'Object_Size: 32
   F'Size:       32
   F:            URI_INTERNING
   I:            3



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

* Re: 'Size hack for enumerated types
  2014-07-05 20:32 'Size hack for enumerated types Victor Porton
  2014-07-05 21:47 ` Simon Wright
@ 2014-07-06 13:21 ` sbelmont700
  2014-07-06 16:16   ` Victor Porton
  1 sibling, 1 reply; 26+ messages in thread
From: sbelmont700 @ 2014-07-06 13:21 UTC (permalink / raw)


On Saturday, July 5, 2014 4:32:10 PM UTC-4, Victor Porton wrote:
> 
> What is a better way to do this?
>

I prefer something along these lines:

type T is (x, y, z);

K : constant array (T) of Interfaces.C.int :=
  (x => 1,
   y => 2,
   z => 3);

C_Function(arg => K(x));


You lose a little by having to declare the array (assuming it cannot be optimized away), but can have any size you desire for T, plus you get to explicitly specify how the enum maps.

-sb



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

* Re: 'Size hack for enumerated types
  2014-07-06 13:21 ` sbelmont700
@ 2014-07-06 16:16   ` Victor Porton
  2014-07-06 17:52     ` sbelmont700
  0 siblings, 1 reply; 26+ messages in thread
From: Victor Porton @ 2014-07-06 16:16 UTC (permalink / raw)


sbelmont700@gmail.com wrote:

> On Saturday, July 5, 2014 4:32:10 PM UTC-4, Victor Porton wrote:
>> 
>> What is a better way to do this?
>>
> 
> I prefer something along these lines:
> 
> type T is (x, y, z);
> 
> K : constant array (T) of Interfaces.C.int :=
>   (x => 1,
>    y => 2,
>    z => 3);
> 
> C_Function(arg => K(x));
> 
> 
> You lose a little by having to declare the array (assuming it cannot be
> optimized away), but can have any size you desire for T, plus you get to
> explicitly specify how the enum maps.

Your way does not work backward (K^{-1}).

-- 
Victor Porton - http://portonvictor.org


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

* Re: 'Size hack for enumerated types
  2014-07-05 22:23       ` Victor Porton
@ 2014-07-06 16:25         ` Victor Porton
  0 siblings, 0 replies; 26+ messages in thread
From: Victor Porton @ 2014-07-06 16:25 UTC (permalink / raw)


Victor Porton wrote:

> Victor Porton wrote:
> 
>> I tried to implement it in a memory savvy way. But GNAT does not compile
>> it. It would be good if a future version of Ada supported it.
>> 
>> -- rds.ads
>> package RDF is
>> end RDF;
>> 
>> -- rdf-auxilary.ads
>> with Interfaces.C;
>> 
>> package RDF.Auxilary is
>> 
>>    generic
>>       type Enum_Type is range <>;
>>    package Convert_Enum is
>>       function To_C(Argument: Enum_Type) return Interfaces.C.int;
>>       function From_C(Argument: Interfaces.C.int) return Enum_Type;
>>    end;
>> 
>> end RDF.Auxilary;
>> 
>> -- rdf-auxilary.adb
>> with Ada.Unchecked_Conversion;
>> 
>> package body RDF.Auxilary is
>> 
>>    package body Convert_Enum is
>>       
>>       type Small is mod 2**(Enum_Type'Size);
> 
> Sorry, need also multiply with byte size in bits. BTW, how to get it?
> 
>>       function To_C_Internal is
>>         new Ada.Unchecked_Conversion (Source => Enum_Type, Target =>
>>         Small);
>> 
>>       function From_C_Internal is
>>         new Ada.Unchecked_Conversion (Source => Small, Target =>
>>         Enum_Type);
>>       
>>       function To_C(Argument: Enum_Type) return Interfaces.C.int is
>>       begin
>>          return Interfaces.C.int(To_C_Internal(Argument));
>>       end;
>>             
>>       function From_C(Argument: Interfaces.C.int) return Enum_Type is
>>       begin
>>          return From_C_Internal(Small(Argument));
>>       end;
>> 
>>    end;
>> 
>> end RDF.Auxilary;
>> 
>> gnatmake -q -c -gnatc -u -P/home/porton/Projects/redland-
>> bindings/ada/test.gpr -XRUNTIME=full -XMODE=Install rdf-auxilary.adb
>> rdf-auxilary.adb:7:25: non-static expression used for modular type bound
>> rdf-auxilary.adb:7:38: size attribute is only static for static scalar
>> type (RM 4.9(7,8))
>> gnatmake:
>> "/home/porton/Projects/redland-bindings/ada/src/rdf-auxilary.adb"
>> compilation error

I think this can be made manually (without generics) (explicitly declaring a 
`Small` type for every enumeration in question), but I better do it with 
'Size hack, not spending time on manually programming what should be doable 
with generics.

-- 
Victor Porton - http://portonvictor.org

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

* Re: 'Size hack for enumerated types
  2014-07-06 16:16   ` Victor Porton
@ 2014-07-06 17:52     ` sbelmont700
  0 siblings, 0 replies; 26+ messages in thread
From: sbelmont700 @ 2014-07-06 17:52 UTC (permalink / raw)


On Sunday, July 6, 2014 12:16:00 PM UTC-4, Victor Porton wrote:
> 
> Your way does not work backward (K^{-1}).
> 

Sure it can, contingent on the C enum not being declared in any sort of inane manner:

subtype E is Interfaces.C.int range 1 .. 3;

K_Inv : constant array (E) of T :=
 (1 => x;
  2 => y;
  3 => z);

Of course, any number of stupid programmer tricks could have been done on the other end to put gaps in the values, have multiple elements with the same value, or even make them implementation-defined non-integer numbers, in which case all bets are off.  Though all bets are off anyway, since there is no reason to expect a C function to return a valid value in the first place.

-sb

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

* Re: 'Size hack for enumerated types
  2014-07-05 22:18     ` Victor Porton
  2014-07-05 22:23       ` Victor Porton
@ 2014-07-06 20:59       ` Simon Wright
  2014-07-06 23:01         ` Victor Porton
  1 sibling, 1 reply; 26+ messages in thread
From: Simon Wright @ 2014-07-06 20:59 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> -- rdf-auxilary.ads
> with Interfaces.C;
>
> package RDF.Auxilary is
>
>    generic
>       type Enum_Type is range <>;
>    package Convert_Enum is
>       function To_C(Argument: Enum_Type) return Interfaces.C.int;
>       function From_C(Argument: Interfaces.C.int) return Enum_Type;
>    end;
>
> end RDF.Auxilary;

If you want Enum_Type to be an enumeration, you should use a formal
discrete type definition[1]:

   type Enum_Type is (<>);

But I don't see what you're trying to achieve that can't easily be done
using simple language facilities:

   with Ada.Text_IO; use Ada.Text_IO;
   procedure Enums is
      type Flag_Type is (Libxml_Error_Save,
                         Libxml_Structured_Error_Save,
                         URI_Interning,
                         WWW_Skip_Init_Finish) with Convention => C;
      for Flag_Type use (Libxml_Error_Save => 1,
                         Libxml_Structured_Error_Save => 2,
                         URI_Interning => 3,
                         WWW_Skip_Init_Finish => 4);
      function Increment (F : Flag_Type) return Flag_Type
      with Import, Convention => C, External_Name => "increment";
   begin
      Put_Line ("incremented "
                  & Libxml_Structured_Error_Save'Img
                  & " is "
                  & Increment (Libxml_Structured_Error_Save)'Img);
   end Enums;

and, in increment.c,

   #include <stdio.h>

   typedef enum {LIBXML_ERROR_SAVE = 1,
                 LIBXML_STRUCTURED_ERROR_SAVE,
                 URI_INTERNING,
                 WWW_SKIP_INIT_FINISH} flag_type;

   flag_type increment(flag_type f) {
     flag_type result = f;
     ++result;
     printf("increment received %d, returning %d\n", f, result);
     return result;
   }

with

   $ gcc -c increment.c
   $ gnatmake enums.adb -largs increment.o
   $ ./enums
   increment received 2, returning 3
   incremented LIBXML_STRUCTURED_ERROR_SAVE is URI_INTERNING

[1] http://www.ada-auth.org/standards/12rm/html/RM-12-5-2.html#p2



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

* Re: 'Size hack for enumerated types
  2014-07-06 20:59       ` Simon Wright
@ 2014-07-06 23:01         ` Victor Porton
  2014-07-06 23:30           ` Jeffrey Carter
  2014-07-07  7:45           ` Simon Wright
  0 siblings, 2 replies; 26+ messages in thread
From: Victor Porton @ 2014-07-06 23:01 UTC (permalink / raw)


Simon Wright wrote:

> Victor Porton <porton@narod.ru> writes:
> 
>> -- rdf-auxilary.ads
>> with Interfaces.C;
>>
>> package RDF.Auxilary is
>>
>>    generic
>>       type Enum_Type is range <>;
>>    package Convert_Enum is
>>       function To_C(Argument: Enum_Type) return Interfaces.C.int;
>>       function From_C(Argument: Interfaces.C.int) return Enum_Type;
>>    end;
>>
>> end RDF.Auxilary;
> 
> If you want Enum_Type to be an enumeration, you should use a formal
> discrete type definition[1]:
> 
>    type Enum_Type is (<>);

The same error with this.

BTW, remind me what is the difference of:
- type Enum_Type is range <>;
- type Enum_Type is (<>);
?

> But I don't see what you're trying to achieve that can't easily be done
> using simple language facilities:
> 
>    with Ada.Text_IO; use Ada.Text_IO;
>    procedure Enums is
>       type Flag_Type is (Libxml_Error_Save,
>                          Libxml_Structured_Error_Save,
>                          URI_Interning,
>                          WWW_Skip_Init_Finish) with Convention => C;
>       for Flag_Type use (Libxml_Error_Save => 1,
>                          Libxml_Structured_Error_Save => 2,
>                          URI_Interning => 3,
>                          WWW_Skip_Init_Finish => 4);
>       function Increment (F : Flag_Type) return Flag_Type
>       with Import, Convention => C, External_Name => "increment";
>    begin
>       Put_Line ("incremented "
>                   & Libxml_Structured_Error_Save'Img
>                   & " is "
>                   & Increment (Libxml_Structured_Error_Save)'Img);
>    end Enums;

I see no reason for Increment function to work well with Convention => C, it 
seems that you are lucky with your compiler.

After all Flag_Type and enum flag_type may be of different size!

> and, in increment.c,
> 
>    #include <stdio.h>
> 
>    typedef enum {LIBXML_ERROR_SAVE = 1,
>                  LIBXML_STRUCTURED_ERROR_SAVE,
>                  URI_INTERNING,
>                  WWW_SKIP_INIT_FINISH} flag_type;
> 
>    flag_type increment(flag_type f) {
>      flag_type result = f;
>      ++result;
>      printf("increment received %d, returning %d\n", f, result);
>      return result;
>    }
> 
> with
> 
>    $ gcc -c increment.c
>    $ gnatmake enums.adb -largs increment.o
>    $ ./enums
>    increment received 2, returning 3
>    incremented LIBXML_STRUCTURED_ERROR_SAVE is URI_INTERNING
> 
> [1] http://www.ada-auth.org/standards/12rm/html/RM-12-5-2.html#p2

-- 
Victor Porton - http://portonvictor.org

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

* Re: 'Size hack for enumerated types
  2014-07-06 23:01         ` Victor Porton
@ 2014-07-06 23:30           ` Jeffrey Carter
  2014-07-07 16:00             ` Victor Porton
  2014-07-07  7:45           ` Simon Wright
  1 sibling, 1 reply; 26+ messages in thread
From: Jeffrey Carter @ 2014-07-06 23:30 UTC (permalink / raw)


On 07/06/2014 04:01 PM, Victor Porton wrote:
>
> I see no reason for Increment function to work well with Convention => C, it
> seems that you are lucky with your compiler.

Clearly you don't understand Convention C.

> After all Flag_Type and enum flag_type may be of different size!

No, they may not. Convention C means the Ada compiler should represent the type 
exactly as the (targeted) C compiler would represent the equivalent C type.

-- 
Jeff Carter
"Why, the Mayflower was full of Fireflies, and a few
horseflies, too. The Fireflies were on the upper deck,
and the horseflies were on the Fireflies."
Duck Soup
95

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

* Re: 'Size hack for enumerated types
  2014-07-06 23:01         ` Victor Porton
  2014-07-06 23:30           ` Jeffrey Carter
@ 2014-07-07  7:45           ` Simon Wright
  1 sibling, 0 replies; 26+ messages in thread
From: Simon Wright @ 2014-07-07  7:45 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

>> If you want Enum_Type to be an enumeration, you should use a formal
>> discrete type definition[1]:
>>
>>    type Enum_Type is (<>);
>
> The same error with this.

I never said that that change would fix the problem with your
implementation; but whatever the implementation, you can't instantiate
your generic with an enumeration because an enumeration is not a signed
integer.

> BTW, remind me what is the difference of:
> - type Enum_Type is range <>;
> - type Enum_Type is (<>);
> ?

I already gave you a link to the ARM:
http://www.ada-auth.org/standards/12rm/html/RM-12-5-2.html#p2

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

* Re: 'Size hack for enumerated types
  2014-07-06 23:30           ` Jeffrey Carter
@ 2014-07-07 16:00             ` Victor Porton
  2014-07-07 17:12               ` Simon Wright
  0 siblings, 1 reply; 26+ messages in thread
From: Victor Porton @ 2014-07-07 16:00 UTC (permalink / raw)


Jeffrey Carter wrote:

> On 07/06/2014 04:01 PM, Victor Porton wrote:
>>
>> I see no reason for Increment function to work well with Convention => C,
>> it seems that you are lucky with your compiler.
> 
> Clearly you don't understand Convention C.
> 
>> After all Flag_Type and enum flag_type may be of different size!
> 
> No, they may not. Convention C means the Ada compiler should represent the
> type exactly as the (targeted) C compiler would represent the equivalent C
> type.

Where in the Reference Manual it is said that Ada enumeration types are 
"equivalent" to C int (=enum) type?

-- 
Victor Porton - http://portonvictor.org

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

* Re: 'Size hack for enumerated types
  2014-07-07 16:00             ` Victor Porton
@ 2014-07-07 17:12               ` Simon Wright
  2014-07-07 20:23                 ` Victor Porton
  0 siblings, 1 reply; 26+ messages in thread
From: Simon Wright @ 2014-07-07 17:12 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> Where in the Reference Manual it is said that Ada enumeration types
> are "equivalent" to C int (=enum) type?

Annex B.1 (http://www.ada-auth.org/standards/12rm/html/RM-B-1.html),

2  The Convention aspect is used to indicate that an Ada entity should
   use the conventions of another language.

21 If the Convention aspect is specified for a type, then the type shall
   either be compatible with or eligible for the specified convention.


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

* Re: 'Size hack for enumerated types
  2014-07-07 17:12               ` Simon Wright
@ 2014-07-07 20:23                 ` Victor Porton
  2014-07-08  7:04                   ` Simon Wright
  2014-07-08  9:43                   ` AdaMagica
  0 siblings, 2 replies; 26+ messages in thread
From: Victor Porton @ 2014-07-07 20:23 UTC (permalink / raw)


Simon Wright wrote:

> Victor Porton <porton@narod.ru> writes:
> 
>> Where in the Reference Manual it is said that Ada enumeration types
>> are "equivalent" to C int (=enum) type?
> 
> Annex B.1 (http://www.ada-auth.org/standards/12rm/html/RM-B-1.html),
> 
> 2  The Convention aspect is used to indicate that an Ada entity should
>    use the conventions of another language.
> 
> 21 If the Convention aspect is specified for a type, then the type shall
>    either be compatible with or eligible for the specified convention.

No reason to assume either of:

1. Ada enumeration is compatible with C int/enum.

2. Ada enumeration is eligible for the specified convention (the convention 
C).

This is a work for a future standard.

It seems that the current one does not assert neither 1 neither 2. :-(

-- 
Victor Porton - http://portonvictor.org


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

* Re: 'Size hack for enumerated types
  2014-07-07 20:23                 ` Victor Porton
@ 2014-07-08  7:04                   ` Simon Wright
  2014-07-08 10:17                     ` sbelmont700
  2014-07-08 14:53                     ` Dan'l Miller
  2014-07-08  9:43                   ` AdaMagica
  1 sibling, 2 replies; 26+ messages in thread
From: Simon Wright @ 2014-07-08  7:04 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> Simon Wright wrote:
>
>> Victor Porton <porton@narod.ru> writes:
>> 
>>> Where in the Reference Manual it is said that Ada enumeration types
>>> are "equivalent" to C int (=enum) type?
>> 
>> Annex B.1 (http://www.ada-auth.org/standards/12rm/html/RM-B-1.html),
>> 
>> 2  The Convention aspect is used to indicate that an Ada entity should
>>    use the conventions of another language.
>> 
>> 21 If the Convention aspect is specified for a type, then the type shall
>>    either be compatible with or eligible for the specified convention.
>
> No reason to assume either of:
>
> 1. Ada enumeration is compatible with C int/enum.
>
> 2. Ada enumeration is eligible for the specified convention (the
> convention C).
>
> This is a work for a future standard.
>
> It seems that the current one does not assert neither 1 neither 2. :-(

Well, try submitting it to the ARG. I expect you'll get rebuffed in
short order.

I tried

   type Flag_Type is (Libxml_Error_Save,
                      Libxml_Structured_Error_Save,
		      URI_Interning,
                      WWW_Skip_Init_Finish) with Size => 3, Convention => C;

and GNAT said "warning: C enum types have the size of a C int" (I had
hoped this would have been an error, not a warning).



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

* Re: 'Size hack for enumerated types
  2014-07-07 20:23                 ` Victor Porton
  2014-07-08  7:04                   ` Simon Wright
@ 2014-07-08  9:43                   ` AdaMagica
  2014-07-08 13:52                     ` Victor Porton
  1 sibling, 1 reply; 26+ messages in thread
From: AdaMagica @ 2014-07-08  9:43 UTC (permalink / raw)


On Monday, July 7, 2014 10:23:06 PM UTC+2, Victor Porton wrote:
> Simon Wright wrote:
> > Victor Porton <porton@narod.ru> writes:
> >> Where in the Reference Manual it is said that Ada enumeration types
> >> are "equivalent" to C int (=enum) type?
> > Annex B.1 (http://www.ada-auth.org/standards/12rm/html/RM-B-1.html),
> > 2  The Convention aspect is used to indicate that an Ada entity should
> >    use the conventions of another language.
> > 21 If the Convention aspect is specified for a type, then the type shall
> >    either be compatible with or eligible for the specified convention.
> No reason to assume either of:
> 1. Ada enumeration is compatible with C int/enum.
> 2. Ada enumeration is eligible for the specified convention (the convention 
> C).
> This is a work for a future standard.
> It seems that the current one does not assert neither 1 neither 2. :-(

B.1(21/3) says "shall", so RM 1.1.5(3) applies. The compiler must reject the code if the enumeration is not compatible with C.

B.1(2/3) only says "should". So what does this mean? I gather together with (21), we're safe to assume it works.

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

* Re: 'Size hack for enumerated types
  2014-07-08  7:04                   ` Simon Wright
@ 2014-07-08 10:17                     ` sbelmont700
  2014-07-08 14:53                     ` Dan'l Miller
  1 sibling, 0 replies; 26+ messages in thread
From: sbelmont700 @ 2014-07-08 10:17 UTC (permalink / raw)


On Tuesday, July 8, 2014 3:04:06 AM UTC-4, Simon Wright wrote:
> 
> ... GNAT said "warning: C enum types have the size of a C int" 
> 

GNAT is being optimistic.  From 6.7.2.2/4:

"Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration."

It's perfectly reasonable to have non-int sized enums (bigger or smaller), and IIRC gcc even has a switch to achieve this.

-sb


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

* Re: 'Size hack for enumerated types
  2014-07-08  9:43                   ` AdaMagica
@ 2014-07-08 13:52                     ` Victor Porton
  2014-07-08 15:02                       ` Simon Wright
  0 siblings, 1 reply; 26+ messages in thread
From: Victor Porton @ 2014-07-08 13:52 UTC (permalink / raw)


AdaMagica wrote:

> On Monday, July 7, 2014 10:23:06 PM UTC+2, Victor Porton wrote:
>> Simon Wright wrote:
>> > Victor Porton <porton@narod.ru> writes:
>> >> Where in the Reference Manual it is said that Ada enumeration types
>> >> are "equivalent" to C int (=enum) type?
>> > Annex B.1 (http://www.ada-auth.org/standards/12rm/html/RM-B-1.html),
>> > 2  The Convention aspect is used to indicate that an Ada entity should
>> >    use the conventions of another language.
>> > 21 If the Convention aspect is specified for a type, then the type
>> > shall
>> >    either be compatible with or eligible for the specified convention.
>> No reason to assume either of:
>> 1. Ada enumeration is compatible with C int/enum.
>> 2. Ada enumeration is eligible for the specified convention (the
>> convention C).
>> This is a work for a future standard.
>> It seems that the current one does not assert neither 1 neither 2. :-(
> 
> B.1(21/3) says "shall", so RM 1.1.5(3) applies. The compiler must reject
> the code if the enumeration is not compatible with C.

It could be able to meaningfully reject the code, only it knew the C 
function profile. But what it known about the C function profile is only 
what is provided in our pragma. Certainly the C function profile which we 
provide is compatible with itself :-)

So, the C code is compatible with some Ada function profile, but not 
necessarily with one we provide.

Just logic.

> B.1(2/3) only says "should". So what does this mean? I gather together
> with (21), we're safe to assume it works.

-- 
Victor Porton - http://portonvictor.org

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

* Re: 'Size hack for enumerated types
  2014-07-08  7:04                   ` Simon Wright
  2014-07-08 10:17                     ` sbelmont700
@ 2014-07-08 14:53                     ` Dan'l Miller
  2014-07-08 20:56                       ` Randy Brukardt
  1 sibling, 1 reply; 26+ messages in thread
From: Dan'l Miller @ 2014-07-08 14:53 UTC (permalink / raw)


On Tuesday, July 8, 2014 2:04:06 AM UTC-5, Simon Wright wrote:
> Victor Porton writes:
> > Simon Wright wrote:
> > No reason to assume either of:
> > 1. Ada enumeration is compatible with C int/enum.

In ISO 14882 C++2011 (a.k.a. C++11 for the Y2K-challenged living 2000 years ago) enums are no longer all of type int (or any other mishmash of interpretations and proprietary extensions.  In C++2011 the following is now legal syntax & semantics:

enum Flag_Type : unsigned char { Libxml_Error_Save, Libxml_Structured_Error_Save, URI_Interning, WWW_Skip_Init_Finish};

as depicted at section 3.2 on page 8 of:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf

Because of the postfix "integralType identifier : bitsize" syntax after the identifier being declared in C & C++ for bitfields (and the lack of any declaration of identifier between enum and { here), there is no way in C++2011 to specify the underlying type of an enum to be a bit-field, as seems to be the desire in the Ada analogue along this thread.

> > 2. Ada enumeration is eligible for the specified convention (the
> > convention C).
>
> > This is a work for a future standard.
> > It seems that the current one does not assert neither 1 neither 2. :-(
> 
> Well, try submitting it to the ARG. I expect you'll get rebuffed in
> short order.

If the ARG is truly committed to interoperability with C & C++, then the ARG must seriously pursue accommodating N2347 and any other evolutions of C & C++ feature-set.  If the ARG rebuffs this, then repeatedly rebuff the rebuffing until seamless interoperability is achieved between Ada and C and between Ada & C++.

Conversely, ISO 9899 C2011 does not allow this new language feature, as shown in section 6.4.4.3 on page 67 of http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf.  So perhaps ARG needs to seriously consider adding Convention => C_Plus_Plus or whatever its syntax would be to handle the increasing divergence between C++ and C standards.

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

* Re: 'Size hack for enumerated types
  2014-07-08 13:52                     ` Victor Porton
@ 2014-07-08 15:02                       ` Simon Wright
  0 siblings, 0 replies; 26+ messages in thread
From: Simon Wright @ 2014-07-08 15:02 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> It could be able to meaningfully reject the code, only it knew the C
> function profile. But what it known about the C function profile is
> only what is provided in our pragma. Certainly the C function profile
> which we provide is compatible with itself :-)
>
> So, the C code is compatible with some Ada function profile, but not
> necessarily with one we provide.

To paraphrase, if your code is wrong it won't work properly.


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

* Re: 'Size hack for enumerated types
  2014-07-08 14:53                     ` Dan'l Miller
@ 2014-07-08 20:56                       ` Randy Brukardt
  2014-07-08 22:26                         ` Dan'l Miller
  2014-07-08 23:18                         ` Jeffrey Carter
  0 siblings, 2 replies; 26+ messages in thread
From: Randy Brukardt @ 2014-07-08 20:56 UTC (permalink / raw)


"Dan'l Miller" <optikos@verizon.net> wrote in message 
news:d2272863-c1e4-4130-a767-eb6fdd61e14b@googlegroups.com...

<Various interesting stuff elided>

...
>Conversely, ISO 9899 C2011 does not allow this new language feature, as
>shown in section 6.4.4.3 on page 67 of 
>http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf.
>So perhaps ARG needs to seriously consider adding Convention => C_Plus_Plus 
>or
>whatever its syntax would be to handle the increasing divergence between 
>C++ and
>C standards.

We've previously argued about a convention C_Plus_Plus or the like. We 
decided not to go there for two reasons:
(1) C_Plus_Plus is unspeakable ugly; C++ is bad syntax. We could get no 
agreement on the name here.
(2) We don't want to support convention C_Plus_Plus (or whatever it ends up 
being called) on tagged types. Doing so insists that all tagged types are 
represented as C++ does. That might be OK for GNAT (where the C++ compiler 
is maintained in tandem), but it wouldn't work very well for any target 
where the C++ compiler is from a separate organization. (I'm not interested 
in chasing Microsoft on this, thank you.) In addition other information is 
needed which tends to vary between C++ implementations. We didn't think that 
we could come up with a mechanism that was sufficiently abstract to allow 
portability between implementations.

The ultimate decision was that we wouldn't define a C++ convention.

Implementations are supposed to have a dedicated convention for every 
compiler they support. So if the C++ compiler does something different than 
the C compiler, then the *implementation* should have a separate convention 
for the C++ compiler. The language need not get involved, as portability 
between implementations can't be guaranteed anyway.

I'm sure we'll revisit this someday, but I'm not sure that any other 
conclusion is possible.

                                     Randy.



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

* Re: 'Size hack for enumerated types
  2014-07-08 20:56                       ` Randy Brukardt
@ 2014-07-08 22:26                         ` Dan'l Miller
  2014-07-08 23:18                         ` Jeffrey Carter
  1 sibling, 0 replies; 26+ messages in thread
From: Dan'l Miller @ 2014-07-08 22:26 UTC (permalink / raw)


On Tuesday, July 8, 2014 3:56:25 PM UTC-5, Randy Brukardt wrote:
> We've previously argued about a convention C_Plus_Plus or the like. We 
> decided not to go there for two reasons:
> (1) C_Plus_Plus is unspeakable ugly; C++ is bad syntax. We could get no 
> agreement on the name here.

  This is one of the very few areas where C++ was wiser than Ada:  C++'s analogous syntax is:  extern "C", where the string-quotes quarantine peculiar language names that would pollute the C++ grammar/parser.  I would suggest making Convention => "C" equivalent to Convention => C, then adding Convention => "C++".

> (2) We don't want to support convention C_Plus_Plus (or whatever it ends up 
> being called) on tagged types. Doing so insists that all tagged types are 
> represented as C++ does. That might be OK for GNAT (where the C++ compiler 
> is maintained in tandem), but it wouldn't work very well for any target 
> where the C++ compiler is from a separate organization. (I'm not interested 
> in chasing Microsoft on this, thank you.)

I agree.  There is no way that Ada should have Convention => "C++/CLI" for .NET boxed-type bytecode or Convention => "C++/CX" for boxed-type native machine-code.

> In addition other information is 
> needed which tends to vary between C++ implementations. We didn't think that 
> we could come up with a mechanism that was sufficiently abstract to allow 
> portability between implementations.

1000 pure Ada tagged types would need to conform to C++'s analogue (pointer to virtual-function table) just because 1 tagged type was annotated with Convention => "C++".  What might be too burdensome, is to go through every portion of the LRM to see where conforming to pointer to virtual-function table and non-virtual member-functions would change the Ada semantics for an Ada tagged type with Convention => "C++".

Your list is too short and not pessimistic enough.  There seem far more severe:

3) Name mangling.  Ada would need to conform to the highly-proprietary name-mangling conventions of encoding type information in very-lengthy function names.  In effect, this proprietarianism would seem to require the syntax of with Convention => "C++" to be something to the effect of with Convention => "Microsoft C++" or with Convention => "GNU C++" or with Convention => "Edison Design Group C++".

4) Exceptions.  Ada exceptions have no ability to have user-defined fields in a record that represents the exception.  As soon as full exception compatibility with C++ is admitted into Convention => "C++", then Ada exceptions would need to be expanded to have parity with the C++ expressivity of user-defined fields in exception structs.

> The ultimate decision was that we wouldn't define a C++ convention.

You make the decision sound so permanent, as if it cannot be divided & conquered by even partial attempts at Convention => "C++" that omit tagged types and exceptions.

> Implementations are supposed to have a dedicated convention for every 
> compiler they support. So if the C++ compiler does something different than 
> the C compiler, then the *implementation* should have a separate convention 
> for the C++ compiler. The language need not get involved, as portability 
> between implementations can't be guaranteed anyway.

I assume that you are saying here that portability is an impractical up-hill battle, not mathematically-provably impossible.

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

* Re: 'Size hack for enumerated types
  2014-07-08 20:56                       ` Randy Brukardt
  2014-07-08 22:26                         ` Dan'l Miller
@ 2014-07-08 23:18                         ` Jeffrey Carter
  1 sibling, 0 replies; 26+ messages in thread
From: Jeffrey Carter @ 2014-07-08 23:18 UTC (permalink / raw)


On 07/08/2014 01:56 PM, Randy Brukardt wrote:
>
> (1) C_Plus_Plus is unspeakable ugly

C++ is unspeakably ugly; I don't see why it's convention name shouldn't be, too.

-- 
Jeff Carter
"Why don't you bore a hole in yourself and let the sap run out?"
Horse Feathers
49


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

end of thread, other threads:[~2014-07-08 23:18 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-05 20:32 'Size hack for enumerated types Victor Porton
2014-07-05 21:47 ` Simon Wright
2014-07-05 22:11   ` Victor Porton
2014-07-05 22:18     ` Victor Porton
2014-07-05 22:23       ` Victor Porton
2014-07-06 16:25         ` Victor Porton
2014-07-06 20:59       ` Simon Wright
2014-07-06 23:01         ` Victor Porton
2014-07-06 23:30           ` Jeffrey Carter
2014-07-07 16:00             ` Victor Porton
2014-07-07 17:12               ` Simon Wright
2014-07-07 20:23                 ` Victor Porton
2014-07-08  7:04                   ` Simon Wright
2014-07-08 10:17                     ` sbelmont700
2014-07-08 14:53                     ` Dan'l Miller
2014-07-08 20:56                       ` Randy Brukardt
2014-07-08 22:26                         ` Dan'l Miller
2014-07-08 23:18                         ` Jeffrey Carter
2014-07-08  9:43                   ` AdaMagica
2014-07-08 13:52                     ` Victor Porton
2014-07-08 15:02                       ` Simon Wright
2014-07-07  7:45           ` Simon Wright
2014-07-06  7:22     ` Simon Wright
2014-07-06 13:21 ` sbelmont700
2014-07-06 16:16   ` Victor Porton
2014-07-06 17:52     ` sbelmont700

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