主要内容

coder.nullcopy

在生成的代码中声明未初始化的变量

说明

您可以使用 coder.nullcopy 通过声明未初始化的变量来优化生成的代码,而无需复制变量值。仅在两种特定情况下使用 coder.nullcopy

  • 在代码生成时,您看到以下错误之一:

    For code generation, all variables must be fully defined before use.(要进行代码生成,所有变量在使用前都必须完全定义。)

    For code generation, all cell array elements must be fully defined before use.(对于代码生成,所有元胞数组元素在使用前必须完全定义。)

    但是,您已完全定义所有执行路径中的所有变量和元胞数组元素,并且已考虑并拒绝其他故障排除解决方案。请参阅解决问题:变量在使用前必须完全定义 (MATLAB Coder)解决问题:元胞数组元素在使用前必须完全定义

  • 您在生成的代码中看到冗余的变量赋值。也就是说,对一个变量进行了赋值,然后在使用该变量前又赋予了不同值。

请慎用 coder.nullcopy。在大多数情况下,即使您的 MATLAB® 代码中不包含 coder.nullcopy 函数,代码生成器也会自动执行与 coder.nullcopy 对应的优化。如果使用 coder.nullcopy 声明一个变量,并且在使用该变量之前没有对其进行完整赋值,则生成的代码的行为可能不可预测。

X = coder.nullcopy(A)A 的类型、大小和复/实性复制到 X,但不复制元素值。在生成的代码中,coder.nullcopy 声明一个未初始化的变量,从而为 X 预分配内存,而不会产生初始化内存的开销。在 MATLAB 执行中,coder.nullcopy 返回输入值。

在大多数情况下,coder.nullcopy 以递归方式应用。也就是说,如果 A 是聚合类型(类、结构体或元胞数组),coder.nullcopy 还会为 A 的字段、属性或元素预分配内存。但是,如果 A 是包含一个或多个可变大小数组的聚合类型,则需要考虑一些特殊事项。请参阅在类、结构体或元胞数组中声明可变大小数组

在使用或返回 X 之前,必须为其所有元素赋值。否则,生成的代码的行为可能不可预测。

示例

示例

全部折叠

此示例说明如何在生成的代码中声明一个数组,但没有为数组的每个元素赋值带来的开销。

创建一个 MATLAB 函数 foo,该函数返回一个 n×n 矩阵。通过为数组的每个元素赋值 1 来初始化输出矩阵变量 out。然后,使用 for 循环为 out 的每个元素重新赋值。

function out = foo(inp) %#codegen
out = ones(inp);
for idx = 1:inp*inp
   if mod(idx,2) == 0
      out(idx) = idx;
   else
      out(idx) = idx + 1;
   end
end

为此函数生成 C 代码,并检查生成的代码。C 代码在 for 循环中为 out 的每个元素显式赋值 1.0(C 代码映射中的第 33 到 35 行)。然后,在第二个 for 循环中,生成的代码对 out 的元素重新赋值(第 37 到 43 行)。

Code mapping between MATLAB code and generated C code without using coder.nullcopy

修改 foo 并使用 coder.nullcopyout 声明为 n×n 双精度矩阵,然后使用 for 循环为每个元素赋值。

function out = foo(inp) %#codegen
out = coder.nullcopy(ones(inp));
for idx = 1:inp*inp
   if mod(idx,2) == 0
      out(idx) = idx;
   else
      out(idx) = idx + 1;
   end
end

为此函数生成 C 代码,并将生成的代码与不使用 coder.nullcopy 时生成的代码进行比较。当您使用 coder.nullcopy 时,生成的代码只对 out 的元素赋值一次。

Code mapping between MATLAB code and generated C code when using coder.nullcopy

当对包含一个或多个可变大小数组的聚合类型(类、结构体或元胞数组)调用 coder.nullcopy 时,在使用 for 循环赋值之前,还必须直接对可变大小数组调用 coder.nullcopy。当您执行向量化赋值时,或当字段、属性或元胞数组元素的大小固定时,此额外步骤是不必要的。

copyStructExample 函数为例。该函数返回一个包含三个字段的结构体,其中两个字段的大小是可变的。使用 coder.nullcopy 声明此结构体,然后为每个字段赋值。

  • 使用 for 循环对固定大小的 out.field1 赋值。

  • 通过使用向量化对可变大小的 out.field2 赋值。

  • 直接对可变大小的 s.field3 调用 coder.nullcopy,然后使用 for 循环对 out.field3 赋值。

function out = copyStructExample(n) %#codegen

s.field1 = ones(1,5);
s.field2 = ones(1,n);
s.field3 = ones(1,n);
out = coder.nullcopy(s); % out is a structure with unassigned contents

for i = 1:5
    out.field1(i) = i+2;
end

out.field2 = 5:5:n*5;

out.field3 = coder.nullcopy(s.field3);
for i = 1:n
    out.field3(i) = i*2;
end
end

输入参数

全部折叠

要复制的变量,指定为标量、向量、矩阵、结构体或多维数组。

数据类型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical | char | string | struct | class
复数支持:

限制

  • 您无法对稀疏矩阵使用 coder.nullcopy

  • 您无法将 coder.nullcopy 用于支持重载括号或需要索引方法来访问其数据的类,如 table

扩展功能

全部展开

C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。

GPU 代码生成
使用 GPU Coder™ 为 NVIDIA® GPU 生成 CUDA® 代码。

版本历史记录

在 R2011a 中推出