Reputation: 11
I'm not clear what the Alignment clause in Ada does. See an example below. I have a 40 bit sized record, and I'm not sure what happens when I use the clause.
type Knots_Status_Record is
record
Value : Knots;
Status : Statuses;
end record;
for Knots_Status_Record use
record
Value at 0 range 0 .. 31; -- 32
Status at 0 range 32 .. 39; -- 8
end record;
for Knots_Status_Record'Alignment use 1;
Upvotes: 1
Views: 3543
Reputation: 1080
Alignment of x
ensure the address is divisible by x
Data'Aligment = x <=> Data'Address mod x = 0
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
with System.Storage_Elements; use System.Storage_Elements;
with Ada.Assertions; use Ada.Assertions;
with Ada.Command_Line; use Ada.Command_Line;
procedure Main is
function Get_Argument_1 return Natural is
begin
return Natural'Value (Argument (1));
exception
when others => raise Program_Error with "Missing natural argument(1)";
end;
-- Change this size to see what happens for every address aligment under 64.
Float_Array_Size : Natural := Get_Argument_1;
type Float_Array is array (Integer range 1 .. Float_Array_Size) of Float;
F4 : Float_Array;
for F4'Alignment use 4;
F8 : Float_Array;
for F8'Alignment use 8;
F16 : Float_Array;
for F16'Alignment use 16;
F32 : Float_Array;
for F32'Alignment use 32;
F64 : Float_Array;
for F64'Alignment use 64;
begin
-- Check if a 4 aligned address could be a 64 aligned.
Put (Integer(To_Integer(F4'Address) mod 64));
-- Sometimes it is, sometimes not, depends partly of Float_Array_Size.
New_Line;
Put (Integer(To_Integer(F8'Address) mod 64));
New_Line;
Put (Integer(To_Integer(F16'Address) mod 64));
New_Line;
Put (Integer(To_Integer(F32'Address) mod 64));
New_Line;
Put (Integer(To_Integer(F64'Address) mod 64));
-- Lets see if the address is aligned to 64 storage units.
Assert (Integer(To_Integer(F64'Address) mod 64) = 0);
end;
http://www.adaic.org/resources/add_content/standards/05rm/html/RM-13-3.html http://www.adaic.org/resources/add_content/standards/05rm/html/RM-K.html
The value of this attribute is of type universal_integer, and nonnegative; zero means that the object is not necessarily aligned on a storage element boundary. If X'Alignment is not zero, then X is aligned on a storage unit boundary and X'Address is an integral multiple of X'Alignment (that is, the Address modulo the Alignment is zero).
https://docs.adacore.com/gnat_rm-docs/html/gnat_rm/gnat_rm/representation_clauses_and_pragmas.html https://gcc.gnu.org/onlinedocs/gnat_rm/Alignment-Clauses.html
GNAT requires that all alignment clauses specify a power of 2, and all default alignments are always a power of 2. The default alignment values are as follows:
https://en.wikibooks.org/wiki/Ada_Programming/Attributes/'Alignment
X'Alignment is an Ada attribute where X is any memory-allocated object or type. This attribute controls the address values used for objects. The alignment must be non-negative. A value of zero means that the object need not be allocated at the boundary of a storage units. Otherwise the address is a multiple of X's alignment. The alignment of an object may be set.
Upvotes: 4