### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: What is the goal of assigned() ?  (Read 2069 times)

#### Fred vS

• Hero Member
• Posts: 2196
##### Re: What is the goal of assigned() ?
« Reply #45 on: April 07, 2021, 08:29:24 pm »
@lainz
Quote
We don't have nullable types in FPC?
Code: Pascal  [Select][+][-]
1. uses Variants;
2.
3. var
4.   V: Variant;
5. begin
6.   V := null;
7.   if VarIsNull(V) then
8.     //...
9. end;

Hello GetMem.

OK, your solution does not produce a crash  with VarIsNull(V) if V was not initialized.

But the problem remains because if V was not initialized, the result of  VarIsNull(V)  will be false (because initialized with random):

Tested:

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2.   var
3.   V: Variant;
4. begin
5.   V := null;
6.   if VarIsNull(V) then caption := 'V is null' else  caption := 'V is NOT null' ;
7.
8. end;

Gives as TForm1.caption :
Quote
'V is null'

But without initialization of V:

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2.   var
3.   V: Variant;
4. begin
5.   if VarIsNull(V) then caption := 'V is null' else  caption := 'V is NOT null' ;
6. end;

Gives as TForm1.caption :
Quote
'V is NOT null'

« Last Edit: April 07, 2021, 08:46:07 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### Gustavo 'Gus' Carreno

• Sr. Member
• Posts: 448
• Professional amateur ;-P
##### Re: What is the goal of assigned() ?
« Reply #46 on: April 07, 2021, 09:20:09 pm »
Hey Fre;D,

In my view, Assigned and VarIsNull are opposites both semantically and logically.

One tests if something is assigned, hence not null. The other tests if something is null, hence not assigned.

I could be wrong, but are you not comparing apples and oranges?

If so, please correct me. I may be looking at this quite erroneously.

Cheers,
Gus
Lazarus 2.1.0(trunk) FPC 3.3.1(trunk) Ubuntu 20.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.0(stable) Ubuntu 20.10 64b Dark Theme
http://github.com/gcarreno

#### Fred vS

• Hero Member
• Posts: 2196
##### Re: What is the goal of assigned() ?
« Reply #47 on: April 07, 2021, 09:28:11 pm »
Hey Fre;D,

In my view, Assigned and VarIsNull are opposites both semantically and logically.

One tests if something is assigned, hence not null. The other tests if something is null, hence not assigned.

I could be wrong, but are you not comparing apples and oranges?

If so, please correct me. I may be looking at this quite erroneously.

Cheers,
Gus

Hello Gus.

Of course Assigned and VarIsNull are opposites both semantically and logically.

I was talking how both treat a local variable not initialized.
And both set as not nil/null a local variable not initialized (because, like explained in previous posts, a not initialized local variable is filled with random byte and not with nil/null).

Fre;D
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### GetMem

• Hero Member
• Posts: 3984
##### Re: What is the goal of assigned() ?
« Reply #48 on: April 07, 2021, 09:31:19 pm »
@Fred vS
Quote
But the problem remains because if V was not initialized, the result of  VarIsNull(V)  will be false (because initialized with random):
By default, a variant is unassigned or empty. Unassigned is the a lowest state in the variant hierarchy.  A null variant is already an assigned one, but has the value null.

#### Gustavo 'Gus' Carreno

• Sr. Member
• Posts: 448
• Professional amateur ;-P
##### Re: What is the goal of assigned() ?
« Reply #49 on: April 07, 2021, 09:35:43 pm »
Hey All,

After Remy pointed out this blog post: Assigned or not Assigned, that is the question..., my conclusions are:
• Always initialize your variables with nil, well, where appropriate of course
• Only reliably use Assigned for it's intended use: method addresses
• The opposite of nil can be either assigned of pointing at random memory contents

This, nonetheless, leaves me with one burning question, or two:

How can I test if a variable has a valid instance of an object if the opposite of nil is not always assigned?
In my code, I can follow my rule of always initialising to nil, but how can I test that if I'm handed something from a black box of someone else's code?

Cheers,
Gus
Lazarus 2.1.0(trunk) FPC 3.3.1(trunk) Ubuntu 20.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.0(stable) Ubuntu 20.10 64b Dark Theme
http://github.com/gcarreno

#### Fred vS

• Hero Member
• Posts: 2196
##### Re: What is the goal of assigned() ?
« Reply #50 on: April 07, 2021, 09:38:33 pm »
@Fred vS
Quote
But the problem remains because if V was not initialized, the result of  VarIsNull(V)  will be false (because initialized with random):
By default, a variant is unassigned or empty. Unassigned is the a lowest state in the variant hierarchy.  A null variant is already an assigned one, but has the value null.

OK, perfect, for me all is perfectly clear now.

So the conclusion should be: could it be possible to envisage a new function ?:

Code: Pascal  [Select][+][-]
1.  isinitialized(myvariable)

Quote
No, you should take care to initialize you local variable by your self.

Many thanks to everybody, it was a very instructive topic.

Fre;D

I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### GetMem

• Hero Member
• Posts: 3984
##### Re: What is the goal of assigned() ?
« Reply #51 on: April 07, 2021, 09:53:23 pm »
Quote
So the conclusion should be: could it be possible to envisage a new function ?:  isinitialized(myvariable)
You don't have to envision it, it's already implemented:
Code: Pascal  [Select][+][-]
1. uses variants;
2.
3. var
4.   V: Variant;
5. begin
6.   if V = Variants.Unassigned then
7.     //...
8. end;

The code from your previous post, should look like this:
Code: Pascal  [Select][+][-]
1. var
2.   V: Variant;
3. begin
4.   if (V = Variants.Unassigned) or (V = Variants.Null) then //if VarIsEmpty(V) or VarIsNull(V) then
5.     Caption := 'V is nothing'
6.   else
7.     Caption := 'V is something';
8. end;

Quote
No, you should take care to initialize you local variable by your self.
I agree with this one. Please try the following code with and without Sum := 0
Code: Pascal  [Select][+][-]
1. var
2.   Sum, I: Integer;
3. begin
4.   Sum := 0;
5.   for I := 1 to 10 do
6.      Sum := Sum + I;
7.   ShowMessage(Sum.ToString);
8. end;
Is there any difference between the two results?
« Last Edit: April 07, 2021, 10:01:59 pm by GetMem »

#### lainz

• Hero Member
• Posts: 4005
• Leandro Diaz
##### Re: What is the goal of assigned() ?
« Reply #52 on: April 07, 2021, 10:21:44 pm »
Well like in Javascript.
Seems that does not work for classes?

Well in a class we can implement it ourselves?
https://lainz.github.io/ - My Website

#### Fred vS

• Hero Member
• Posts: 2196
##### Re: What is the goal of assigned() ?
« Reply #53 on: April 07, 2021, 10:25:18 pm »
Hello GetMem.

Finally, I get THE answer of my original first post, first question:

Quote
So what must be used to know if something was not assigned by something ( even not nil )?

Your answer is exactly what I asked for "common local" variables ( not variants ) but it seems to exist only for variants:

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. var
3.  V: Variant;
4. begin
5.   if (V = Variants.Unassigned) then
6.      Caption := 'V is nothing'
7.    else
8.      Caption := 'V is something';
9. end;

It works perfectly as wanted: TForm1.caption =  'V is nothing'

Quote
Please try the following code with and without Sum := 0
Is there any difference between the two results?

This, with or without  Sum := 0, gives same result: caption = 55;

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. var
3.   Sum, I: Integer;
4. begin
5.   Sum := 0;   // with or without I get 55
6.   for I := 1 to 10 do
7.      Sum := Sum + I;
8.   Caption := Sum.ToString;
9. end;

Fre;D
« Last Edit: April 07, 2021, 10:56:56 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### Fred vS

• Hero Member
• Posts: 2196
##### Re: What is the goal of assigned() ?
« Reply #54 on: April 07, 2021, 11:34:29 pm »
Hello everybody.

Now that I am a local variable (included variant) Guru, this are my conclusions:

The names used for properties are not always logical.

For example: Variants.Unassigned will check if the variant was initialized.
Imho, Variants.Unassigned should be renamed Variants.Uinitialized.

And for the famous assigned(), I would rename it into notnil().

[EDIT] And even if I agree that it is a good practice to always initialize local variables, there are cases when not all the variables will be used and to share memory only initialize it when needed.

Something for all variables like initialized(thevar) that will check, like variants do with Variants.Unassigned , if  the variable was initialized or no should be useful.

Voila, this to annoy my colleagues the gurus.

Thanks to everybody, it was a beautiful travel.

Fre;D
« Last Edit: April 08, 2021, 12:04:25 am by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### lainz

• Hero Member
• Posts: 4005
• Leandro Diaz
##### Re: What is the goal of assigned() ?
« Reply #55 on: April 08, 2021, 02:00:29 am »
I suppose you can add an extension and name it as you want?

In JavaScript is called undefined and null, so every language puts the name the devs wants, there is no standard

But... Is not the same as nil, so I prefer null instead.
https://lainz.github.io/ - My Website

#### lainz

• Hero Member
• Posts: 4005
• Leandro Diaz
##### Re: What is the goal of assigned() ?
« Reply #56 on: April 08, 2021, 02:35:25 am »
Hello GetMem.

Finally, I get THE answer of my original first post, first question:

Quote
So what must be used to know if something was not assigned by something ( even not nil )?

Your answer is exactly what I asked for "common local" variables ( not variants ) but it seems to exist only for variants:
...

Yes... but it not solves for your original snippet?

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. var
3. abitmap : TBGRABitmap;
4. begin
5. abitmap.free;
6. end;
https://lainz.github.io/ - My Website

#### Fred vS

• Hero Member
• Posts: 2196
##### Re: What is the goal of assigned() ?
« Reply #57 on: April 08, 2021, 03:30:04 am »
Hello GetMem.

Finally, I get THE answer of my original first post, first question:

Quote
So what must be used to know if something was not assigned by something ( even not nil )?

Your answer is exactly what I asked for "common local" variables ( not variants ) but it seems to exist only for variants:
...

Yes... but it not solves for your original snippet?

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. var
3. abitmap : TBGRABitmap;
4. begin
5. abitmap.free;
6. end;

Yes, no.

It does not solve the thing, but now I know that with variant there is a trick (variant.unassigned) and for the other variables, the only solution is to initialize the var like this:

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. var
3. abitmap : TBGRABitmap = nil;  // here initialize
4. begin
5. abitmap.free;
6. end;
« Last Edit: April 08, 2021, 03:37:04 am by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

#### GetMem

• Hero Member
• Posts: 3984
##### Re: What is the goal of assigned() ?
« Reply #58 on: April 08, 2021, 06:55:51 am »
@Fred vS
Quote
This, with or without  Sum := 0, gives same result: caption = 55;
Please see attached image with Lazarus Trunk/FPC 3.2.0. So I always initialize everything.

@Fred vS, @lainz
Many of your arguments are valid. Indeed it seems strange that you have to initialize some variables others are initialized by default, but this is how pascal works. In my opinion every language has it's own peculiarity, for example I found  "=", "==", "===" in javascript hilarious.

#### PascalDragon

• Hero Member
• Posts: 2895
• Compiler Developer
##### Re: What is the goal of assigned() ?
« Reply #59 on: April 08, 2021, 09:07:25 am »
We don't have nullable types in FPC?

With FPC 3.2.1 and newer:

Code: Pascal  [Select][+][-]
1. program tnull;
2.
3. {\$mode objfpc}{\$H+}
4.
5. uses
6.   Nullable;
7.
8. procedure Test;
9. var
10.   n: specialize TNullable<LongInt>;
11. begin
12.   Writeln(n.HasValue);
13.   n := 42;
14.   Writeln(n.HasValue);
15.   Writeln(LongInt(n));
16.   n.Clear;
17.   Writeln(n.HasValue);
18. end;
19.
20. begin
21.   Test;
22. end.

Output:

Code: [Select]
`FALSETRUE42FALSE`
But the problem remains because if V was not initialized, the result of  VarIsNull(V)  will be false (because initialized with random):

Not quite right. Like e.g. AnsiString and dynamic arrays a Variant is a managed type. Thus it's initialized by the compiler/RTL to a default value which (as you noticed) is not Null, but Unassigned. You can test for it with VarIsEmpty which will return True for such a Variant.

How can I test if a variable has a valid instance of an object if the opposite of nil is not always assigned?
In my code, I can follow my rule of always initialising to nil, but how can I test that if I'm handed something from a black box of someone else's code?

You can't, because to decide whether some variable (especially pointer types like classes, dynamic arrays and such) is a valid, correct "instance" of its type is essentially uncomputable at least in languages that don't run on some kind of VM (e.g. Java, .Net, JavaScript) and thus have more control over things.

So the conclusion should be: could it be possible to envisage a new function ?:

Code: Pascal  [Select][+][-]
1.  isinitialized(myvariable)

Such a function only makes sense for local variables (due to the above point of computability) and only inside the same function and then you don't need this anymore, because you're in control of your own code, thus you know whether you initialized it or not.