Unable to Determine That Every Element of Cell Array Is Assigned

Issue

You see one of these messages:

Unable to determine that every element of 'y' is
assigned before this line.
Unable to determine that every element of 'y' is
assigned before exiting the function.
Unable to determine that every element of 'y' is
assigned before exiting the recursively called function.

Cause

For code generation, before you use a cell array element, you must assign a value to it. When you use cell to create a variable-size cell array, for example, cell(1,n), MATLAB® assigns an empty matrix to each element. However, for code generation, the elements are unassigned. For code generation, after you use cell to create a variable-size cell array, you must assign all elements of the cell array before any use of the cell array.

The code generator analyzes your code to determine whether all elements are assigned before the first use of the cell array. The code generator detects that all elements are assigned when the code follows this pattern:

function z = mycell(n, j)
%#codegen
assert(n < 100);
x = cell(1,n);   
for i = 1:n
    x{i} = i;
end
z = x{j};
end

Here is the pattern for a multidimensional cell array:

function z = mycell(m,n,p)
%#codegen
assert(m < 100);
assert(n < 100);
assert(p < 100);
x = cell(m,n,p);
for i = 1:m
    for j =1:n
        for k = 1:p
            x{i,j,k} = i+j+k;
        end
    end
end
z = x{m,n,p};
end

If the code generator detects that some elements are not assigned, code generation fails. Sometimes, even though your code assigns all elements of the cell array, code generation fails because the analysis does not detect that all elements are assigned.

Here are examples where the code generator is unable to detect that elements are assigned:

  • Elements are assigned in different loops

    ...
    x = cell(1,n)
    for i = 1:5
        x{i} = 5;
    end
    for i = 6:n
        x{i} = 7;
    end 
    ...             

  • The variable that defines the loop end value is not the same as the variable that defines the cell dimension.

    ...
    x = cell(1,n);
    m = n;
    for i = 1:m
        x{i} = 2;
    end 
    ...                 

For more information, see Definition of Variable-Size Cell Array by Using cell.

Solution

Try one of these solutions:

Use recognized pattern for assigning elements

If possible, rewrite your code to follow this pattern:

...
x = cell(1,n);   
for i = 1:n
    x{i} = i;
end
z = x{j};
...

Use repmat

Sometimes, you can use repmat to define the variable-size cell array.

Consider this code that defines a variable-size cell array. It assigns the value 1 to odd elements and the value 2 to even elements.

function z = mycell2(n, j)
%#codegen
assert(n < 100);
c =cell(1,n);
for i = 1:2:n-1
    c{i} = 1;
end
for i = 2:2:n
    c{i} = 2;
end
z = c{j};

Code generation does not allow this code because:

  • More than one loop assigns the elements.

  • The loop counter does not increment by 1.

Rewrite the code to first use cell to create a 1-by-2 cell array whose first element is 1 and whose second element is 2. Then, use repmat to create a variable-size cell array whose element values alternate between 1 and 2.

function z = mycell2(n, j)
%#codegen
assert(n < 100);
c = cell(1,2);
c{1} = 1;
c{2} = 2;
c1= repmat(c,1,n);
z = c1{j};
end

Use coder.nullcopy

As a last resort, you can use coder.nullcopy to indicate that the code generator can allocate the memory for your cell array without initializing the memory. For example:

function z = mycell3(n, j)
%#codegen
assert(n < 100);
c =cell(1,n);
c1 = coder.nullcopy(c);
for i = 1:4
    c1{i} = 1;
end
for i = 5:n
    c1{i} = 2;
end
z = c1{j};
end

Use coder.nullcopy with caution. If you access uninitialized memory, results are unpredictable.

See Also

| |

Related Topics