Difference between revisions of "SizeOf/ru"

From Lazarus wiki
Jump to navigationJump to search
Line 10: Line 10:
 
== Использование ==
 
== Использование ==
  
<syntaxhighlight lang="pascal" enclose="none">sizeOf</syntaxhighlight> is especially encountered in [[Assembler|assembly language]] or when doing manual allocation of memory:
+
<syntaxhighlight lang="pascal" enclose="none">sizeOf</syntaxhighlight> особенно часто встречается в [[Assembler| ассемблере]] или при ручном выделении памяти:
 
<syntaxhighlight lang="pascal" line highlight="20,31">
 
<syntaxhighlight lang="pascal" line highlight="20,31">
 
program sizeOfDemo(input, output, stderr);
 
program sizeOfDemo(input, output, stderr);
Line 45: Line 45:
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
Direct handling of structured data types in assembly language requires awareness of data sizes, too:
+
Прямая обработка структурированных типов данных на ассемблере также требует знания размеров данных:
 
<syntaxhighlight lang="pascal" line highlight="19,22,24,33,35">
 
<syntaxhighlight lang="pascal" line highlight="19,22,24,33,35">
 
program sizeOfDemo(input, output, stderr);
 
program sizeOfDemo(input, output, stderr);
Line 57: Line 57:
 
{$asmMode intel}
 
{$asmMode intel}
 
asm
 
asm
// ensure f is in a particular register
+
// убеждаемся, что f находится в конкретном регистре
mov rsi, f                      // rsi := f  (pointer to an array)
+
mov rsi, f                      // rsi := f  (указатель на массив)
 
 
// check for nil pointer (i.e. empty array)
+
// проверка на пустой (nil) указатель (напр. пустой массив)
 
test rsi, rsi                    // rsi = 0 ?
 
test rsi, rsi                    // rsi = 0 ?
jz @sum_abort                    // if rsi = nil then goto abort
+
jz @sum_abort                    // если rsi = nil, то переходим к @sum_abort
 
 
// load last index of array [theoretically there is highF]
+
// загружаем последний индекс массива [теоретически это верхний элемент массива F]
 
mov rcx, [rsi] - sizeOf(sizeInt) // rcx := (rsi - sizeOf(sizeInt))^
 
mov rcx, [rsi] - sizeOf(sizeInt) // rcx := (rsi - sizeOf(sizeInt))^
 
 
// load first element, since loop condition won't reach it
+
// загружаем первый элемент, поскольку условие цикла не дойдет до него
 
{$if sizeOf(integer) = 4}
 
{$if sizeOf(integer) = 4}
 
mov eax, [rsi]                  // eax := rsi^
 
mov eax, [rsi]                  // eax := rsi^
 
{$elseif sizeOf(integer) = 2}
 
{$elseif sizeOf(integer) = 2}
 
mov ax, [rsi]                    // ax := rsi^
 
mov ax, [rsi]                    // ax := rsi^
{$else} {$error unexpected integer size} {$endif}
+
{$else} {$error неожиданный целочисленный размер} {$endif}
 
 
// we're done, if f doesn't contain any more elements
+
// мы сделаем, если f не содержит больше элементов
 
test rcx, rcx                    // rcx = 0 ?
 
test rcx, rcx                    // rcx = 0 ?
jz @sum_done                    // if high(f) = 0 then goto done
+
jz @sum_done                    // если high(f) = 0,  то переходим к @sum_done
 
 
 
@sum_iterate:
 
@sum_iterate:
Line 83: Line 83:
 
{$elseif sizeOf(integer) = 2}
 
{$elseif sizeOf(integer) = 2}
 
mov dx, [rsi + rcx * 2]          // dx := (rsi + 2 * rcx)^
 
mov dx, [rsi + rcx * 2]          // dx := (rsi + 2 * rcx)^
{$else} {$error unexpected scale factor} {$endif}
+
{$else} {$error неожиданный масштабный коэффициент} {$endif}
 
 
 
add rax, rdx                    // rax := rax + rdx
 
add rax, rdx                    // rax := rax + rdx
 
 
jo @sum_abort                    // if OF then goto abort
+
jo @sum_abort                    // если OF, то переходим к @sum_abort
 
 
 
loop @sum_iterate                // dec(rcx)
 
loop @sum_iterate                // dec(rcx)
                                // if rcx <> 0 then goto iterate
+
                                // если rcx <> 0,  то переходим к @sum_iterate
 
 
jmp @sum_done                    // goto done
+
jmp @sum_done                    // переходим к @sum_done
 
 
 
@sum_abort:
 
@sum_abort:
// load neutral element for addition
+
// загружаем нейтральный элемент для прибавления
 
xor rax, rax                    // rax := 0
 
xor rax, rax                    // rax := 0
 
 
Line 111: Line 111:
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
With [[FPC]] the size of an {{Doc|package=RTL|unit=system|identifier=integer|text=<syntaxhighlight lang="pascal" enclose="none">integer</syntaxhighlight>}} depends on the used [[Compiler Mode|compiler mode]].
+
 
However, <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> was inserted for demonstration purposes only.
+
В [[FPC/ru|FPC]] размер {{Doc|package=RTL|unit=system|identifier=integer|text=<syntaxhighlight lang="pascal" enclose="none">integer</syntaxhighlight>}} зависит от используемого [[Compiler_Mode|режима компилятора]].
In the <syntaxhighlight lang="pascal" enclose="none">{$ifdef CPUx86_64}</syntaxhighlight> branch <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> is always <syntaxhighlight lang="pascal" enclose="none">8</syntaxhighlight>.
+
Однако  <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> был вставлен только для демонстрационных целей. В ветке <syntaxhighlight lang="pascal" enclose="none">{$ifdef CPUx86_64}</syntaxhighlight> <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> всегда равен <syntaxhighlight lang="pascal" enclose="none">8</syntaxhighlight>.
  
 
== comparative remarks ==
 
== comparative remarks ==

Revision as of 23:11, 23 April 2019

Deutsch (de) English (en) suomi (fi) русский (ru)

Функция времени компиляции sizeOf вычисляет размер в байтах данного имени типа данных или идентификатора переменной.

sizeOf также может применяться в выражениях времени компиляции внутри директив компилятора.


Использование

sizeOf особенно часто встречается в ассемблере или при ручном выделении памяти:

 1program sizeOfDemo(input, output, stderr);
 2
 3{$typedAddress on}
 4
 5uses
 6	heaptrc;
 7
 8type
 9	s = record
10		c: char;
11		i: longint;
12	end;
13
14var
15	x: ^s;
16
17begin
18	returnNilIfGrowHeapFails := true;
19	
20	getMem(x, sizeOf(x));
21	
22	if not assigned(x) then
23	begin
24		writeLn(stderr, 'malloc for x failed');
25		halt(1);
26	end;
27	
28	x^.c := 'r';
29	x^.i := -42;
30	
31	freeMem(x, sizeOf(x));
32end.

Прямая обработка структурированных типов данных на ассемблере также требует знания размеров данных:

 1program sizeOfDemo(input, output, stderr);
 2
 3type
 4	integerArray = array of integer;
 5
 6function sum(const f: integerArray): int64;
 7{$ifdef CPUx86_64}
 8assembler;
 9{$asmMode intel}
10asm
11	// убеждаемся, что f находится в конкретном регистре
12	mov rsi, f                       // rsi := f  (указатель на массив)
13	
14	// проверка на пустой (nil) указатель (напр. пустой массив)
15	test rsi, rsi                    // rsi = 0 ?
16	jz @sum_abort                    // если rsi = nil, то переходим к @sum_abort
17	
18	// загружаем последний индекс массива [теоретически это верхний элемент массива F]
19	mov rcx, [rsi] - sizeOf(sizeInt) // rcx := (rsi - sizeOf(sizeInt))^
20	
21	// загружаем первый элемент, поскольку условие цикла не дойдет до него
22	{$if sizeOf(integer) = 4}
23	mov eax, [rsi]                   // eax := rsi^
24	{$elseif sizeOf(integer) = 2}
25	mov ax, [rsi]                    // ax := rsi^
26	{$else} {$error неожиданный целочисленный размер} {$endif}
27	
28	// мы сделаем, если f не содержит больше элементов
29	test rcx, rcx                    // rcx = 0 ?
30	jz @sum_done                     // если high(f) = 0,  то переходим к @sum_done
31	
32@sum_iterate:
33	{$if sizeOf(integer) = 4}
34	mov edx, [rsi + rcx * 4]         // edx := (rsi + 4 * rcx)^
35	{$elseif sizeOf(integer) = 2}
36	mov dx, [rsi + rcx * 2]          // dx := (rsi + 2 * rcx)^
37	{$else} {$error неожиданный масштабный коэффициент} {$endif}
38	
39	add rax, rdx                     // rax := rax + rdx
40	
41	jo @sum_abort                    // если OF, то переходим к @sum_abort
42	
43	loop @sum_iterate                // dec(rcx)
44	                                 // если rcx <> 0,  то переходим к @sum_iterate
45	
46	jmp @sum_done                    // переходим к @sum_done
47	
48@sum_abort:
49	// загружаем нейтральный элемент для прибавления
50	xor rax, rax                     // rax := 0
51	
52@sum_done:
53end;
54{$else}
55unimplemented;
56begin
57	sum := 0;
58end;
59{$endif}
60
61begin
62	writeLn(sum(integerArray.create(2, 5, 11, 17, 23)));
63end.

В FPC размер integer зависит от используемого режима компилятора. Однако sizeOf(sizeInt) был вставлен только для демонстрационных целей. В ветке {$ifdef CPUx86_64} sizeOf(sizeInt) всегда равен 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.

 1program dynamicArraySizeDemo(input, output, stderr);
 2
 3uses
 4	sysUtils;
 5
 6resourcestring
 7	enteredN = 'You''ve entered %0:d integers';
 8	totalData = 'occupying a total of %0:d Bytes.';
 9
10var
11	f: array of longint;
12
13begin
14	setLength(f, 0);
15	
16	while not eof() do
17	begin
18		setLength(f, length(f) + 1);
19		readLn(f[length(f)]);
20	end;
21	
22	writeLn(format(enteredN, [length(f)]));
23	writeLn(format(totalData, [length(f) * sizeOf(f[0])]));
24end.

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.