Can imported C enums be resized?

As the title says.

I found an error in SDLAda:

typedef struct SDL_WindowEvent
{
    Uint32 type;        /**< SDL_WINDOWEVENT */
    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
    Uint32 windowID;    /**< The associated window */
    Uint8 event;        /**< SDL_WindowEventID */
    Uint8 padding1;
    Uint8 padding2;
    Uint8 padding3;
    Sint32 data1;       /**< event dependent data */
    Sint32 data2;       /**< event dependent data */
} SDL_WindowEvent;
   type Window_Event_ID is
     (None,
      Shown,
      Hidden,
      Exposed,
      Moved,
      Resized,
      Size_Changed,
      Minimised,
      Maximised,
      Restored,
      Enter,
      Leave,
      Focus_Gained,
      Focus_Lost,
      Close,
      Take_Focus,
      Hit_Test) with
   Convention => C;

   type Window_Event is
      record
         Event_Type : Event_Types;           --  Will be set to Window.
         Time_Stamp : Time_Stamps;

         ID         : SDL.Video.Windows.ID;
         Event_ID   : Window_Event_ID;
         Padding_1  : Padding_8;
         Padding_2  : Padding_8;
         Padding_3  : Padding_8;
         Data_1     : Interfaces.Integer_32;
         Data_2     : Interfaces.Integer_32;
      end record with
   Convention => C;

Event_ID should be 8-bit to match the event in the c version, SDL_WindowEventID is an enum, but in c, there is an implicit conversion to int from enums.

nm. It will work.

with Ada.Direct_IO;
with Ada.Text_IO; use Ada.Text_IO;

procedure Test is
   type enum is (blah, wah) with
      Convention => C,
      Size => 8;
begin
   Put_Line ("enum'Size => " & Integer'Image (enum'Size));
end Test;
$ ./test 
enum'Size =>  8
2 Likes

You can add the Size => 8 aspect directly to the definition, and have a new type Wide_Window_Event_ID is new Window_Event_ID with Size => Interfaces.C.Int'Size; if you need the two sizes. (I would recommend the wider deriving from the smaller, so that the compiler can complain at you if you try shoving [eg] 5 enumerations into 2 bits.)

Nope, don’t need the two sizes, just need the one.

Oh, yeah, then just throw Size on the definition.
(I’ve used this not infrequently, when doing things like protocols or HW/VM internals/interfacing.)

1 Like

Isn’t it 32 bits in C?

The C standard doesn’t specify a specific size for integers. At a minimum they need to be 16 bits (-32768 .. 32767) but can hold larger values. They cannot be smaller than a short or larger than a long as well.

For enumeration size, it only says the following:
6.7.2.2 Enumeration specifiers

The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.

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.

I mean in the original C declaration.

And if it were a real enum, it would be also 32 bits, because with GCC/GNAT, enums are ints. So I don’t understand why setting the size of the type Window_Event_ID to 8 bits.

And I think that not setting the size is actually more portable.

If pragma Convention C is specified for an Ada enumeration type, then the size is modified as necessary (usually to 32 bits) to be consistent with the C convention for enum values.

GNAT Reference Manual > 9. Representation Clauses and Pragmas

Forget about this, I’ve just realized that you were referring to

and not windowID.