Sign in Join
Wiki copytemporary

SizeOf

Deutsch · English · Suomi · Русский

The compile-time function sizeOf evaluates to the size in Bytes of a given data type name or variable identifier.

sizeOf can appear in compile-time expressions, inside compiler directives, too.

usage

sizeOf is especially encountered in assembly language or when doing manual allocation of memory:

pascal
program sizeOfDemo(input, output, stderr);

{$typedAddress on}

uses
    heaptrc;

type
    s = record
        c: char;
        i: longint;
    end;

var
    x: ^s;

begin
    returnNilIfGrowHeapFails := true;
    
    getMem(x, sizeOf(x));
    
    if not assigned(x) then
    begin
        writeLn(stderr, 'malloc for x failed');
        halt(1);
    end;
    
    x^.c := 'r';
    x^.i := -42;
    
    freeMem(x, sizeOf(x));
end.

Direct handling of structured data types in assembly language requires awareness of data sizes, too:

pascal
program sizeOfDemo(input, output, stderr);

type
    integerArray = array of integer;

function sum(const f: integerArray): int64;
{$ifdef CPUx86_64}
assembler;
{$asmMode intel}
asm// ensure f is in a particular register// rsi := f  (pointer to an array)// check for nil pointer (i.e. empty array)// rsi = 0 ?// if rsi = nil then goto abort// load last index of array [theoretically there is highF]// rcx := (rsi - sizeOf(sizeInt))^// load first element, since loop condition won't reach it{$if sizeOf(integer) = 4}// eax := rsi^{$elseif sizeOf(integer) = 2}// ax := rsi^{$else}{$error unexpected integer size}{$endif}// we're done, if f doesn't contain any more elements// rcx = 0 ?// if high(f) = 0 then goto done{$if sizeOf(integer) = 4}// edx := (rsi + 4 * rcx)^{$elseif sizeOf(integer) = 2}// dx := (rsi + 2 * rcx)^{$else}{$error unexpected scale factor}{$endif}// rax := rax + rdx// if OF then goto abort// dec(rcx)// if rcx <> 0 then goto iterate// goto done// load neutral element for addition// rax := 0
    // ensure f is in a particular register
    mov rsi, f                       // rsi := f  (pointer to an array)
    
    // check for nil pointer (i.e. empty array)
    test rsi, rsi                    // rsi = 0 ?
    jz @sum_abort                    // if rsi = nil then goto abort
    
    // load last index of array [theoretically there is highF]
    mov rcx, [rsi] - sizeOf(sizeInt) // rcx := (rsi - sizeOf(sizeInt))^
    
    // load first element, since loop condition won't reach it
    {$if sizeOf(integer) = 4}
    mov eax, [rsi]                   // eax := rsi^
    {$elseif sizeOf(integer) = 2}
    mov ax, [rsi]                    // ax := rsi^
    {$else} {$error unexpected integer size} {$endif}
    
    // we're done, if f doesn't contain any more elements
    test rcx, rcx                    // rcx = 0 ?
    jz @sum_done                     // if high(f) = 0 then goto done
    
@sum_iterate:
    {$if sizeOf(integer) = 4}
    mov edx, [rsi + rcx * 4]         // edx := (rsi + 4 * rcx)^
    {$elseif sizeOf(integer) = 2}
    mov dx, [rsi + rcx * 2]          // dx := (rsi + 2 * rcx)^
    {$else} {$error unexpected scale factor} {$endif}
    
    add rax, rdx                     // rax := rax + rdx
    
    jo @sum_abort                    // if OF then goto abort
    
    loop @sum_iterate                // dec(rcx)
                                     // if rcx <> 0 then goto iterate
    
    jmp @sum_done                    // goto done
    
@sum_abort:
    // load neutral element for addition
    xor rax, rax                     // rax := 0
    
@sum_done:
END;
{$else}
unimplemented;
begin
    sum := 0;
end;
{$endif}

begin
    writeLn(sum(integerArray.create(2, 5, 11, 17, 23)));
end.

With FPC the size of an integer depends on the used compiler mode. However, sizeOf(sizeInt) was inserted for demonstration purposes only. In the {$ifdef CPUx86_64} branch sizeOf(sizeInt) is always 8.

comparative remarks

dynamic arrays and alike

Since dynamic arrays are realized as pointers to a block on the heap, sizeOf evaluates to the pointer's size. In order to determine the array's size – of its data – sizeOf has to be used in conjunction with the function length.

pascal
program dynamicArraySizeDemo(input, output, stderr);

uses
    sysUtils;

resourcestring
    enteredN = 'You''ve entered %0:d integers';
    totalData = 'occupying a total of %0:d Bytes.';

var
    f: array of longint;

begin
    setLength(f, 0);
    
    while not eof() do
    begin
        setLength(f, length(f) + 1);
        readLn(f[length(f)]);
    end;
    
    writeLn(format(enteredN, [length(f)]));
    writeLn(format(totalData, [length(f) * sizeOf(f[0])]));
end.

The approach is the same for ANSI strings (depending on the {$longstrings} compiler switch state possibly denoted by string, too). Do not forget that dynamic arrays have management data in front of the referenced payload block. So if you really want to know, how much memory has been reserved for one array, you would have to take the high (last index in array) and reference count fields into account, too.

classes

Classes as well are pointers. The class TObject provides the function instanceSize. It returns an object's size as it is determined by the class's type definition. Additional memory that's allocated by constructors or any method, is not taken into account. Note, that classes might contain dynamic arrays or ANSI strings, too.

see also


From the Free Pascal wiki, page "SizeOf", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 1, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.