Does the instruction myVar is TMyObj
can work if myVar
is nil? I don't know how the is is performed internally

- 12,173
- 9
- 63
- 184
-
2Do you know how to find documentation? Perhaps I can suggest you visit this topic https://stackoverflow.com/q/21403628/505088 – David Heffernan Feb 03 '19 at 16:24
-
seems simple enough to test this yourself with a few lines of code – GuidoG Feb 04 '19 at 10:26
-
@Guido spot checks don't prove something always to be so, hence documentation – David Heffernan Feb 04 '19 at 13:27
2 Answers
It works if myVar
is of type TMyObj
or a descendant, but returns false if the object is nil.
See The is Operator: (emphasis mine)
The is operator, which performs dynamic type checking, is used to verify the actual runtime class of an object. The expression:
object is class
returns True if object is an instance of the class denoted by class or one of its descendants, and False otherwise. (If object is nil, the result is False.) If the declared type of object is unrelated to class -- that is, if the types are distinct and one is not an ancestor of the other -- a compilation error results.
The implementation of is
is available in the system unit.
function _IsClass(const Child: TObject; Parent: TClass): Boolean;
begin
Result := (Child <> nil) and Child.InheritsFrom(Parent);
end;
Though, it is not 100% reliable because there is some compiler magic surrounding the is
operator.
Amongs other, the following :
var
vWin : TWinControl;
begin
vWin := TWinControl(TControl.Create(nil));
if vWin is TWinControl then
ShowMessage('The shouldn''t be true!!!');
vWin.Free;
end;
Gets optimised to (at least in Seattle)
var
vWin : TWinControl;
begin
vWin := TWinControl(TControl.Create(nil));
if vWin <> nil then
ShowMessage('The shouldn''t be true!!!');
vWin.Free;
end;
Which doesn''t give the result one could expect.
Note : I'm not pretending here that vWin := TWinControl(TControl.Create(nil))
is a valid operation.

- 6,363
- 1
- 19
- 28
-
1I don't care for this answer. That is actually not the implementation of is. That's the part for object references. But there are also interfaces to consider. And then there's the magic. A good answer here refers to the documentation. – David Heffernan Feb 04 '19 at 21:01
-
I think otherwise. IMO The optimization in this case is open for discussion, vWin clearly does NOT point to a TWinControl object, so the is operator should return False, where the optimized code just checks for assignment. I learned something. – H.Hasenack Feb 05 '19 at 21:56
-
@H.Hasenack The optimisation assume a TWinControl variable will always contains a TWinControl or nil... something I agree on. It is totally fair to consider assigning a TControl in a TWinControl an invalid operation. Though, I don't remember reading any official statement in the documentation to that regard... – Ken Bourassa Feb 07 '19 at 14:21
-
@Ken, exactly. Thats what I learned! Its the choice the optimizer makes. Now I wonder what happens if you turn optimization off... Optimization on/off should NOT change the way the code works, but it might have an effect here. (didn't test) – H.Hasenack Feb 08 '19 at 08:19
-
@H.Hasenack Optimization should not change DEFINED behavior... but it is free to alter any undefined behavior. So, if assigning a non TWincontrol to a TWinControl variable is considered "undefined behavior", the optimization is entirely legitimate. – Ken Bourassa Feb 08 '19 at 18:18
-
@Ken, as I said before, you are right. If I find the time, I'll just try it out to satisfy my curiosity :p – H.Hasenack Feb 08 '19 at 23:06