The file rtl/inc/dynarr.inc has
type
{ don't add new fields, the size is used }
{ to calculate memory requirements }
pdynarray = ^tdynarray;
{ removed packed here as
1) both fields have typically the same size (2, 4 or 8 bytes), if this is not the case, packed
should be used only for this architecture
2) the memory blocks are sufficiently well aligned
3) in particular 64 bit CPUs which require natural alignment suffer from
the packed as it causes each field access being split in 8 single loads and appropriate shift operations
}
tdynarray = { packed } record
refcount : ptrint;
high : tdynarrayindex;
end;
1/2 I've tried to understand the usage of refcount, but the Pascal code made the mission difficult. The questions were related to negative refcount values like: is refcount allowed to be negative, can refcount become negative in any way, and so on. Looking at the code, my conclusion was that refcount's minimum value should be zero. When it's zero, something went wrong somewhere and an exception has to be raised. For normal usage a minimum value of 1 is needed.
Many times developers use signed integers although those variables are expected to always use unsigned integers. It's this experience with other Pascal reviewed code that made me think twice about tdynarray's refcount.
If refcount should never be negative, I ask you why refcount is ptrint instead of ptruint. If it was ptruint, programmers would have understood that refcount is designed to store values greater or equal to zero. No more questions about negative values, the code would have been easier to understand.
2/2 tdynarrayindex(tdynarray.high) points to a signed integer, too. I wonder if tdynarray.high is allowed to store negative values. The -1 value of high is the result of function fpc_dynarray_high, not the value stored at tdynarray.high.
function fpc_dynarray_high(p : pointer) : tdynarrayindex;[Public,Alias:'FPC_DYNARRAY_HIGH']; compilerproc;
begin
if assigned(p) then
fpc_dynarray_high:=pdynarray(p-sizeof(tdynarray))^.high
else
fpc_dynarray_high:=-1;
end;