Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

潜在差异消息

当您启用潜在差异报告时,代码生成器会报告生成的代码的行为和 MATLAB® 代码的行为之间的潜在差异。在生成独立代码之前检查并解决潜在差异有助于避免生成的代码中出现错误和不正确的答案。

以下是一些潜在差异消息:

自动维度不兼容

在生成的代码中,要运算的维度是自
动选择的,可能与 MATLAB 不同。
请考虑将工作维度显示指定为常量值。

此限制适用于接受工作维度(运算所基于的维度)作为输入的函数。在 MATLAB 和代码生成中,如果您不提供工作维度,函数会选择工作维度。在 MATLAB 中,函数选择其大小不等于 1 的第一个维度。对于代码生成,函数选择具有可变大小或不等于 1 的固定大小的第一个维度。如果该工作维度具有可变大小并且在运行时大小变为 1,则该工作维度不同于 MATLAB 中的工作维度。因此,如果启用了运行时错误检查,可能会发生错误。

例如,假设 X 是维度为 1x:3x:5 的可变大小矩阵。在生成的代码中,sum(X) 的行为类似于 sum(X,2)。在 MATLAB 中,sum(X) 的行为类似于 sum(X,2),除非 size(X,2) 为 1。在 MATLAB 中,当 size(X,2) 为 1 时,sum(X) 的行为类似于 sum(X,3)

要避免此问题,请将需要的工作维度显式指定为一个常量值。例如,sum(X,2)

mtimes 没有动态标量扩展

生成的代码执行一般矩阵乘法。
如果可变大小矩阵操作数在运行
时变为标量,维度仍必须一致。
不会自动切换到标量乘法。

A*B 相乘为例。如果代码生成器发现 A 是标量,B 是矩阵,则代码生成器会生成用于标量矩阵乘法的代码。但是,如果代码生成器发现 AB 是可变大小矩阵,它会生成用于一般矩阵乘法的代码。在运行时,如果发现 A 是标量,则生成的代码不会更改其行为。因此,当启用运行时错误检查时,可能会出现大小不匹配错误。

矩阵-矩阵索引

对于使用矩阵对矩阵进行索引的方式 matrix1(matrix2),
代码生成器假设结果的大小与 matrix2 相同。
如果 matrix1 和 matrix2 在运行时是向量,其方向
必须匹配。

在矩阵-矩阵索引中,您可以使用一个矩阵来索引另一个矩阵。在 MATLAB 中,矩阵-矩阵索引的一般规则是,结果的大小和方向与索引矩阵的大小和方向保持一致。例如,如果 AB 是矩阵,则 size(A(B)) 等于 size(B)。当 AB 是向量时,MATLAB 将应用特殊规则。特殊的向量-向量索引规则是,结果的方向等于数据矩阵的方向。例如,如果 A 是 1×5,B 是 3×1,则 A(B) 是 1×3。

代码生成器应用与 MATLAB 相同的矩阵-矩阵索引规则。如果 AB 是可变大小矩阵,为了应用矩阵-矩阵索引规则,代码生成器会假设 size(A(B)) 等于 size(B)。如果 AB 在运行时变成向量且方向不同,则该假设不正确。因此,如果启用了运行时错误检查,可能会发生错误。

为了避免此问题,请通过使用冒号操作符进行索引,强制您的数据为向量。例如,假设您的代码在运行时有意要在向量和常规矩阵之间进行切换。您可以对向量-向量索引执行显式检查:

...
if isvector(A) && isvector(B)
    C = A(:);
    D = C(B(:));
else
    D = A(B);
end
...

第一个分支中的索引指定 CB(:) 是编译时向量。因此,代码生成器将应用使用一个向量索引另一个向量的索引规则。结果的方向等于数据向量 C 的方向。

向量-向量索引

对于使用向量对向量进行索引的方式 vector1(vector2),
代码生成器假设结果的方向与 vector1 相同。
如果 vector1 在运行时是标量,则 vector2 的方向
必须与 vector1 匹配。

在 MATLAB 中,特殊的向量-向量索引规则是,结果的方向等于数据向量的方向。例如,如果 A 是 1×5,B 是 3×1,则 A(B) 是 1×3。但是,如果数据向量 A 是标量,则 A(B) 的方向等于索引向量 B 的方向。

代码生成器应用与 MATLAB 相同的向量-向量索引规则。如果 AB 是可变大小向量,为了应用索引规则,代码生成器会假设 B 的方向与 A 的方向一致。如果 A 在运行时变成标量,并且 AB 的方向不一致,则该假设不正确。因此,如果启用了运行时错误检查,可能会发生运行时错误。

为了避免出现此问题,应使向量的方向保持一致。或者通过指定行和列来索引单个元素。例如,A(row, column)

循环索引溢出

生成的代码假设循环索引不会在循环的最后一次
迭代中溢出。如果循环索引溢出,可能会出现
无限循环。

假设 for 循环结束值等于或接近循环索引数据类型的最大值或最小值。在生成的代码中,循环索引的最后一次递增或递减可能会导致索引变量溢出。索引溢出可能导致无限循环。

启用内存完整性检查时,如果代码生成器检测到循环索引可能溢出,它会报告错误。软件错误检查是保守型的。它可能会误报循环索引溢出。默认情况下,内存完整性检查对 MEX 代码启用,对独立 C/C++ 代码禁用。请参阅为什么要在 MATLAB 中测试 MEX 函数?Generate Standalone C/C++ Code That Detects and Reports Run-Time Errors

为了避免循环索引溢出,请使用下表中的解决方法。

可能导致溢出的循环条件解决方法
  • 循环索引递增 1。

  • 结束值等于整数类型的最大值。

如果循环不必覆盖整数类型的全部范围,请重写循环,使结束值不等于整数类型的最大值。例如,将:

N=intmax('int16')
for k=N-10:N
替换为:
for k=1:10

  • 循环索引递减 1。

  • 结束值等于整数类型的最小值。

如果循环不必覆盖整数类型的全部范围,请重写循环,使结束值不等于整数类型的最小值。例如,将:

N=intmin('int32')
for k=N+10:-1:N
替换为:
for k=10:-1:1

  • 循环索引递增或递减 1。

  • 起始值等于整数类型的最小值或最大值。

  • 结束值等于整数类型的最大值或最小值。

如果循环必须覆盖整数类型的全部范围,请将循环的开始值、步长值和结束值的类型转换为更大的整数或双精度值。例如,重写:

M= intmin('int16');
N= intmax('int16');
for k=M:N
	% Loop body
end
为:
M= intmin('int16');
N= intmax('int16');
for k=int32(M):int32(N)
	% Loop body
end

  • 循环索引按不等于 1 的值递增或递减。

  • 在最后一次循环迭代中,循环索引不等于结束值。

重写循环,使最后一次循环迭代中的循环索引等于结束值。

相关主题