Difference between revisions of "SizeOf"

From Free Pascal wiki
Jump to navigationJump to search
Line 147: Line 147:
 
It returns an object's size as it is determined by the class's type definition.
 
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.
 
Additional memory that's allocated by constructors or any method, is not taken into account.
Note, classes might contain dynamic arrays or ANSI strings, too.
+
Note, that classes might contain dynamic arrays or ANSI strings, too.
  
 
[[Category:Code]]
 
[[Category:Code]]

Revision as of 12:09, 15 May 2018

Template:Translate 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:

 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.

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

 1program sizeOfDemo(input, output, stderr);
 2
 3function sum(const f: array of integer): int64;
 4{$ifdef CPUx86_64}
 5assembler;
 6{$asmMode intel}
 7asm
 8	// ensure f is in a particular register
 9	mov rsi, f                       // rsi := f  (pointer to an array)
10	
11	// check for nil pointer (i.e. empty array)
12	test rsi, rsi                    // rsi = 0 ?
13	jz @sum_abort                    // if rsi = nil then goto abort
14	
15	// load last index of array [theoretically there is highF]
16	mov rcx, [rsi] - sizeOf(sizeInt) // rcx := (rsi - sizeOf(sizeInt))^
17	
18	// load first element, since loop condition won't reach it
19	{$if sizeOf(integer) = 4}
20	mov eax, [rsi]                   // edx := rsi^
21	{$elseif sizeOf(integer) = 2}
22	mov ax, [rsi]                    // ax := rsi^
23	{$else} {$error unexpected integer size} {$endif}
24	
25@sum_iterate:
26	{$if sizeOf(integer) = 4}
27	mov edx, [rsi + rcx * 4]         // rdx := (rsi + 4 * (rcx-1))^
28	{$elseif sizeOf(integer) = 2}
29	mov dx, [rsi + rcx * 2]          // dx := (rsi + 2 * (rcx-1))^
30	{$else} {$error unexpected scale factor} {$endif}
31	
32	add rax, rdx                     // rax := rax + rdx
33	
34	jo @sum_abort                    // if OF then goto abort
35	
36	loop @sum_iterate                // dec(rcx)
37	                                 // if rcx <> 0 then goto iterate
38	
39	// TODO: j @done somehow compiles as jo @done
40	jno @sum_done                    // goto done
41	
42@sum_abort:
43	// load neutral element for addition
44	xor rax, rax                     // rax := 0
45	
46@sum_done:
47end;
48{$else}
49unimplemented;
50begin
51	sum := 0;
52end;
53{$endif}
54
55var
56	f: array of integer;
57
58begin
59	setLength(f, 5);
60	f[0] := 2;
61	f[1] := 5;
62	f[2] := 11;
63	f[3] := 17;
64	f[4] := 23;
65	writeLn(sum(f));
66end.

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).

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.