Ограничения, накладываемые на объекты указатель для генерации кода

Генератор кода статически определяет время жизни объекта указатель. При использовании указателя объектов этот статический анализ имеет определенные ограничения.

При статическом анализе сгенерированный код может повторно использовать память, а не полагаться на динамическую схему управления памятью, такую как подсчет ссылок или набор мусора. Генератор кода может избежать динамического выделения памяти и автоматического управления памятью во время выполнения. Эти сгенерированные коды характеристики важны для некоторых критически важных приложений и приложений реального времени.

Ограничения см. в:

Генератор кода анализирует, заданы ли все переменные перед использованием. Неопределенные переменные или типы данных вызывают ошибку во время генерации кода. В определенных обстоятельствах генератор кода не может определить, заданы ли ссылки для обработки объектов. См. раздел Ссылки для обработки, Объекты могут появляться неопределенными.

Переменная вне цикла не может ссылаться на Указатель Объекта, выделенную внутри цикла

Рассмотрим класс handle mycls и функцию usehandle1.

classdef mycls < handle
   properties
       prop
   end
   
   methods
       function obj = mycls(x)
       obj.prop = x;
       end
   end
end
function y = usehandle1
p = mycls(0); % Instance of mycls with prop value 10 created

for i = 1:10
    p = mycls(i); % Handle object allocated inside loop
end

y = p.prop; % Handle object referenced outside loop
end

Если вы пытаетесь сгенерировать код для usehandle1 функция, генератор кода производит ошибку. Ошибка возникает из-за:

  • Внутри указатель выделяется объекту for цикл. Переменная p.prop относится к этому указателю объекта.

  • Вне цикла переменная x относится к свойству prop объект указатель.

A Указателя Объекта, на который ссылается постоянная переменная, должна быть синглтоном Объект

Если постоянная переменная ссылается на объект указатель, генератор кода допускает только один образец объекта во время жизни программы. Объект должен быть singleton объектом. Чтобы создать объект singleton указателя, заключайте операторы, которые создают объект в if isempty() защитите постоянную переменную.

Например, рассмотрим класс mycls и функцию usehandle2. Генератор кода сообщает об ошибке для usehandle2 потому что p.prop относится к mycls объект, который оператор inner = mycls создает. Этот оператор создает mycls объект для каждого вызова 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

Если вы перемещаете операторы inner = mycls и inner.prop = x внутри if isempty() охрана, генерация кода успешна. Оператор inner = mycls выполняется только один раз в течение срока службы программы.

function usehandle2(x)
assert(isa(x, 'double'));
persistent p;
if isempty(p)
    inner = mycls;
    inner.prop = x;
    p = mycls;
    p.prop = inner;
end

Рассмотрим функцию usehandle3. Генератор кода сообщает об ошибке для usehandle3 потому что постоянная переменная p относится к mycls объект, который оператор myobj = mycls создает. Этот оператор создает mycls объект для каждого вызова 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

Если вы делаете myobj сохраняет и заключает оператор myobj = mycls внутри if isempty() охрана, генерация кода успешна. Оператор myobj = mycls выполняется только один раз в течение срока службы программы.

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

Ссылки на указатели на Объекты могут появиться неопределенными

Рассмотрим функцию refHandle который копирует свойство объекта указатель в другой объект. Функция использует простой класс handle и класс value. В MATLAB®функция запускается без ошибок.

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

Во время генерации кода возникает ошибка:

Property 'v.prop.prop' is undefined on some execution paths.

Три переменные ссылаются на то же место памяти: x, y, и v.prop. Генератор кода определяет, что x.prop и y.prop иметь то же значение. Генератор кода не может определить, что свойство объекта handle v.prop.prop разделяет его определение с x.prop и y.prop. Чтобы избежать ошибки, задайте v.prop.prop непосредственно.