For 16 alignment my assumptions are correct, but 32 seems to fail on some platforms.
Which means that 32 align may not be supported, even in trunk:
{$mode objfpc}
{$assertions on}
{$codealign varmin=32}
{$codealign varmax=32}
const
N = 100000;
var
ptrs: array of Pointer;
i: Integer;
r16, r32: NativeUInt;
bad16, bad32: Integer;
minAddr, maxAddr: NativeUInt;
begin
SetLength(ptrs, N);
bad16 := 0;
bad32 := 0;
minAddr := High(NativeUInt);
maxAddr := 0;
for i := 0 to N - 1 do
begin
ptrs[i] := AllocMem(100);
r16 := NativeUInt(ptrs[i]) mod 16;
r32 := NativeUInt(ptrs[i]) mod 32;
if r16 <> 0 then Inc(bad16);
if r32 <> 0 then Inc(bad32);
if NativeUInt(ptrs[i]) < minAddr then minAddr := NativeUInt(ptrs[i]);
if NativeUInt(ptrs[i]) > maxAddr then maxAddr := NativeUInt(ptrs[i]);
end;
Writeln('allocations=', N);
Writeln('bad16=', bad16);
Writeln('bad32=', bad32);
Writeln('min=', minAddr);
Writeln('max=', maxAddr);
Assert(bad16 = 0, 'Some allocations were not 16-byte aligned');
Assert(bad32 = 0, 'Some allocations were not 32-byte aligned');
for i := 0 to N - 1 do
FreeMem(ptrs[i]);
end.
I think I have to re-run my example code with other alignment settings. It may very well be that the alignment for getmem and allocmem depends on platform and e.g. 32/64. I used two 64 bit platforms and no 32 bit. So I may be wrong.
If you compile for 32 bit, I expect in that case that 16 fails and only 8 succeeds.
Anyway you can do the alignment also by hand.
[edit: yes on 64 bit Windows and Linux the alignment is always 16, also when 4 or 8 is specified.
So my code is a wrong assumption. I will later show some code to do the alignment manually.