Wiki-kopiopeilipalvelin

Tämä on pascal.chatin wikin peilipalvelin. Muokkaus, historia ja kirjautuminen ovat siellä.

SizeOf/fi

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

Käännösaikainen funktio SizeOf arvioi tietyn tyyppisen nimen tai muuttujan tunnisteen koon tavuina (byte).

sizeOf voi olla myös käännösaikaisissa laajennuksissa, kuten kääntäjädirektiiveissä.

Käyttö

SizeOf esiintyy erityisesti assembly-kielessä tai kun suoritetaan muistin manuaalista allokointia:

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.

Rakenteellisten tietotyyppien suora käsittely assembly-kielellä edellyttää myös tietojen (datan) koon tuntemusta:

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.

FPC:llä integer kokonaisluvun koko riippuu käytetystä kääntäjän moodista. SizeOf(sizeInt) lisättiin kuitenkin vain esittelyä varten. {$ifdef CPUx86_64} haarassa sizeOf(sizeInt) on aina 8.

Vertailevia huomautuksia

Dynaamiset taulukot ja vastaavat

Koskadynaamiset taulukot toteutetaan osoittimina are realized as pointers to a block on the heap, sizeOf arvioi osoittimen koon. Dynaamisen taulukon koon määrittämiseksi. SizeOf on käytettävä yhdessä funktion length kanssa.

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.

Lähestymistapa on sama ANSI strings merkkijonoille (riippuen myös {$longstrings} kääntäjän kytkimen tilasta, jota merkitään myös string). Ei saa unohtaa, että dynaamisissa taulukoissa on hallintatiedot viitatun hyötykuorman edessä. Joten jos todella halutaan tietää, kuinka paljon muistia on varattu yhdelle taulukolla, niin on otettava huomioon myös suurin (viimeinen indeksi taulukossa) ja viitearvojen kentät.

Luokat

Luokat (class) ovat myös viitteitä. Luokka TObject tarjoaa funktion instanceSize. Se palauttaa olion koon, koska se määräytyy luokan tyypin määritelmän mukaan. Lisämuistia, jota rakentajat (constructor) ovat käyttäneet tai mikä tahansa metodi, ei oteta huomioon. Huomaa, että luokat voivat sisältää myös dynaamisia taulukoita tai ANSI-merkkijonoja.


From the Free Pascal wiki, page "SizeOf/fi", 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.

Versio 1, viimeksi muokannut WikiArchive .