Handle Object Limitations for Code Generation
The code generator statically determines the lifetime of a handle object. When you use handle objects, this static analysis has certain restrictions.
With static analysis the generated code can reuse memory rather than rely on a dynamic memory management scheme, such as reference counting or garbage collection. The code generator can avoid dynamic memory allocation and run-time automatic memory management. These generated code characteristics are important for some safety-critical and real-time applications.
For limitations, see:
The code generator analyzes whether all variables are defined prior to use. Undefined variables or data types cause an error during code generation. In certain circumstances, the code generator cannot determine if references to handle objects are defined. See References to Handle Objects Can Appear Undefined.
A Variable Outside a Loop Cannot Refer to a Handle Object Allocated Inside a Loop
Consider the handle class mycls
and the function
usehandle1
.
classdef mycls < handle properties prop end methods function obj = mycls(x) obj.prop = x; end end end
function y = usehandle1(n) c = cell(1,n); for i = 1:n c{i} = mycls(i); % Handle object allocated inside loop end y = c{n}.prop; % Handle object referenced outside loop end
If you try to generate code for the usehandle1
function, the
code generator produces an error. The error occurs because:
Handle objects are allocated inside the
for
-loopOne of these handle objects is used outside of the
for
-loop
A Handle Object That a Persistent Variable Refers To Must Be a Singleton Object
If a persistent variable refers to a handle object, the code
generator allows only one instance of the object during the program’s
lifetime. The object must be a singleton object.
To create a singleton handle object,
enclose statements that create the object in the if isempty()
guard
for the persistent variable.
For example, consider the class mycls
and the
function usehandle2
. The code generator reports
an error for usehandle2
because p.prop
refers
to the mycls
object that the statement inner
= mycls
creates. This statement creates a mycls
object
for each invocation of usehandle2
.
classdef mycls < handle properties prop end end
function usehandle2(x) assert(isa(x, 'double')); persistent p; inner = mycls; inner.prop = x; if isempty(p) p = mycls; p.prop = inner; end
If you move the statements inner = mycls
and inner.prop
= x
inside the if isempty()
guard, code
generation succeeds. The statement inner = mycls
executes
only once during the program’s lifetime.
function usehandle2(x) assert(isa(x, 'double')); persistent p; if isempty(p) inner = mycls; inner.prop = x; p = mycls; p.prop = inner; end
Consider the function usehandle3
. The code
generator reports an error for usehandle3
because
the persistent variable p
refers to the mycls
object
that the statement myobj = mycls
creates. This
statement creates a mycls
object for each invocation
of usehandle3
.
function usehandle3(x) assert(isa(x, 'double')); myobj = mycls; myobj.prop = x; doinit(myobj); disp(myobj.prop); function doinit(obj) persistent p; if isempty(p) p = obj; end
If you make myobj
persistent and enclose
the statement myobj = mycls
inside an if
isempty()
guard, code generation succeeds. The statement myobj
= mycls
executes only once during the program’s lifetime.
function usehandle3(x) assert(isa(x, 'double')); persistent myobj; if isempty(myobj) myobj = mycls; end doinit(myobj); function doinit(obj) persistent p; if isempty(p) p = obj; end
References to Handle Objects Can Appear Undefined
Consider the function refHandle
that copies a handle object
property to another object. The function uses a simple handle class and value class.
In MATLAB®, the function runs without
error.
function [out1, out2, out3] = refHandle() x = myHandleClass; y = x; v = myValueClass(); v.prop = x; x.prop = 42; out1 = x.prop; out2 = y.prop; out3 = v.prop.prop; end
classdef myHandleClass < handle properties prop end end
classdef myValueClass properties prop end end
During code generation, an error occurs:
Property 'v.prop.prop' is undefined on some execution paths.
Three variables reference the same memory location: x
,
y
, and v.prop
. The code generator
determines that x.prop
and y.prop
share the
same value. The code generator cannot determine that the handle object property
v.prop.prop
shares its definition with
x.prop
and y.prop
. To avoid the error,
define v.prop.prop
directly.