Main Content

Best Practices for Defining Variables for C/C++ Code Generation

Define Variables By Assignment Before Using Them

For C/C++ code generation, you should explicitly and unambiguously define the class, size, and complexity of variables before using them in operations or returning them as outputs. Define variables by assignment, but note that the assignment copies not only the value, but also the size, class, and complexity represented by that value to the new variable. For example:

Assignment: Defines:
a = 14.7;a as a real double scalar.
b = a;b with properties of a (real double scalar).
c = zeros(5,2);c as a real 5-by-2 array of doubles.
d = [1 2 3 4 5; 6 7 8 9 0];d as a real 5-by-2 array of doubles.
y = int16(3);y as a real 16-bit integer scalar.

Define properties this way so that the variable is defined on the required execution paths during C/C++ code generation.

The data that you assign to a variable can be a scalar, matrix, or structure. If your variable is a structure, define the properties of each field explicitly.

Initializing the new variable to the value of the assigned data sometimes results in redundant copies in the generated code. To avoid redundant copies, you can define variables without initializing their values by using the coder.nullcopy construct as described in Eliminate Redundant Copies of Variables in Generated Code.

When you define variables, they are local by default; they do not persist between function calls. To make variables persistent, see persistent.

Example 1. Defining a Variable for Multiple Execution Paths

Consider the following MATLAB® code:

...
if c > 0
  x = 11;
end
% Later in your code ...
if c > 0
  use(x);
end
...
Here, x is assigned only if c > 0 and used only when c > 0. This code works in MATLAB, but generates a compilation error during code generation because it detects that x is undefined on some execution paths (when c <= 0).

To make this code suitable for code generation, define x before using it:

x = 0;
...
if c > 0
  x = 11;
end
% Later in your code ...
if c > 0
  use(x);
end
...

Example 2. Defining Fields in a Structure

Consider the following MATLAB code:

...
if c > 0 
  s.a = 11;
  disp(s);
else
  s.a = 12;
  s.b = 12;
end
% Try to use s
use(s);
...
Here, the first part of the if statement uses only the field a, and the else clause uses fields a and b. This code works in MATLAB, but generates a compilation error during C/C++ code generation because it detects a structure type mismatch. To prevent this error, do not add fields to a structure after you perform certain operations on the structure. For more information, see Structure Definition for Code Generation.

To make this code suitable for C/C++ code generation, define all fields of s before using it.

...
% Define all fields in structure s
s = struct(‘a’,0, ‘b’, 0);
if c > 0 
  s.a = 11;
  disp(s);
else
  s.a = 12;
  s.b = 12;
end
% Use s
use(s);
...

Use Caution When Reassigning Variables

In general, you should adhere to the "one variable/one type" rule for C/C++ code generation; that is, each variable must have a specific class, size and complexity. Generally, if you reassign variable properties after the initial assignment, you get a compilation error during code generation, but there are exceptions, as described in Reassignment of Variable Properties.

Use Type Cast Operators in Variable Definitions

By default, constants are of type double. To define variables of other types, you can use type cast operators in variable definitions. For example, the following code defines variable y as an integer:

...
x = 15; % x is of type double by default.
y = uint8(x); % y has the value of x, but cast to uint8.
...

Define Matrices Before Assigning Indexed Variables

When generating C/C++ code from MATLAB, you cannot grow a variable by writing into an element beyond its current size. Such indexing operations produce run-time errors. You must define the matrix first before assigning values to its elements.

For example, the following initial assignment is not allowed for code generation:

g(3,2) = 14.6; % Not allowed for creating g
               % OK for assigning value once created

For more information about indexing matrices, see Incompatibility with MATLAB in Matrix Indexing Operations for Code Generation.

Index Arrays by Using Constant Value Vectors

It is a best practice to use constant value vectors to index arrays instead of using ranges that contain nonconstant objects.

In some cases, the code generator is unable to determine whether an expression containing the colon operator is fixed-size or variable-size. Use constant value vectors to index arrays to prevent them from being unnecessarily created as variable-size arrays in the generated code.

For example, the array out has been created by using the variable i indexed through the random row vector A.

...
% extract elements i through i+5 for processing
A = rand(1,10);
out = A(i:i+5); % If i is unknown at compile time, out is variable-size
...

If i is a compile-time constant value, the code generator produces a fixed-size object for out. If i is unknown at compile time, the code generator produces a variable-size array for out in the generated code.

To prevent the code generator from creating variable-size arrays, the previous code snippet is rewritten in this pattern:

...
% extract elements i through i+5 for processing
A = rand(1,10);
out = A (i+(0:5)); % out is fixed-size, even if i is unknown at compile time
...

This pattern enables you to generate fixed-size arrays that have iterator values unknown at compile-time. Another example of the recommended rewrite is:

width = 25;              
A = A(j-width:j+width);  % A is variable-size, if j is unknown at compile time 
fsA = A(j+(-width:width)); % This makes A fixed-size, even if j is unknown at compile time
...

See Also

|

Related Topics