Main Content

Resolve Issue: Cell Array Elements Must Be Fully Defined Before Use

Issue

Unlike MATLAB®, which is a dynamically typed language, C and C++ are statically typed. This means that the code generator must be able to determine the types of all variables in your MATLAB code so that it can define variables in the generated code. When you use the cell function to create a cell array, the sizes and types of the elements of the cell array are undefined in the generated code. Therefore, in MATLAB code for code generation, you must make sure to assign initial values to all elements of all cell arrays created using the cell function.

If the code generator is unable to determine the types of all elements of all cell arrays in your MATLAB code, you see an error message containing this sentence:

For code generation, all cell array elements must be fully defined before use.

Even though your MATLAB code assigns values to all elements of a cell array, code generation can fail for certain coding patterns because the code generator is unable to recognize that all cell array elements are assigned. These coding patterns include:

  • You assign initial values to cell array elements in different loops. For example, consider the function cellArrayAssignmentError1. MATLAB populates cell array ca for all values of n. However, code generation for cellArrayAssignmentError1 fails because the code generator is unable to determine that all cell array elements are defined for all values of n.

    function out = cellArrayAssignmentError1(n) %#codegen
    ca = cell(1,n);
    for i = 1:5
        ca{i} = 5;
    end
    for i = 6:n
        ca{i} = i;
    end
    out = ca{n};
    end

  • The variable that you use to construct the cell array using cell differs from the variable that you use to control the for-loop in which you assign initial values to the cell array elements. For example, consider the function cellArrayAssignmentError2. MATLAB populates cell array ca for all values of n. However, code generation for cellArrayAssignmentError2 fails because the code generator is unable to determine that all cell array elements are defined for all values of n.

    function out = cellArrayAssignmentError2(n) %#codegen
    ca = cell(1,n);
    counter = n;
    for i = 1:counter
        ca{i} = 2*i;
    end 
    out = ca{n};
    end
    

  • In the for-loop you use to assign initial values to the cell array elements, you increment or decrement the loop counter by a number other than 1. For example, consider the function cellArrayAssignmentError3. MATLAB populates cell array ca for all values of n. However, code generation for cellArrayAssignmentError3 fails because the code generator is unable to determine that all elements of ca have been defined for all values of n.

    function out = cellArrayAssignmentError3(n) %#codegen
    ca = cell(1,n*2);
    for i = 1:2:n*2-1
        ca{i} = 1;
        ca{i+1} = 2;
    end
    out = ca{n};
    end

  • You assign initial values to cell array elements using subscript or dot indexing. For example, consider the function cellArrayAssignmentError4. MATLAB populates cell array ca. However, code generation for cellArrayAssignmentError4 fails because the code generator is unable to subscript into ca before all of the elements of ca have been defined.

    function out = cellArrayAssignmentError4 %#codegen
    ca = cell(1,3);
    for j = 1:3
        ca{j}(1) = 10; 
        ca{j}(2) = 20;
        ca{j}(3) = 30;
    end
    out = ca{2};
    end

Possible Solutions

To resolve this issue, try one of these solutions.

Use a recognized coding pattern to assign cell array elements

Assign values to the elements of the cell array using a coding pattern that the code generator can recognize. If you use a for-loop to assign initial values to the cell array elements and the cell array is variable-size, make sure that you:

  • Assign initial values to all elements in the same loop.

  • Use the same variable for the loop counter as you used in the cell function to create the cell array.

  • Increment or decrement the loop counter by 1.

To assign a scalar value to each element of a 1-by-n cell array, follow this pattern.

function out = codingPatternExample1(n) %#codegen
ca = cell(1,n);   
for i = 1:n
    ca{i} = sqrt(i);
end
out = ca{n};
end

To assign an array of values to each element of a 1-by-n cell array, assign arrays of values to each element in a single statement. Do not use subscripted or dot assignments.

function out = codingPatternExample2(n) %#codegen
ca = cell(1,n);   
for i = 1:n
    ca{i} = [sqrt(i) i i^2];
end
out = ca{n};
end

To assign a value to each element of a multidimensional cell array, use nested loops. For example, use this coding pattern for a three-dimensional (m-by-n-by-p) array.

function out = codingPatternExample3(m,n,p) %#codegen
ca = cell(m,n,p);
for i = 1:m
    for j =1:n
        for k = 1:p
            ca{i,j,k} = i+j+k;
        end
    end
end
out = ca{m,n,p};
end

Use the repmat function

The repmat function takes an input array and replicates it a specified number of times in the row and column dimensions to construct an output array. In certain cases where your cell array contains repeating elements, you can rewrite your code to define the elements of a cell array by using repmat. For example, consider the function repmatAssignmentError, which creates a 1-by-(n*2) cell array using the cell function. repmatAssignmentError assigns 1 to the odd elements of ca and 0 to the even elements. Code generation fails for this function because initial values are assigned to the cell array elements in different for-loops and because the loop counters increment by a value other than 1.

function out = repmatAssignmentError(n) %#codegen
ca = cell(1,n*2);
for i = 1:2:n*2
    ca{i} = 1;
end
for i = 2:2:n*2
    ca{i} = 0;
end
out = ca{n};
end

To resolve this issue, first use the cell function to create a temporary 1-by-2 cell array whose first element is 1 and whose second element is 0. Then, use the repmat function to create a 1-by-(n*2) cell array whose element values alternate between 1 and 2.

function out = repmatAssignmentExample(n) %#codegen
tmp = cell(1,2);
tmp{1} = 1;
tmp{2} = 0;
ca = repmat(tmp,1,n);
out = ca{n};
end

Use coder.nullcopy

You can use the coder.nullcopy function to preallocate memory for a homogenous cell array without specifically assigning values to the cell array elements. In general, homogenous cell arrays contain elements that are all of the same type, such as double or string. However, under certain circumstances, the code generator can classify the same cell array as homogenous in some contexts but as heterogeneous in other contexts. See Code Generation for Cell Arrays.

If you use coder.nullcopy to define a homogenous cell array, you can generate code without having to adhere to the recognized coding patterns described above. For example, consider the function nullcopyExample. Because this function uses coder.nullcopy to preallocate memory for homogenous cell array ca, you can assign values to the cell array in two separate loops.

function out = nullcopyExample(n) %#codegen
tmp = cell(1,n);
ca = coder.nullcopy(tmp);
for i = 1:4
    ca{i} = 0;
end
for i = 5:n
    ca{i} = i;
end
out = ca{n};
end

Note

Use coder.nullcopy with caution. You must make sure that you assign values to all elements in your cell array. If you access uninitialized cell array elements, the results can be unpredictable.

See Also

| |

Related Topics