Why this code does not crash?
T is nil. How it is possible to access
procedure Crash; VAR T: TButton; begin T:= NIL; T.Caption:= ''; <---------- this works end;
TButton control is a wrapper around the Win32 Button control. It uses the Windows messaging system to operate upon it. And the core method for doing so,
TControl.Perform(), has a built in safeguard against sending messages if
function TControl.Perform(Msg: Cardinal; WParam: WPARAM; LParam: LPARAM): LRESULT; var Message: TMessage; begin Message.Msg := Msg; Message.WParam := WParam; Message.LParam := LParam; Message.Result := 0; if Self <> nil then // <-- here WindowProc(Message); Result := Message.Result; end;
Caption is a property whose setter uses the non-virtual
TControl.SetText() methods, which can be safely called upon
nil objects, as their functionality rely on sending various messages (
WM_SETTEXT) to the control, and only involve local variables or passed parameters. So the actual object is not accessed when
nil, thus no crash.