Если бы я написал
type u1 is range 0 .. 1;
type Index is range 0 .. 499999;
type U1Array is array(Index) of u1;
Могу ли я предположить, что это будет битовый вектор, который эффективно упаковывает отдельные экземпляры u1? Т.е. 8 бит/байт?
Лучше проверить, чем предполагать. Проверить представление типа данных можно с помощью -gnatR2
(см. здесь). Быстрая проверка ниже показывает, что U1Array
не будет битовым вектором. Размер его компонентов составит 8 [бит], общий размер — 4 000 000 [бит].
Чтобы иметь его как битовый вектор, вам нужно сделать его «упакованным» массивом (см. RM 13.2). Размер упакованного массива составит 500 000 [бит]. Размер его компонентов будет равен 1 [бит].
foo.ads
package Foo is
type u1 is range 0 .. 1;
type Index is range 0 .. 499999;
type U1Array is array(Index) of u1;
type U1PackedArray is array(Index) of u1 with Pack;
end Foo;
выход
$ gcc -c foo.ads -gnatR2
Representation information for unit Foo (spec)
----------------------------------------------
for U1'Object_Size use 8;
for U1'Value_Size use 1;
for U1'Alignment use 1;
for Index'Object_Size use 32;
for Index'Value_Size use 19;
for Index'Alignment use 4;
for U1array'Size use 4000000;
for U1array'Alignment use 1;
for U1array'Component_Size use 8;
for U1packedarray'Size use 500000;
for U1packedarray'Alignment use 1;
for U1packedarray'Component_Size use 1;
Поскольку U1 является целочисленным типом со знаком (определенным с помощью range
), его базовый тип U1'Base будет примерно симметричен относительно нуля, включая как минимум диапазон -1 .. 1
. В большинстве систем будет выбран подходящий тип оборудования, обычно один байт, -128 .. 127
или эквивалент Interfaces.Integer_8. Этот базовый тип, скорее всего, будет использоваться для представления компонентов типа U1 при отсутствии каких-либо предложений представления.
Когда вам нужны конкретные представления в Аде, следует сказать так:
type U1 is mod 2 with Size => 1;
type U1array is array (Index) of U1 with Component_Size => U1'Size, Size => Index'Last + 1;
Затем компилятор будет использовать один бит для каждого значения массива, упакованного до битового уровня.
Обратите внимание, что аспект Pack — это всего лишь подсказка компилятора; компилятор может игнорировать это или упаковывать вещи менее полно, чем это возможно. С другой стороны, Size и Component_Size должны соблюдаться полностью или отвергаться, если компилятор не может этого сделать.
Верно! Мой 0 .. 1
мог ввести меня в заблуждение, заставив думать, что на самом деле я определяю один битовый тип. Позже я подумал, что mod 2
будет делать то же самое, но просто решил, что это вопрос предпочтений. Как вы заметили, это может быть не так. Очень ценный ответ!
Также, вероятно, хорошей идеей будет либо поместить аспект размера в U1, либо аспект Component_Size в U1PackedArray.