Sign in Join
Wiki copytemporary

Pointer: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Pointer

OldNewLine
1+**Pointer** has two meanings in [[FPC|Free Pascal]]:
2+
3+- term or concept for a class of types and [[Variable|variables]] of those types
4+- a simple [[Data type|data type]] that can hold the address of any data type
5+
6+## Concept
7+
8+A **pointer** is a variable that contains the memory address of a local or global variable, or the memory address of a value or complex object that has been created and stored in the heap part of a program's memory layout. It can be said to be a [[reference]] for the value/variable, or that it "points to" the value/variable. For any data type, a pointer type for that data can be declared using operator **[[^]]** in front of the data type. With the {\$TYPEDADDRESS ON} [[Compiler directive|compiler directive]] set (advisable), pointers can only hold the addresses of variables or values of the same type that they have been declared to point to.
9+
10+Pointer variables are assigned the address of a variable with the **[[@]]** operator and they are assigned the address of a value/object on the heap by using the output of the New procedure. To access, for reading or writing, the data "pointed to" by a pointer variable, you *de-reference* it with the **[[^]]** operator.
11+
12+``` pascal
13+program test_pointer_wiki2;
14+{$TYPEDADDRESS ON}
15+var
16+ a : Integer = 100;
17+ b : Real = 10.5;
18+ ptrToInt : PInteger; // PInteger is a pointer type declared in the RTL
19+ // which can only point to Integer value/variab
20+ ptrToInt2 : ^Integer; // the general format for declaring a pointer type
21+begin
22+ //ptrToInt := @b; // compile error with {$TYPEDADDRESS ON}
23+ ptrToInt := @a;
24+ //Writeln(ptrToInt); // compiler error: Error: Can't read or write variables of this type
25+ Writeln(ptrToInt^); // prints 100
26+ New(ptrToInt2); // allocate an un-initialized Integer on the heap
27+ Writeln(ptrToInt2^); // writes random integer value
28+ ptrToInt2^ := 222; // assign a value to the heap allocated integer
29+ Writeln(ptrToInt2^); // prints 222
30+end.
31+```
32+
33+## Data Type
34+
35+Back to [[Data type|data types]].
36+
37+The **Pointer** data type is a simple type which can contain the address of a variable or value of **any** data type. This is in contrast to typed pointer variables (e.g. PInteger) that can only point to a variables or values of a specific type with compiler directive {\$TYPEDADDRESS ON} . For example:
38+
39+``` pascal
40+{$TYPEDADRESS ON}
41+Var
42+ a : Integer = 20;
43+ b : Real = 20.5;
44+ c : Boolean = true;
45+ ptr : Pointer;
46+begin
47+ ptr := @a; // valid to hold Integer address
48+ ptr := @b; // valid to hold Real address
49+ ptr := @c; // valid to hold Boolean address
50+end.
51+```
52+
53+But, before a Pointer variable with a value can be used, it must be
54+
55+1. cast to the type of the value or variable that it points to
56+2. de-referenced with the **^** operator
57+
58+For example:
59+
60+``` pascal
61+Var
62+ a : Integer = 20;
63+ ptr : Pointer;
64+begin
65+ ptr := @a; // valid to hold Integer address
66+ //Writeln(ptr); // Invalid - will not compile
67+ // Error: Can't read or write variables of this type
68+ //Writeln( ptr^); // Error: Can't read or write variables of this type
69+ // Just de-referencing a Pointer variable is not sufficient
70+ Writeln( PInteger(ptr)^); // After cast, then de-reference: prints 20
71+end.
72+```
73+
74+## Predeclared Pointer Types
75+
76+The [[System unit]] of the standard [[RTL|Runtime Library]] declares a number of pointer types for the built-in variables including:
77+
78+``` pascal
79+ PSmallInt = ^Smallint;
80+ PShortInt = ^Shortint;
81+ PInteger = ^Integer;
82+ PByte = ^Byte;
83+ PWord = ^word;
84+ PDWord = ^DWord;
85+ PLongWord = ^LongWord;
86+ PLongint = ^Longint;
87+ PCardinal = ^Cardinal;
88+ PQWord = ^QWord;
89+ PBoolean = ^Boolean;
90+```
91+
92+## How Pointer variables are initialized
93+
94+Q: I would like to understand the default initialization behavior more - what is the value Pointer variable is being initialized to?
95+
96+A (by FPC developer **PascalDragon**):
97+
98+Pointer variables/fields by themselves are not initialized at all. There value will depend upon where they are used:
99+
100+- if it is a global variable or part of a record/object that's declared as a global variable it will be Nil unless an explicit value is assigned to it, because that's what global variables without explicit value initializers are initialized to
101+- if it is a field of a class then it will be Nil, because class instances are zeroed before the constructor is run
102+- if it is a local variable or part of a record/object that's declared as a local variable and there is no value initializer then the value will be undefined and can be anything
103+- if it's a variable that is allocated using GetMem or New or is part of a record/object that is allocated that way then the value will be undefined and can be anything
104+
105+In the later two cases you need to explicitly set the value yourself.
106+
107+A2 (by forum member **Warfley**):
108+
109+It's not just for pointer variables the case pointers are basic unmanaged variables, so they behave like other basic unmanaged variables (like float, integer or boolean), if they are not members of a block that explicitly guarantees initialization (like global variables or class members which are guaranteed to be 0), the value is undefined and must be initialized by you.
110+
111+## See also
112+
113+- Usage of [[Pointers]]
114+- <http://www.freepascal.org/docs-html/ref/refse15.html>
115+
116+---
117+*From the Free Pascal wiki, page "Pointer", as it stood on 2023-03-03 after a change by Alextp, 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](/wiki-contact).*

Back to history