Handle Object Limitations for Code Generation

The code generator statically determines the lifetimes of handle objects. It can reuse memory rather than rely on a dynamic memory management scheme such as reference counting or garbage collection. It generates code that does not use dynamic memory allocation or incur the overhead of run-time automatic memory management. These characteristics of the generated code are important for some safety-critical and real-time applications.

When you use handle objects, the static analysis that the code generator uses requires that you adhere to the following restrictions:

A Variable Outside a Loop Cannot Refer to a Handle Object Created Inside a Loop

Consider the handle class mycls and the function usehandle1. The code generator reports an error because p, which is outside the loop, has a property that refers to a mycls object created inside the loop.

classdef mycls < handle
   properties
       prop
   end
end
function usehandle1
p = mycls;
for i = 1:10
    p.prop = mycls;
end

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

Was this topic helpful?