Difference between revisions of "Nil"

From Lazarus wiki
Jump to navigationJump to search
m (→‎Application: Fix typo)
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
{{Nil}}
 
{{Nil}}
  
The [[Reserved word|reserved word]] <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> represents the special [[Constant|value]] of a pointer [[Variable|variable]] not pointing anywhere particular.
+
The [[Reserved word|reserved word]] <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> represents the special [[Constant|value]] of a pointer [[Variable|variable]] not pointing anywhere in particular.
 
In [[FPC]] it is implemented as <syntaxhighlight lang="pascal" enclose="none">pointer(0)</syntaxhighlight> (the numeric value <syntaxhighlight lang="pascal" enclose="none">0</syntaxhighlight>), however the programmer is not supposed to use this fact.
 
In [[FPC]] it is implemented as <syntaxhighlight lang="pascal" enclose="none">pointer(0)</syntaxhighlight> (the numeric value <syntaxhighlight lang="pascal" enclose="none">0</syntaxhighlight>), however the programmer is not supposed to use this fact.
In other programming languages, e.g in C, someone writes <syntaxhighlight lang="C" enclose="none">null</syntaxhighlight>.
+
In other programming languages, e.g in C, you write <syntaxhighlight lang="C" enclose="none">null</syntaxhighlight>.
The terms “null pointer” or “nil pointer” are used interchangeably, even among [[Standard Pascal|Pascal]] programmers.
+
The terms “null pointer” and “nil pointer” are used interchangeably, even among [[Standard Pascal|Pascal]] programmers.
  
 
There are two popular explanations of <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight>'s etymology.
 
There are two popular explanations of <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight>'s etymology.
One says, nil is short for the Latin word “nihil” meaning “nothing”.
+
One says, <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> is short for the Latin word “nihil” meaning “nothing”.
 
The other suggests, <syntaxhighlight lang="pascal" enclose="none">NIL</syntaxhighlight> is an English acronym standing for “not in list.”
 
The other suggests, <syntaxhighlight lang="pascal" enclose="none">NIL</syntaxhighlight> is an English acronym standing for “not in list.”
Maybe, since the German word „Null“ stands for the digit “zero”, and in order to avoid confusion, or to distinguish between the concept and value, the word <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> was chosen.
+
Maybe, since the German word „Null“ stands for the digit “zero”, and in order to avoid confusion, or to distinguish between the concept and value, the word <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> was chosen. At any rate, this does not have any implications while programming.
At any rate, this does not have any implications while programming.
 
  
== assignment compatibility ==
+
== Assignment compatibility ==
<syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> can be of course [[Becomes|assigned]] to a [[Pointer|<syntaxhighlight lang="pascal" enclose="none">pointer</syntaxhighlight>]] variable, but also to other types, which are in fact pointers, but their usage is more convenient.
+
 
For instance [[Dynamic array|dynamic arrays]] or [[Class|classes]]:
+
<syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> can be of course [[Becomes|assigned]] to a [[Pointer|<syntaxhighlight lang="pascal" enclose="none">pointer</syntaxhighlight>]] variable, but also to other types, which are in fact pointers, but their usage is more convenient. For instance [[Dynamic array|dynamic arrays]] or [[Class|classes]]:
<syntaxhighlight lang="pascal" line highlight="8,10,12,14">
+
 
 +
<syntaxhighlight lang="pascal" line highlight="10,12,14,16,18">
 
program nilDemo(input, output, stderr);
 
program nilDemo(input, output, stderr);
 
var
 
var
Line 21: Line 21:
 
chk: array of boolean;
 
chk: array of boolean;
 
msg: PChar;
 
msg: PChar;
 +
prc: TProcedure;
 
obj: TObject;
 
obj: TObject;
 
begin
 
begin
 +
// point to nothing
 
loc := nil;
 
loc := nil;
 
// clears dynamic array
 
// clears dynamic array
Line 28: Line 30:
 
// empty string
 
// empty string
 
msg := nil;
 
msg := nil;
 +
// procedural variable not referencing any procedure
 +
prc := nil;
 
// loses reference to object
 
// loses reference to object
 
obj := nil;
 
obj := nil;
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
Note, assigning <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> to a dynamic array is equivalent to the statement <syntaxhighlight lang="pascal" enclose="none">setLength(dynamicArrayVariable, 0)</syntaxhighlight>.
 
The values of the array are lost.
 
However, there is no comparable mechanism for other types, e.g. assigning <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> to a <syntaxhighlight lang="pascal" enclose="none">class</syntaxhighlight> or <syntaxhighlight lang="pascal" enclose="none">pointer</syntaxhighlight> variable ''will not'' release (de-allocate) the memory that is possibly been occupied by the referenced structure.
 
  
== application ==
+
Note, assigning <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> to a dynamic array is virtually equivalent to the [[Procedure|procedure]] invocation <syntaxhighlight lang="pascal" enclose="none">setLength(dynamicArrayVariable, 0)</syntaxhighlight>.
In a Pascal's manner you usually do not write expressions like <syntaxhighlight lang="pascal" enclose="none">pointerVariable = nil</syntaxhighlight> but use more explanatory identifiers.
+
The values of the array are lost, if the reference count of <syntaxhighlight lang="pascal" enclose="none">dynamicArrayVariable</syntaxhighlight> has hit zero.
The routine [[Assigned|<syntaxhighlight lang="pascal" enclose="none">system.assigned</syntaxhighlight>]] will be replaced by the exact same expression, but conceals the fact a variable is (''implemented'' as) a pointer.
+
However, there is no comparable mechanism for other types, e.g. assigning <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> to a <syntaxhighlight lang="pascal" enclose="none">class</syntaxhighlight> or <syntaxhighlight lang="pascal" enclose="none">pointer</syntaxhighlight> variable ''will not'' release (i.e. de-allocate) the memory that is possibly been occupied by the referenced structure.
So its usage is optional.
+
 
 +
== Application ==
 +
 
 +
In Pascal you usually do not write expressions like <syntaxhighlight lang="pascal" enclose="none">pointerVariable =: nil</syntaxhighlight> but use more explanatory [[Identifier|identifiers]].
 +
The [[Function|function]] [[Assigned|<syntaxhighlight lang="pascal" enclose="none">system.assigned</syntaxhighlight>]] will be replaced by the exact same expression, but conceals the fact a variable is (''implemented'' as) a pointer. So its usage is optional.
  
The routine [[FreeAndNil|<syntaxhighlight lang="pascal" enclose="none">sysUtils.freeAndNil</syntaxhighlight>]] will call a class's <syntaxhighlight lang="pascal" enclose="none">free</syntaxhighlight> routine and assign <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> to the handed pointer (variable of type <syntaxhighlight lang="pascal" enclose="none">class</syntaxhighlight>).
+
The [[Routine|routine]] [[FreeAndNil|<syntaxhighlight lang="pascal" enclose="none">SysUtils.FreeAndNil</syntaxhighlight>]] will call a class's <syntaxhighlight lang="pascal" enclose="none">free</syntaxhighlight> routine and assign <syntaxhighlight lang="pascal" enclose="none">nil</syntaxhighlight> to the handed pointer (variable of type <syntaxhighlight lang="pascal" enclose="none">class</syntaxhighlight>).
Although it is a good idea, to clear pointers which do not point to valid objects anymore, this can make debugging more difficult, since there is no pointer available, pointing to the address a certain object used to be.
+
Although it is a good idea, to clear pointers which do not point to valid objects anymore, this can make debugging more difficult since there is no pointer available pointing to the address at which a certain object used to be.
 +
 
 +
== See also ==
  
== see also ==
 
 
* [[^|<syntaxhighlight lang="pascal" enclose="none">^</syntaxhighlight>]]
 
* [[^|<syntaxhighlight lang="pascal" enclose="none">^</syntaxhighlight>]]
 
* {{Doc|package=RTL|unit=system|identifier=returnnilifgrowheapfails|text=<syntaxhighlight lang="pascal" enclose="none">system.returnNilIfGrowHeapFails</syntaxhighlight>}}
 
* {{Doc|package=RTL|unit=system|identifier=returnnilifgrowheapfails|text=<syntaxhighlight lang="pascal" enclose="none">system.returnNilIfGrowHeapFails</syntaxhighlight>}}
 
* <syntaxhighlight lang="pascal" enclose="none">{$objectChecks on}</syntaxhighlight>
 
* <syntaxhighlight lang="pascal" enclose="none">{$objectChecks on}</syntaxhighlight>
 
+
* [[Nullable types|nullable types]]
[[Category:Code]]
 

Revision as of 05:50, 17 October 2020

Deutsch (de) English (en) suomi (fi) français (fr) русский (ru) 中文(中国大陆)‎ (zh_CN)

The reserved word nil represents the special value of a pointer variable not pointing anywhere in particular. In FPC it is implemented as pointer(0) (the numeric value 0), however the programmer is not supposed to use this fact. In other programming languages, e.g in C, you write null. The terms “null pointer” and “nil pointer” are used interchangeably, even among Pascal programmers.

There are two popular explanations of nil's etymology. One says, nil is short for the Latin word “nihil” meaning “nothing”. The other suggests, NIL is an English acronym standing for “not in list.” Maybe, since the German word „Null“ stands for the digit “zero”, and in order to avoid confusion, or to distinguish between the concept and value, the word nil was chosen. At any rate, this does not have any implications while programming.

Assignment compatibility

nil can be of course assigned to a pointer variable, but also to other types, which are in fact pointers, but their usage is more convenient. For instance dynamic arrays or classes:

 1program nilDemo(input, output, stderr);
 2var
 3	loc: pointer;
 4	chk: array of boolean;
 5	msg: PChar;
 6	prc: TProcedure;
 7	obj: TObject;
 8begin
 9	// point to nothing
10	loc := nil;
11	// clears dynamic array
12	chk := nil;
13	// empty string
14	msg := nil;
15	// procedural variable not referencing any procedure
16	prc := nil;
17	// loses reference to object
18	obj := nil;
19end.

Note, assigning nil to a dynamic array is virtually equivalent to the procedure invocation setLength(dynamicArrayVariable, 0). The values of the array are lost, if the reference count of dynamicArrayVariable has hit zero. However, there is no comparable mechanism for other types, e.g. assigning nil to a class or pointer variable will not release (i.e. de-allocate) the memory that is possibly been occupied by the referenced structure.

Application

In Pascal you usually do not write expressions like pointerVariable =: nil but use more explanatory identifiers. The function system.assigned will be replaced by the exact same expression, but conceals the fact a variable is (implemented as) a pointer. So its usage is optional.

The routine SysUtils.FreeAndNil will call a class's free routine and assign nil to the handed pointer (variable of type class). Although it is a good idea, to clear pointers which do not point to valid objects anymore, this can make debugging more difficult since there is no pointer available pointing to the address at which a certain object used to be.

See also