exponenta event banner

Обработка ограничений объектов для создания кода

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

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

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

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

Переменная вне цикла не может ссылаться на объект-дескриптор, назначенный внутри цикла

Рассмотрим класс дескрипторов 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 объект-дескриптор.

Объект-дескриптор, на который ссылается постоянная переменная, должен быть объектом-одиночкой

Если постоянная переменная ссылается на объект-дескриптор, генератор кода допускает только один экземпляр объекта в течение срока действия программы. Объект должен быть одиночным. Чтобы создать одиночный объект-дескриптор, заключите инструкции, которые создают объект в 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 persistent и включить оператор 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 копирует свойство объекта дескриптора в другой объект. Функция использует простой класс дескриптора и класс значения. В 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 использовать одно и то же значение. Генератор кода не может определить, что свойство объекта дескриптора v.prop.prop делится своим определением с x.prop и y.prop. Чтобы избежать ошибки, определите v.prop.prop непосредственно.