comp.lang.ada
 help / color / mirror / Atom feed
* Record initialisation question
@ 2021-01-09  9:30 DrPi
  2021-01-09 10:46 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: DrPi @ 2021-01-09  9:30 UTC (permalink / raw)


Hi,

I'm working on a µP BSP. The boot sequence of this µP requires byte 
structures located in FLASH memory.
For example :

    type t_Dcd_Header is record
       Tag     : Unsigned_8  := 16#D2#;
       Length  : Unsigned_16 := 4;      -- Length in byte of the DCD 
structure (this header included)
       Version : Unsigned_8  := 16#41#;
    end record
      with Object_Size => 32,
           Bit_Order => System.Low_Order_First;

    for t_Dcd_Header use record
       Tag     at 0 range  0 .. 7;
       Length  at 0 range  8 .. 23;
       Version at 0 range 24 .. 31;
    end record;

The t_Dcd_Header is part of t_Dcd record.
The Length field of t_Dcd_Header must contain the length of t_Dcd.

    Dcd : constant t_Dcd :=
     ( Dcd_Header => ( Length => ???, -- Length of Dcd
                       others => <>),
       ...
     );

Is there a way to automatically set Length ?
Dcd goes in a dedicated .txt section.

Nicolas

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

* Re: Record initialisation question
  2021-01-09  9:30 Record initialisation question DrPi
@ 2021-01-09 10:46 ` Dmitry A. Kazakov
  2021-01-10 16:41   ` DrPi
  2021-01-17 17:03   ` DrPi
  2021-01-09 15:44 ` Niklas Holsti
  2021-01-17 17:08 ` DrPi
  2 siblings, 2 replies; 32+ messages in thread
From: Dmitry A. Kazakov @ 2021-01-09 10:46 UTC (permalink / raw)


On 2021-01-09 10:30, DrPi wrote:
> Hi,
> 
> I'm working on a µP BSP. The boot sequence of this µP requires byte 
> structures located in FLASH memory.
> For example :
> 
>     type t_Dcd_Header is record
>        Tag     : Unsigned_8  := 16#D2#;
>        Length  : Unsigned_16 := 4;      -- Length in byte of the DCD 
> structure (this header included)
>        Version : Unsigned_8  := 16#41#;
>     end record
>       with Object_Size => 32,
>            Bit_Order => System.Low_Order_First;
> 
>     for t_Dcd_Header use record
>        Tag     at 0 range  0 .. 7;
>        Length  at 0 range  8 .. 23;
>        Version at 0 range 24 .. 31;
>     end record;
> 
> The t_Dcd_Header is part of t_Dcd record.
> The Length field of t_Dcd_Header must contain the length of t_Dcd.
> 
>     Dcd : constant t_Dcd :=
>      ( Dcd_Header => ( Length => ???, -- Length of Dcd
>                        others => <>),
>        ...
>      );
> 
> Is there a way to automatically set Length ?

t_Dcd'Max_Size_In_Storage_Elements?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: Record initialisation question
  2021-01-09  9:30 Record initialisation question DrPi
  2021-01-09 10:46 ` Dmitry A. Kazakov
@ 2021-01-09 15:44 ` Niklas Holsti
  2021-01-10 16:53   ` DrPi
  2021-01-17 17:08 ` DrPi
  2 siblings, 1 reply; 32+ messages in thread
From: Niklas Holsti @ 2021-01-09 15:44 UTC (permalink / raw)


On 2021-01-09 11:30, DrPi wrote:
> Hi,
> 
> I'm working on a µP BSP. The boot sequence of this µP requires byte 
> structures located in FLASH memory.
> For example :
> 
>     type t_Dcd_Header is record
>        Tag     : Unsigned_8  := 16#D2#;
>        Length  : Unsigned_16 := 4;      -- Length in byte of the DCD 
> structure (this header included)


(As the default value (4) does not include the rest of the DCD 
structure, the comment is rather misleading. Best to remove the default 
value, I think.)


>        Version : Unsigned_8  := 16#41#;
>     end record
>       with Object_Size => 32,
>            Bit_Order => System.Low_Order_First;
> 
>     for t_Dcd_Header use record
>        Tag     at 0 range  0 .. 7;
>        Length  at 0 range  8 .. 23;
>        Version at 0 range 24 .. 31;
>     end record;
> 
> The t_Dcd_Header is part of t_Dcd record.
> The Length field of t_Dcd_Header must contain the length of t_Dcd.
> 
>     Dcd : constant t_Dcd :=
>      ( Dcd_Header => ( Length => ???, -- Length of Dcd
>                        others => <>),
>        ...
>      );
> 
> Is there a way to automatically set Length ?


If the Length should apply to the whole t_Dcd object, it is hard to 
answer without knowing how the rest of the t_Dcd type is defined. Does 
it have a fixed size, or are there some components of variable size?


> Dcd goes in a dedicated .txt section.


Do you expect the compiler/linker to generate the full value of the Dcd 
object into the program image at compilation and link time? Have you 
ensured that the construction of the Dcd object requires no elaboration 
code? Most Flash memories cannot be written in the same way as RAM, so 
even if that .txt section is not write-protected, normal RAM-oriented 
elaboration code would not be able to write into Flash.

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

* Re: Record initialisation question
  2021-01-09 10:46 ` Dmitry A. Kazakov
@ 2021-01-10 16:41   ` DrPi
  2021-01-11 21:48     ` Shark8
  2021-01-17 17:03   ` DrPi
  1 sibling, 1 reply; 32+ messages in thread
From: DrPi @ 2021-01-10 16:41 UTC (permalink / raw)


Le 09/01/2021 à 11:46, Dmitry A. Kazakov a écrit :
> On 2021-01-09 10:30, DrPi wrote:
>> Hi,
>>
>> I'm working on a µP BSP. The boot sequence of this µP requires byte 
>> structures located in FLASH memory.
>> For example :
>>
>>     type t_Dcd_Header is record
>>        Tag     : Unsigned_8  := 16#D2#;
>>        Length  : Unsigned_16 := 4;      -- Length in byte of the DCD 
>> structure (this header included)
>>        Version : Unsigned_8  := 16#41#;
>>     end record
>>       with Object_Size => 32,
>>            Bit_Order => System.Low_Order_First;
>>
>>     for t_Dcd_Header use record
>>        Tag     at 0 range  0 .. 7;
>>        Length  at 0 range  8 .. 23;
>>        Version at 0 range 24 .. 31;
>>     end record;
>>
>> The t_Dcd_Header is part of t_Dcd record.
>> The Length field of t_Dcd_Header must contain the length of t_Dcd.
>>
>>     Dcd : constant t_Dcd :=
>>      ( Dcd_Header => ( Length => ???, -- Length of Dcd
>>                        others => <>),
>>        ...
>>      );
>>
>> Is there a way to automatically set Length ?
> 
> t_Dcd'Max_Size_In_Storage_Elements?
> 
I'll try it but I've just faced another problem where a component of 
another record is the address of the record itself.

I tried to partly declare the record in public and fully declare it in 
private part of the package but the compiler still complains : "full 
constant declaration appears too late".

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

* Re: Record initialisation question
  2021-01-09 15:44 ` Niklas Holsti
@ 2021-01-10 16:53   ` DrPi
  2021-01-10 19:30     ` Niklas Holsti
  0 siblings, 1 reply; 32+ messages in thread
From: DrPi @ 2021-01-10 16:53 UTC (permalink / raw)


Le 09/01/2021 à 16:44, Niklas Holsti a écrit :
> On 2021-01-09 11:30, DrPi wrote:
>> Hi,
>>
>> I'm working on a µP BSP. The boot sequence of this µP requires byte 
>> structures located in FLASH memory.
>> For example :
>>
>>     type t_Dcd_Header is record
>>        Tag     : Unsigned_8  := 16#D2#;
>>        Length  : Unsigned_16 := 4;      -- Length in byte of the DCD 
>> structure (this header included)
> 
> 
> (As the default value (4) does not include the rest of the DCD 
> structure, the comment is rather misleading. Best to remove the default 
> value, I think.)
Maybe, I'm sure sure.
Value of 4 means only the header is present.

> 
> 
>>        Version : Unsigned_8  := 16#41#;
>>     end record
>>       with Object_Size => 32,
>>            Bit_Order => System.Low_Order_First;
>>
>>     for t_Dcd_Header use record
>>        Tag     at 0 range  0 .. 7;
>>        Length  at 0 range  8 .. 23;
>>        Version at 0 range 24 .. 31;
>>     end record;
>>
>> The t_Dcd_Header is part of t_Dcd record.
>> The Length field of t_Dcd_Header must contain the length of t_Dcd.
>>
>>     Dcd : constant t_Dcd :=
>>      ( Dcd_Header => ( Length => ???, -- Length of Dcd
>>                        others => <>),
>>        ...
>>      );
>>
>> Is there a way to automatically set Length ?
> 
> 
> If the Length should apply to the whole t_Dcd object, it is hard to 
> answer without knowing how the rest of the t_Dcd type is defined. Does 
> it have a fixed size, or are there some components of variable size?
> 
The DCD is fully specified.

> 
>> Dcd goes in a dedicated .txt section.
> 
> 
> Do you expect the compiler/linker to generate the full value of the Dcd 
> object into the program image at compilation and link time? 
That's it.

> Have you 
> ensured that the construction of the Dcd object requires no elaboration 
> code? Most Flash memories cannot be written in the same way as RAM, so 
> even if that .txt section is not write-protected, normal RAM-oriented 
> elaboration code would not be able to write into Flash.
I'm aware of this (I'm an electronics guy).
I'll add a "pragma No_Elaboration_Code_All;" when I'm ready.

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

* Re: Record initialisation question
  2021-01-10 16:53   ` DrPi
@ 2021-01-10 19:30     ` Niklas Holsti
  2021-01-10 21:27       ` DrPi
  0 siblings, 1 reply; 32+ messages in thread
From: Niklas Holsti @ 2021-01-10 19:30 UTC (permalink / raw)


On 2021-01-10 18:53, DrPi wrote:
> Le 09/01/2021 à 16:44, Niklas Holsti a écrit :
    ...
>>
>> Do you expect the compiler/linker to generate the full value of the 
>> Dcd object into the program image at compilation and link time? 
> That's it.
> 
>> Have you ensured that the construction of the Dcd object requires no 
>> elaboration code? Most Flash memories cannot be written in the same 
>> way as RAM, so even if that .txt section is not write-protected, 
>> normal RAM-oriented elaboration code would not be able to write into 
>> Flash.
> I'm aware of this (I'm an electronics guy).
> I'll add a "pragma No_Elaboration_Code_All;" when I'm ready.


Better add it now, because if you add it later, the compiler may then 
complain that it cannot implement the Dcd aggregate without elaboration 
code, and you will have to work around that somehow.

A good while ago, a colleague had a problem where a large constant array 
aggregate would require elaboration code if written in named form (Index 
=> Value, Index => Value, ...), and it was necessary to write it in 
positional form (Value, Value, ...) to get rid of the elaboration code. 
It can be tricky, so it is better to be warned early of any problems.

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

* Re: Record initialisation question
  2021-01-10 19:30     ` Niklas Holsti
@ 2021-01-10 21:27       ` DrPi
  2021-01-10 22:14         ` Niklas Holsti
  0 siblings, 1 reply; 32+ messages in thread
From: DrPi @ 2021-01-10 21:27 UTC (permalink / raw)


Le 10/01/2021 à 20:30, Niklas Holsti a écrit :
> On 2021-01-10 18:53, DrPi wrote:
>> Le 09/01/2021 à 16:44, Niklas Holsti a écrit :
>     ...
>>>
>>> Do you expect the compiler/linker to generate the full value of the 
>>> Dcd object into the program image at compilation and link time? 
>> That's it.
>>
>>> Have you ensured that the construction of the Dcd object requires no 
>>> elaboration code? Most Flash memories cannot be written in the same 
>>> way as RAM, so even if that .txt section is not write-protected, 
>>> normal RAM-oriented elaboration code would not be able to write into 
>>> Flash.
>> I'm aware of this (I'm an electronics guy).
>> I'll add a "pragma No_Elaboration_Code_All;" when I'm ready.
> 
> 
> Better add it now, because if you add it later, the compiler may then 
> complain that it cannot implement the Dcd aggregate without elaboration 
> code, and you will have to work around that somehow.
> 
> A good while ago, a colleague had a problem where a large constant array 
> aggregate would require elaboration code if written in named form (Index 
> => Value, Index => Value, ...), and it was necessary to write it in 
> positional form (Value, Value, ...) to get rid of the elaboration code. 
> It can be tricky, so it is better to be warned early of any problems.
Thanks for letting me know.
Any reason why the behavior changes with the way of writing ?

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

* Re: Record initialisation question
  2021-01-10 21:27       ` DrPi
@ 2021-01-10 22:14         ` Niklas Holsti
  2021-01-11 17:46           ` DrPi
  0 siblings, 1 reply; 32+ messages in thread
From: Niklas Holsti @ 2021-01-10 22:14 UTC (permalink / raw)


On 2021-01-10 23:27, DrPi wrote:
> Le 10/01/2021 à 20:30, Niklas Holsti a écrit :
>> On 2021-01-10 18:53, DrPi wrote:
>>> Le 09/01/2021 à 16:44, Niklas Holsti a écrit :
>>     ...
>>>>
>>>> Do you expect the compiler/linker to generate the full value of the 
>>>> Dcd object into the program image at compilation and link time? 
>>> That's it.
>>>
>>>> Have you ensured that the construction of the Dcd object requires no 
>>>> elaboration code? Most Flash memories cannot be written in the same 
>>>> way as RAM, so even if that .txt section is not write-protected, 
>>>> normal RAM-oriented elaboration code would not be able to write into 
>>>> Flash.
>>> I'm aware of this (I'm an electronics guy).
>>> I'll add a "pragma No_Elaboration_Code_All;" when I'm ready.
>>
>>
>> Better add it now, because if you add it later, the compiler may then 
>> complain that it cannot implement the Dcd aggregate without 
>> elaboration code, and you will have to work around that somehow.
>>
>> A good while ago, a colleague had a problem where a large constant 
>> array aggregate would require elaboration code if written in named 
>> form (Index => Value, Index => Value, ...), and it was necessary to 
>> write it in positional form (Value, Value, ...) to get rid of the 
>> elaboration code. It can be tricky, so it is better to be warned early 
>> of any problems.
> Thanks for letting me know.
> Any reason why the behavior changes with the way of writing ?


Not really. We asked the compiler vendor (not AdaCore) for help, and 
they advised us to use the positional form, without further explanation. 
I assume the compiler writer just did not bother to implement the 
index-sorting step that would be needed for the named form, and 
preferred to generate elaboration assignments "on the fly" in the order 
the indices appeared in the named aggregate.

The point is that compilers are not required to make all things work 
without elaboration code. Just as for record representation clauses, 
compilers are only required to reject the program if the compiler cannot 
(or does not bother to) implement the request. So you seldom know if 
your request will work, until you try it with your particular compiler.

I am reminded of a similar problem I had (this time with GNAT) more 
recently: I wanted to write start-up code to initialize the DRAM 
controller, but of course this code should normally not use the DRAM, 
only registers. I had nice record types for the DRAM controller 
registers, but any use of record aggregates on the right-hand side of 
assignments made GNAT use temporaries in the stack (thus in DRAM). Only 
for an assignment of a literal constant would GNAT build the constant in 
registers, avoiding DRAM use. (In the end I used the record aggregates, 
because I knew that the DRAM controller would have some working initial 
state left over from the boot SW, and I only needed to modify this state 
a little.)

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

* Re: Record initialisation question
  2021-01-10 22:14         ` Niklas Holsti
@ 2021-01-11 17:46           ` DrPi
  2021-01-11 20:58             ` Niklas Holsti
  0 siblings, 1 reply; 32+ messages in thread
From: DrPi @ 2021-01-11 17:46 UTC (permalink / raw)


Le 10/01/2021 à 23:14, Niklas Holsti a écrit :
> On 2021-01-10 23:27, DrPi wrote:
>> Le 10/01/2021 à 20:30, Niklas Holsti a écrit :
>>> On 2021-01-10 18:53, DrPi wrote:
>>>> Le 09/01/2021 à 16:44, Niklas Holsti a écrit :
>>>     ...
>>>>>
>>>>> Do you expect the compiler/linker to generate the full value of the 
>>>>> Dcd object into the program image at compilation and link time? 
>>>> That's it.
>>>>
>>>>> Have you ensured that the construction of the Dcd object requires 
>>>>> no elaboration code? Most Flash memories cannot be written in the 
>>>>> same way as RAM, so even if that .txt section is not 
>>>>> write-protected, normal RAM-oriented elaboration code would not be 
>>>>> able to write into Flash.
>>>> I'm aware of this (I'm an electronics guy).
>>>> I'll add a "pragma No_Elaboration_Code_All;" when I'm ready.
>>>
>>>
>>> Better add it now, because if you add it later, the compiler may then 
>>> complain that it cannot implement the Dcd aggregate without 
>>> elaboration code, and you will have to work around that somehow.
>>>
>>> A good while ago, a colleague had a problem where a large constant 
>>> array aggregate would require elaboration code if written in named 
>>> form (Index => Value, Index => Value, ...), and it was necessary to 
>>> write it in positional form (Value, Value, ...) to get rid of the 
>>> elaboration code. It can be tricky, so it is better to be warned 
>>> early of any problems.
>> Thanks for letting me know.
>> Any reason why the behavior changes with the way of writing ?
> 
> 
> Not really. We asked the compiler vendor (not AdaCore) for help, and 
> they advised us to use the positional form, without further explanation. 
> I assume the compiler writer just did not bother to implement the 
> index-sorting step that would be needed for the named form, and 
> preferred to generate elaboration assignments "on the fly" in the order 
> the indices appeared in the named aggregate.
> 
> The point is that compilers are not required to make all things work 
> without elaboration code. Just as for record representation clauses, 
> compilers are only required to reject the program if the compiler cannot 
> (or does not bother to) implement the request. So you seldom know if 
> your request will work, until you try it with your particular compiler.
> 
> I am reminded of a similar problem I had (this time with GNAT) more 
> recently: I wanted to write start-up code to initialize the DRAM 
> controller, but of course this code should normally not use the DRAM, 
> only registers. I had nice record types for the DRAM controller 
> registers, but any use of record aggregates on the right-hand side of 
> assignments made GNAT use temporaries in the stack (thus in DRAM). Only 
> for an assignment of a literal constant would GNAT build the constant in 
> registers, avoiding DRAM use. (In the end I used the record aggregates, 
> because I knew that the DRAM controller would have some working initial 
> state left over from the boot SW, and I only needed to modify this state 
> a little.)
> 
Thanks, that's interresting.
I added "pragma No_Elaboration_Code_All;" to my code and... all records 
are rejected.
The boot data structure (in FLASH memory) is composed of several 
records. They are linked by their addresses. When a record contains an 
address, initializing it with a "non static number" value makes the 
compiler complain (with No_Elaboration_Code_All set).
You were right.
I have to find a workaround.

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

* Re: Record initialisation question
  2021-01-11 17:46           ` DrPi
@ 2021-01-11 20:58             ` Niklas Holsti
  2021-01-14 13:07               ` DrPi
  0 siblings, 1 reply; 32+ messages in thread
From: Niklas Holsti @ 2021-01-11 20:58 UTC (permalink / raw)


On 2021-01-11 19:46, DrPi wrote:

> I added "pragma No_Elaboration_Code_All;" to my code and... all records 
> are rejected.
> The boot data structure (in FLASH memory) is composed of several 
> records. They are linked by their addresses. When a record contains an 
> address, initializing it with a "non static number" value makes the 
> compiler complain (with No_Elaboration_Code_All set).


Ah, too bad.

The problem is that "static" in Ada means "known at compile time", while 
addresses, although static in execution, are generally not known until 
link time. A case where assembly language is more powerful :-(

> I have to find a workaround.

If addresses are the only problem, and you are in control of the flash 
memory lay-out, you might be able to define static Ada constant 
expressions that compute ("predict") the addresses of every boot data 
structure record. But those expressions would need to use the sizes of 
the records, I think, and unfortunately the 'Size of a record type is 
not a static expression (IIRC), and that may hold also for the 
GNAT-specific 'Max_Size_In_Storage_Units.

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

* Re: Record initialisation question
  2021-01-10 16:41   ` DrPi
@ 2021-01-11 21:48     ` Shark8
  2021-01-12 11:38       ` Simon Wright
  2021-01-14 12:58       ` DrPi
  0 siblings, 2 replies; 32+ messages in thread
From: Shark8 @ 2021-01-11 21:48 UTC (permalink / raw)


> I'll try it but I've just faced another problem where a component of 
> another record is the address of the record itself. 

    Type Example;
    Function To_Address( Input : Access Example ) return System.Address
       with Inline;
    
    Type Example is limited record
        Addr : System.Address := To_Address(Example'Access);
    End record;
    
    Package Cvt is new System.Address_To_Access_Conversions(Example);
    Function To_Address( Input : Access Example ) return System.Address is
      ( Cvt.To_Address( Input.all'Access ) );

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

* Re: Record initialisation question
  2021-01-11 21:48     ` Shark8
@ 2021-01-12 11:38       ` Simon Wright
  2021-01-12 15:01         ` Shark8
  2021-01-14 12:58       ` DrPi
  1 sibling, 1 reply; 32+ messages in thread
From: Simon Wright @ 2021-01-12 11:38 UTC (permalink / raw)


Shark8 <onewingedshark@gmail.com> writes:

>> I'll try it but I've just faced another problem where a component of 
>> another record is the address of the record itself. 
>
>     Type Example;
>     Function To_Address( Input : Access Example ) return System.Address
>        with Inline;
>     
>     Type Example is limited record
>         Addr : System.Address := To_Address(Example'Access);
>     End record;
>     
>     Package Cvt is new System.Address_To_Access_Conversions(Example);
>     Function To_Address( Input : Access Example ) return System.Address is
>       ( Cvt.To_Address( Input.all'Access ) );

OP wanted to place the data structures in ROM, the chance of this
working looks pretty remote

(what is it with this weird casing "convention" you use? makes the code
quite hard to read ...)

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

* Re: Record initialisation question
  2021-01-12 11:38       ` Simon Wright
@ 2021-01-12 15:01         ` Shark8
  2021-01-14 21:32           ` Simon Wright
  0 siblings, 1 reply; 32+ messages in thread
From: Shark8 @ 2021-01-12 15:01 UTC (permalink / raw)


On Tuesday, January 12, 2021 at 4:38:24 AM UTC-7, Simon Wright wrote:
> Shark8 writes: 
> 
> >> I'll try it but I've just faced another problem where a component of 
> >> another record is the address of the record itself. 
> > 
> > Type Example; 
> > Function To_Address( Input : Access Example ) return System.Address 
> > with Inline; 
> > 
> > Type Example is limited record 
> > Addr : System.Address := To_Address(Example'Access); 
> > End record; 
> > 
> > Package Cvt is new System.Address_To_Access_Conversions(Example); 
> > Function To_Address( Input : Access Example ) return System.Address is 
> > ( Cvt.To_Address( Input.all'Access ) );
> OP wanted to place the data structures in ROM, the chance of this 
> working looks pretty remote 
Yeah, it does, if ROM's the target... but it might work.
The "right way" would be to have an Address-typed parameter on the record, defaulting with Record_Type'Address (using the same Name_in_Definition'Access trick to get the address of the component being created), but we cannot declare discriminants which are not non-scalar or non-access. The other way to do this might be a bit-vector sized as an address, then using Unchecked conversion as the default value.

> (what is it with this weird casing "convention" you use? makes the code 
> quite hard to read ...)
Really?
How so?

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

* Re: Record initialisation question
  2021-01-11 21:48     ` Shark8
  2021-01-12 11:38       ` Simon Wright
@ 2021-01-14 12:58       ` DrPi
  1 sibling, 0 replies; 32+ messages in thread
From: DrPi @ 2021-01-14 12:58 UTC (permalink / raw)


Le 11/01/2021 à 22:48, Shark8 a écrit :
>> I'll try it but I've just faced another problem where a component of
>> another record is the address of the record itself.
> 
>      Type Example;
>      Function To_Address( Input : Access Example ) return System.Address
>         with Inline;
>      
>      Type Example is limited record
>          Addr : System.Address := To_Address(Example'Access);
>      End record;
>      
>      Package Cvt is new System.Address_To_Access_Conversions(Example);
>      Function To_Address( Input : Access Example ) return System.Address is
>        ( Cvt.To_Address( Input.all'Access ) );
> 

System.Address_To_Access_Conversions() is not compatible with 
No_Elaboration_Code_All pragma.

No elaboration code is mandatory since the structure of data go in FLASH 
memory.

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

* Re: Record initialisation question
  2021-01-11 20:58             ` Niklas Holsti
@ 2021-01-14 13:07               ` DrPi
  2021-01-14 13:36                 ` AdaMagica
                                   ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: DrPi @ 2021-01-14 13:07 UTC (permalink / raw)



> The problem is that "static" in Ada means "known at compile time", while 
> addresses, although static in execution, are generally not known until 
> link time. A case where assembly language is more powerful :-(
> 
Or C :(
I use the manufacturer C code generated by their tool as reference. In 
C, initializing a structure element with an address is not a problem.

>> I have to find a workaround.
> 
> If addresses are the only problem, and you are in control of the flash 
> memory lay-out, you might be able to define static Ada constant 
> expressions that compute ("predict") the addresses of every boot data 
> structure record. But those expressions would need to use the sizes of 
> the records, I think, and unfortunately the 'Size of a record type is 
> not a static expression (IIRC), and that may hold also for the 
> GNAT-specific 'Max_Size_In_Storage_Units.

I can redefine the records with UInt32 instead of System.Address. The 
problem is : What is the expression to convert from Address to UInt32 
without using a function ?

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

* Re: Record initialisation question
  2021-01-14 13:07               ` DrPi
@ 2021-01-14 13:36                 ` AdaMagica
  2021-01-14 14:07                 ` Jeffrey R. Carter
  2021-01-14 14:27                 ` Niklas Holsti
  2 siblings, 0 replies; 32+ messages in thread
From: AdaMagica @ 2021-01-14 13:36 UTC (permalink / raw)


13.8 Machine Code Insertions and C.1 Access to Machine Operations might help.

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

* Re: Record initialisation question
  2021-01-14 13:07               ` DrPi
  2021-01-14 13:36                 ` AdaMagica
@ 2021-01-14 14:07                 ` Jeffrey R. Carter
  2021-01-14 14:09                   ` Jeffrey R. Carter
  2021-01-14 14:27                 ` Niklas Holsti
  2 siblings, 1 reply; 32+ messages in thread
From: Jeffrey R. Carter @ 2021-01-14 14:07 UTC (permalink / raw)


On 1/14/21 2:07 PM, DrPi wrote:
> 
> I can redefine the records with UInt32 instead of System.Address. The problem is 
> : What is the expression to convert from Address to UInt32 without using a 
> function ?

You can use an overlay (usually not recommended):

Addr : constant Address := ...;
U32  : constant Unsigned_32 with Import, Convention => Ada, Address => Addr;

You can also use an untagged union (also not usually recommended), which I would 
need to look up.

-- 
Jeff Carter
"Nobody expects the Spanish Inquisition!"
Monty Python's Flying Circus
22

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

* Re: Record initialisation question
  2021-01-14 14:07                 ` Jeffrey R. Carter
@ 2021-01-14 14:09                   ` Jeffrey R. Carter
  0 siblings, 0 replies; 32+ messages in thread
From: Jeffrey R. Carter @ 2021-01-14 14:09 UTC (permalink / raw)


On 1/14/21 3:07 PM, Jeffrey R. Carter wrote:
> On 1/14/21 2:07 PM, DrPi wrote:
>>
>> I can redefine the records with UInt32 instead of System.Address. The problem 
>> is : What is the expression to convert from Address to UInt32 without using a 
>> function ?
> 
> You can use an overlay (usually not recommended):
> 
> Addr : constant Address := ...;
> U32  : constant Unsigned_32 with Import, Convention => Ada, Address => Addr;

Oops! That should be

    Address => Addr'Address

Sorry.

-- 
Jeff Carter
"Nobody expects the Spanish Inquisition!"
Monty Python's Flying Circus
22

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

* Re: Record initialisation question
  2021-01-14 13:07               ` DrPi
  2021-01-14 13:36                 ` AdaMagica
  2021-01-14 14:07                 ` Jeffrey R. Carter
@ 2021-01-14 14:27                 ` Niklas Holsti
  2021-01-14 16:53                   ` Shark8
                                     ` (2 more replies)
  2 siblings, 3 replies; 32+ messages in thread
From: Niklas Holsti @ 2021-01-14 14:27 UTC (permalink / raw)


On 2021-01-14 15:07, DrPi wrote:
> 
>> The problem is that "static" in Ada means "known at compile time", 
>> while addresses, although static in execution, are generally not known 
>> until link time. A case where assembly language is more powerful :-(
>>
> Or C :(
> I use the manufacturer C code generated by their tool as reference. In 
> C, initializing a structure element with an address is not a problem.


The C compiler emits a relocatable reference to the addressed object, 
and the linker replaces it with the absolute address. An Ada compiler 
should be able to do the same thing when the address of a statically 
allocated object is used to initialize another statically allocated 
object, assuming that the initialization expression is simple enough to 
require no run-time computation. Perhaps part of the reason why that 
does not happen is that System.Address is a private type, and might not 
be an integer type.

Do you (or someone) know if the C language standard guarantees that such 
initializations will be done by the linker, and not by the C start-up 
code that is analogous to Ada elaboration code?

Can you ask your Ada compiler vendor for suggestions? Assuming you have 
support from them.


>>> I have to find a workaround.
>>
>> If addresses are the only problem, and you are in control of the flash 
>> memory lay-out, you might be able to define static Ada constant 
>> expressions that compute ("predict") the addresses of every boot data 
>> structure record. But those expressions would need to use the sizes of 
>> the records, I think, and unfortunately the 'Size of a record type is 
>> not a static expression (IIRC), and that may hold also for the 
>> GNAT-specific 'Max_Size_In_Storage_Units.
> 
> I can redefine the records with UInt32 instead of System.Address. The 
> problem is : What is the expression to convert from Address to UInt32 
> without using a function ?


You could try Unchecked_Conversion or System.Storage_Units.To_Integer.

But my suggestion did not involve such conversions: I assumed that you 
would be able to compute, using static universal-integer expressions, 
the addresses for all your flash objects, and use those directly in the 
record aggregates. This assumes that you are able to define the lay-out 
of all the stuff in the flash. You might then also specify the 'Address 
of each flash object, using those same universal-integer expressions.

Something like this (not tested with a compiler):

    Flash_Start : constant := 16#500#;

    Obj_A_Addr : constant := Flash_Start;

    Obj_B_Addr : constant := Obj_A_Addr + 16#234#;
    -- Here 16#234# is supposed to be the size of Obj_A, so that
    -- Obj_B follows Obj_A in flash.

    Obj_A : constant Dcd_T := (
       Next => Obj_B_Addr,
       ...);

    for Obj_A'Address
       use System.Storage_Elements.To_Address (Obj_A_Addr);

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

* Re: Record initialisation question
  2021-01-14 14:27                 ` Niklas Holsti
@ 2021-01-14 16:53                   ` Shark8
  2021-01-15  7:50                     ` DrPi
  2021-01-14 16:59                   ` Paul Rubin
  2021-01-15  7:49                   ` DrPi
  2 siblings, 1 reply; 32+ messages in thread
From: Shark8 @ 2021-01-14 16:53 UTC (permalink / raw)


Another option, which IIUC should work within the constraints, being Pure:

With
Ada.Unchecked_Conversion,
System;

Package Example with Pure is
    
    Type Address_Stub is null record
      with Size => Standard'Address_Size, Warnings => Off;
    Function Convert(Input : System.Address) return Address_Stub;
    
    Type Stub is null record with Size => 8, Warnings => Off;
    Type Static_Record is record
        Reserved_1 : Stub;
        X, Y       : Integer;
        Self       : Address_Stub;
    end record;
    
    Generic
        Location : System.Address;
    Package Based is
        
        Function Create( X, Y : Integer ) return Static_Record;
    Private
        Function Create( X, Y : Integer ) return Static_Record is
          (Self => Convert( Location ), Reserved_1 => (null record),
           X => X, Y => Y
          );
    End Based;
    
    
Private
    Use System, Ada;
    
    Function Address_Conversion is new Unchecked_Conversion(
       Source => Address,
       Target => Address_Stub
      );
    Function Convert(Input : System.Address) return Address_Stub
      renames Address_Conversion;
End Example;

-- Usage should be something like:
Object_Address : Constant System.Address := (<>);
Package Object_Basis is new Example.Based( Object_Address );
Object : Example.Static_Record := Object_Basis.Create( Params => <> );
For Object'Address use Object'Address;

Sorry but I haven't done much in the way of microcontrolers, so this is best-guess on my part. The restrictions of Pure *should* comport with the restrictions you have though, again IIUC.

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

* Re: Record initialisation question
  2021-01-14 14:27                 ` Niklas Holsti
  2021-01-14 16:53                   ` Shark8
@ 2021-01-14 16:59                   ` Paul Rubin
  2021-01-15  7:49                   ` DrPi
  2 siblings, 0 replies; 32+ messages in thread
From: Paul Rubin @ 2021-01-14 16:59 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> Do you (or someone) know if the C language standard guarantees that
> such initializations will be done by the linker, and not by the C
> start-up code that is analogous to Ada elaboration code?

I don't remember it being required by the standard, but I remember there
was some pain in the standardization process trying to make those kinds
of address initializations flexible while still being doable at link
time.  The original proposal had fancier capabilities than the final
standard did, because during discussions it emerged that the fancy
features couldn't straightforwardly be implemented with the linkers that
people expected to use.

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

* Re: Record initialisation question
  2021-01-12 15:01         ` Shark8
@ 2021-01-14 21:32           ` Simon Wright
  2021-01-14 23:12             ` Shark8
  0 siblings, 1 reply; 32+ messages in thread
From: Simon Wright @ 2021-01-14 21:32 UTC (permalink / raw)


Shark8 <onewingedshark@gmail.com> writes:

> On Tuesday, January 12, 2021 at 4:38:24 AM UTC-7, Simon Wright wrote:
>> Shark8 writes: 
>> 
>> >> I'll try it but I've just faced another problem where a component of 
>> >> another record is the address of the record itself. 
>> > 
>> > Type Example; 
>> > Function To_Address( Input : Access Example ) return System.Address 
>> > with Inline; 
>> > 
>> > Type Example is limited record 
>> > Addr : System.Address := To_Address(Example'Access); 
>> > End record; 
>> > 
>> > Package Cvt is new System.Address_To_Access_Conversions(Example); 
>> > Function To_Address( Input : Access Example ) return System.Address is 
>> > ( Cvt.To_Address( Input.all'Access ) );

>> (what is it with this weird casing "convention" you use? makes the code 
>> quite hard to read ...)
> Really?
> How so?

Just looking at the first line, I see

   Type Example;

and I don't recognise it as Ada; I think that this is a textual comment
saying that this is an example relating in some way to types. Similar,
but a little less distracting, with other keywords throughout.

What is the convention? Is it perhaps that the first word on a line gets
capitalised? but then, in the second line, we have

   ... Input : Access Example ) return ...

and the third line starts with "with".

So it's just some keywords that get capitalised.

Basically, I find it jarring and distracting.

We would disagree about spacing round parentheses as well.

De gustibus ...!

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

* Re: Record initialisation question
  2021-01-14 21:32           ` Simon Wright
@ 2021-01-14 23:12             ` Shark8
  0 siblings, 0 replies; 32+ messages in thread
From: Shark8 @ 2021-01-14 23:12 UTC (permalink / raw)


On Thursday, January 14, 2021 at 2:32:43 PM UTC-7, Simon Wright wrote:
> 
> So it's just some keywords that get capitalised. 
> 
> Basically, I find it jarring and distracting. 
> 
> We would disagree about spacing round parentheses as well. 
> 
> De gustibus ...!
Fair enough.
I'm not a fan of plain-text in files/directories being the "central core" in programming-as-practiced; the idea that we should have such ridiculous dependencies as '/' vs '\' vs ':' as directory-path separators in our foundational tools is ridiculous, as is the "tab vs space" war (which is itself an microcosm of formatting in-general) -- IMO we should have IDEs that are *integrated* development-environments, with as little dependency on the host system as possible, but *also* with as little dependency on things like ASCII-7/UTF16/UTF-8/Shift_JIS as possible: ie text as the central idea of a program's representation. -- The reliance on text means that we get idiotic things like search-and-replace renamings taking "minute" and getting "minimumute" because of text. (Better in some IDEs, true.) But keeping source as text means things like 'diff' flag non-meaningful changes, like changing from spaces to tabs in your editor flagging every line as a "change".

So, TL;DR this wouldn't be a problem if we had good tools. (Which would include embedding code/data.)

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

* Re: Record initialisation question
  2021-01-14 14:27                 ` Niklas Holsti
  2021-01-14 16:53                   ` Shark8
  2021-01-14 16:59                   ` Paul Rubin
@ 2021-01-15  7:49                   ` DrPi
  2 siblings, 0 replies; 32+ messages in thread
From: DrPi @ 2021-01-15  7:49 UTC (permalink / raw)


> 
> You could try Unchecked_Conversion or System.Storage_Units.To_Integer.
> 
They are not compatible with no elaboration code.
Generally, using a function call is not compatible with no elaboration code.

> But my suggestion did not involve such conversions: I assumed that you 
> would be able to compute, using static universal-integer expressions, 
> the addresses for all your flash objects, and use those directly in the 
> record aggregates. This assumes that you are able to define the lay-out 
> of all the stuff in the flash. You might then also specify the 'Address 
> of each flash object, using those same universal-integer expressions.
> 
> Something like this (not tested with a compiler):
> 
>     Flash_Start : constant := 16#500#;
> 
>     Obj_A_Addr : constant := Flash_Start;
> 
>     Obj_B_Addr : constant := Obj_A_Addr + 16#234#;
>     -- Here 16#234# is supposed to be the size of Obj_A, so that
>     -- Obj_B follows Obj_A in flash.
> 
>     Obj_A : constant Dcd_T := (
>        Next => Obj_B_Addr,
>        ...);
> 
>     for Obj_A'Address
>        use System.Storage_Elements.To_Address (Obj_A_Addr);
> 
System.Storage_Elements is not compatible with no elaboration code.

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

* Re: Record initialisation question
  2021-01-14 16:53                   ` Shark8
@ 2021-01-15  7:50                     ` DrPi
  2021-01-15 18:15                       ` Shark8
  0 siblings, 1 reply; 32+ messages in thread
From: DrPi @ 2021-01-15  7:50 UTC (permalink / raw)


Le 14/01/2021 à 17:53, Shark8 a écrit :
> Another option, which IIUC should work within the constraints, being Pure:
> 
> With
> Ada.Unchecked_Conversion,
> System;
> 
> Package Example with Pure is
>      
>      Type Address_Stub is null record
>        with Size => Standard'Address_Size, Warnings => Off;
>      Function Convert(Input : System.Address) return Address_Stub;
>      
>      Type Stub is null record with Size => 8, Warnings => Off;
>      Type Static_Record is record
>          Reserved_1 : Stub;
>          X, Y       : Integer;
>          Self       : Address_Stub;
>      end record;
>      
>      Generic
>          Location : System.Address;
>      Package Based is
>          
>          Function Create( X, Y : Integer ) return Static_Record;
>      Private
>          Function Create( X, Y : Integer ) return Static_Record is
>            (Self => Convert( Location ), Reserved_1 => (null record),
>             X => X, Y => Y
>            );
>      End Based;
>      
>      
> Private
>      Use System, Ada;
>      
>      Function Address_Conversion is new Unchecked_Conversion(
>         Source => Address,
>         Target => Address_Stub
>        );
>      Function Convert(Input : System.Address) return Address_Stub
>        renames Address_Conversion;
> End Example;
> 
> -- Usage should be something like:
> Object_Address : Constant System.Address := (<>);
> Package Object_Basis is new Example.Based( Object_Address );
> Object : Example.Static_Record := Object_Basis.Create( Params => <> );
> For Object'Address use Object'Address;
> 
> Sorry but I haven't done much in the way of microcontrolers, so this is best-guess on my part. The restrictions of Pure *should* comport with the restrictions you have though, again IIUC.
> 
Unchecked_Conversion is not compatible with no elaboration code.

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

* Re: Record initialisation question
  2021-01-15  7:50                     ` DrPi
@ 2021-01-15 18:15                       ` Shark8
  2021-01-16 10:28                         ` DrPi
  0 siblings, 1 reply; 32+ messages in thread
From: Shark8 @ 2021-01-15 18:15 UTC (permalink / raw)


On Friday, January 15, 2021 at 12:50:41 AM UTC-7, DrPi wrote:
> Unchecked_Conversion is not compatible with no elaboration code.
I find that surprising.
Ada.Unchecked_Conversion is defined by the LRM as a compiler-intrinsic, with the Pure pragma*:

generic
   type Source(<>) is limited private;
   type Target(<>) is limited private;
function Ada.Unchecked_Conversion(S : Source) return Target
   with Convention => Intrinsic;
pragma Pure(Ada.Unchecked_Conversion);

The GNAT source has, as its last three lines:
pragma No_Elaboration_Code_All (Ada.Unchecked_Conversion);
pragma Pure (Ada.Unchecked_Conversion);
pragma Import (Intrinsic, Ada.Unchecked_Conversion);

So, if you are generating elaboration-code, then GNAT is broken.

* IIUC, this (Intrinsic+Pure) should make it essentially equivalent to C's bitwise reinterpretation-cast, and [IIRC] should qualify for 'static function call'.

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

* Re: Record initialisation question
  2021-01-15 18:15                       ` Shark8
@ 2021-01-16 10:28                         ` DrPi
  0 siblings, 0 replies; 32+ messages in thread
From: DrPi @ 2021-01-16 10:28 UTC (permalink / raw)


Le 15/01/2021 à 19:15, Shark8 a écrit :
> On Friday, January 15, 2021 at 12:50:41 AM UTC-7, DrPi wrote:
>> Unchecked_Conversion is not compatible with no elaboration code.
> I find that surprising.
> Ada.Unchecked_Conversion is defined by the LRM as a compiler-intrinsic, with the Pure pragma*:
> 
> generic
>     type Source(<>) is limited private;
>     type Target(<>) is limited private;
> function Ada.Unchecked_Conversion(S : Source) return Target
>     with Convention => Intrinsic;
> pragma Pure(Ada.Unchecked_Conversion);
> 
> The GNAT source has, as its last three lines:
> pragma No_Elaboration_Code_All (Ada.Unchecked_Conversion);
> pragma Pure (Ada.Unchecked_Conversion);
> pragma Import (Intrinsic, Ada.Unchecked_Conversion);
> 
> So, if you are generating elaboration-code, then GNAT is broken.
> 
> * IIUC, this (Intrinsic+Pure) should make it essentially equivalent to C's bitwise reinterpretation-cast, and [IIRC] should qualify for 'static function call'.
> 
I made new tests.
You are right, Unchecked_Conversion() is not the culprit.
When I tried it, I got 'violation of restriction "No_Elaboration_Code"' 
due to other statements but didn't realized it.

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

* Re: Record initialisation question
  2021-01-09 10:46 ` Dmitry A. Kazakov
  2021-01-10 16:41   ` DrPi
@ 2021-01-17 17:03   ` DrPi
  2021-01-17 23:55     ` Shark8
  1 sibling, 1 reply; 32+ messages in thread
From: DrPi @ 2021-01-17 17:03 UTC (permalink / raw)


Le 09/01/2021 à 11:46, Dmitry A. Kazakov a écrit :
> On 2021-01-09 10:30, DrPi wrote:
>> Hi,
>>
>> I'm working on a µP BSP. The boot sequence of this µP requires byte 
>> structures located in FLASH memory.
>> For example :
>>
>>     type t_Dcd_Header is record
>>        Tag     : Unsigned_8  := 16#D2#;
>>        Length  : Unsigned_16 := 4;      -- Length in byte of the DCD 
>> structure (this header included)
>>        Version : Unsigned_8  := 16#41#;
>>     end record
>>       with Object_Size => 32,
>>            Bit_Order => System.Low_Order_First;
>>
>>     for t_Dcd_Header use record
>>        Tag     at 0 range  0 .. 7;
>>        Length  at 0 range  8 .. 23;
>>        Version at 0 range 24 .. 31;
>>     end record;
>>
>> The t_Dcd_Header is part of t_Dcd record.
>> The Length field of t_Dcd_Header must contain the length of t_Dcd.
>>
>>     Dcd : constant t_Dcd :=
>>      ( Dcd_Header => ( Length => ???, -- Length of Dcd
>>                        others => <>),
>>        ...
>>      );
>>
>> Is there a way to automatically set Length ?
> 
> t_Dcd'Max_Size_In_Storage_Elements?
> 
I finally had success using Object_Size attribute.

I have to set Object_Size of all records.
I also have to specify the Size of enums.
Then I can use t_Dcd'Object_Size.

I had a very bad surprise : Enums are used in some records. One enum did 
not have the Size specified (8 bits). All was working as if it was not 
present except I had to assign it a value. I had to lower the 
Object_Size and the enum was removed from the result (its value was not 
present in memory mapping). After setting Size => 8 to this enum, all 
went well.

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

* Re: Record initialisation question
  2021-01-09  9:30 Record initialisation question DrPi
  2021-01-09 10:46 ` Dmitry A. Kazakov
  2021-01-09 15:44 ` Niklas Holsti
@ 2021-01-17 17:08 ` DrPi
  2 siblings, 0 replies; 32+ messages in thread
From: DrPi @ 2021-01-17 17:08 UTC (permalink / raw)


Le 09/01/2021 à 10:30, DrPi a écrit :
> Hi,
> 
> I'm working on a µP BSP. The boot sequence of this µP requires byte 
> structures located in FLASH memory.
> For example :
> 
>     type t_Dcd_Header is record
>        Tag     : Unsigned_8  := 16#D2#;
>        Length  : Unsigned_16 := 4;      -- Length in byte of the DCD 
> structure (this header included)
>        Version : Unsigned_8  := 16#41#;
>     end record
>       with Object_Size => 32,
>            Bit_Order => System.Low_Order_First;
> 
>     for t_Dcd_Header use record
>        Tag     at 0 range  0 .. 7;
>        Length  at 0 range  8 .. 23;
>        Version at 0 range 24 .. 31;
>     end record;
> 
> The t_Dcd_Header is part of t_Dcd record.
> The Length field of t_Dcd_Header must contain the length of t_Dcd.
> 
>     Dcd : constant t_Dcd :=
>      ( Dcd_Header => ( Length => ???, -- Length of Dcd
>                        others => <>),
>        ...
>      );
> 
> Is there a way to automatically set Length ?
> Dcd goes in a dedicated .txt section.
> 
> Nicolas

I tried to use a C module as a workaround.
I added C to my .gpr file : for Languages use ("Ada", "C");
The C module is compiled correctly. However, it is not linked. This is 
not a surprise since it contains no object used by Ada modules.

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

* Re: Record initialisation question
  2021-01-17 17:03   ` DrPi
@ 2021-01-17 23:55     ` Shark8
  2021-01-18 20:02       ` DrPi
  0 siblings, 1 reply; 32+ messages in thread
From: Shark8 @ 2021-01-17 23:55 UTC (permalink / raw)


On Sunday, January 17, 2021 at 10:03:34 AM UTC-7, DrPi wrote:
> 
> I had a very bad surprise : Enums are used in some records. One enum did 
> not have the Size specified (8 bits). All was working as if it was not 
> present except I had to assign it a value. I had to lower the 
> Object_Size and the enum was removed from the result (its value was not 
> present in memory mapping). After setting Size => 8 to this enum, all 
> went well.

This is not too bad a restriction; simply have two identical-except-for-size types.
NEEDED_SIZE : Constant := 2;
Type Base_Enumeration is (a,b,c); -- Uses defaults.
Type Boot_Enumeration is new Base_Enumeration with Size => NEEDED_SIZE;

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

* Re: Record initialisation question
  2021-01-17 23:55     ` Shark8
@ 2021-01-18 20:02       ` DrPi
  2021-01-19  5:50         ` Randy Brukardt
  0 siblings, 1 reply; 32+ messages in thread
From: DrPi @ 2021-01-18 20:02 UTC (permalink / raw)


Le 18/01/2021 à 00:55, Shark8 a écrit :
> On Sunday, January 17, 2021 at 10:03:34 AM UTC-7, DrPi wrote:
>>
>> I had a very bad surprise : Enums are used in some records. One enum did
>> not have the Size specified (8 bits). All was working as if it was not
>> present except I had to assign it a value. I had to lower the
>> Object_Size and the enum was removed from the result (its value was not
>> present in memory mapping). After setting Size => 8 to this enum, all
>> went well.
> 
> This is not too bad a restriction; simply have two identical-except-for-size types.
> NEEDED_SIZE : Constant := 2;
> Type Base_Enumeration is (a,b,c); -- Uses defaults.
> Type Boot_Enumeration is new Base_Enumeration with Size => NEEDED_SIZE;
> 
That's a clever construct. I have to remember it.
In my case I don't need 2 types since the only place the enum is used is 
in the record which describes the memory mapping.

The bad surprise is that the enum is completely discarded from the 
memory mapping when its size is not specified.


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

* Re: Record initialisation question
  2021-01-18 20:02       ` DrPi
@ 2021-01-19  5:50         ` Randy Brukardt
  0 siblings, 0 replies; 32+ messages in thread
From: Randy Brukardt @ 2021-01-19  5:50 UTC (permalink / raw)


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

"DrPi" <314@drpi.fr> wrote in message 
news:6005e946$0$13558$426a74cc@news.free.fr...
> Le 18/01/2021 à 00:55, Shark8 a écrit :
>> On Sunday, January 17, 2021 at 10:03:34 AM UTC-7, DrPi wrote:
>>>
>>> I had a very bad surprise : Enums are used in some records. One enum did
>>> not have the Size specified (8 bits). All was working as if it was not
>>> present except I had to assign it a value. I had to lower the
>>> Object_Size and the enum was removed from the result (its value was not
>>> present in memory mapping). After setting Size => 8 to this enum, all
>>> went well.
>>
>> This is not too bad a restriction; simply have two 
>> identical-except-for-size types.
>> NEEDED_SIZE : Constant := 2;
>> Type Base_Enumeration is (a,b,c); -- Uses defaults.
>> Type Boot_Enumeration is new Base_Enumeration with Size => NEEDED_SIZE;
>>
> That's a clever construct. I have to remember it.
> In my case I don't need 2 types since the only place the enum is used is 
> in the record which describes the memory mapping.
>
> The bad surprise is that the enum is completely discarded from the memory 
> mapping when its size is not specified.

That sounds like a bug, I don't think data is supposed to be ignored because 
of a too-small Size clause (instead, the program ought to be rejected).

                            Randy.


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

end of thread, other threads:[~2021-01-19  5:50 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-09  9:30 Record initialisation question DrPi
2021-01-09 10:46 ` Dmitry A. Kazakov
2021-01-10 16:41   ` DrPi
2021-01-11 21:48     ` Shark8
2021-01-12 11:38       ` Simon Wright
2021-01-12 15:01         ` Shark8
2021-01-14 21:32           ` Simon Wright
2021-01-14 23:12             ` Shark8
2021-01-14 12:58       ` DrPi
2021-01-17 17:03   ` DrPi
2021-01-17 23:55     ` Shark8
2021-01-18 20:02       ` DrPi
2021-01-19  5:50         ` Randy Brukardt
2021-01-09 15:44 ` Niklas Holsti
2021-01-10 16:53   ` DrPi
2021-01-10 19:30     ` Niklas Holsti
2021-01-10 21:27       ` DrPi
2021-01-10 22:14         ` Niklas Holsti
2021-01-11 17:46           ` DrPi
2021-01-11 20:58             ` Niklas Holsti
2021-01-14 13:07               ` DrPi
2021-01-14 13:36                 ` AdaMagica
2021-01-14 14:07                 ` Jeffrey R. Carter
2021-01-14 14:09                   ` Jeffrey R. Carter
2021-01-14 14:27                 ` Niklas Holsti
2021-01-14 16:53                   ` Shark8
2021-01-15  7:50                     ` DrPi
2021-01-15 18:15                       ` Shark8
2021-01-16 10:28                         ` DrPi
2021-01-14 16:59                   ` Paul Rubin
2021-01-15  7:49                   ` DrPi
2021-01-17 17:08 ` DrPi

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