转换MATLAB®代码转换为高效的C/ c++代码,代码生成器引入优化,有意地使生成的代码表现不同,有时产生与原始源代码不同的结果。
以下是一些不同之处:
当您运行程序时,运行时错误检查可以检测到其中的一些差异。默认情况下,运行时错误检查对MEX代码是启用的,对独立的C/ c++代码是禁用的。为了帮助您在部署代码之前识别和处理差异,代码生成器将差异的子集报告为潜在的差异.
MATLAB支万博1manbetx持16位字符,但生成的代码表示8位字符,这是大多数嵌入式语言(如c)的标准大小代码生成中字符的编码.
生成的代码不强制表达式中的求值顺序。对于大多数表达式,求值顺序并不重要。但是,对于有副作用的表达式,生成的代码产生副作用的顺序可能与原始MATLAB代码不同。产生副作用的表达式包括:
修改持久变量或全局变量
在屏幕上显示数据
向文件写入数据
修改句柄类对象的属性
此外,生成的代码不会强制执行不短路的逻辑运算符的求值顺序。
为了获得更可预测的结果,将依赖于求值顺序的表达式拆分为多个语句是一种良好的编码实践。
重写
A = f1() + f2();
作为
A = f1();A = A + f2();
使生成的代码调用f1
之前f2
.
将多输出函数调用的输出分配给彼此不依赖的变量。例如,重写
[y, y.f, y.g] = foo;
作为
[y, a, b] = foo;Y.f = a;Y.g = b;
当访问单元格数组的多个单元格的内容时,请将结果分配给互不依赖的变量。例如,重写
[y, y.f, y.g] = z{:};
作为
[y, a, b] = z{:};Y.f = a;Y.g = b;
生成的代码不匹配终止行为的MATLAB源代码。例如,如果无限循环没有副作用,优化就会从生成的代码中删除它们。因此,即使相应的MATLAB代码没有终止,生成的代码也可能会终止。
对于可变大小的N-D数组大小
函数在生成的代码中可能返回与MATLAB源代码中不同的结果。的大小
函数有时在生成的代码中返回尾随数(单例维度),但在MATLAB中总是丢弃尾随数。例如,对于N-D数组X
与维[4 2 1 1]
,大小(X)
可能会返回[4 2 1 1]
在生成的代码中,但总是返回(4 - 2)
在MATLAB。看到在确定变大小N-D数组的大小时与MATLAB不兼容.
生成代码中的空数组的大小可能与MATLAB源代码中的大小不同。看到确定空数组大小时与MATLAB不兼容.
删除数组的所有元素将导致一个空数组。生成代码中这个空数组的大小可能与MATLAB源代码中的大小不同。
情况下 | 示例代码 | MATLAB中空数组的大小 | 生成代码中空数组的大小 |
---|---|---|---|
方法删除m × n数组中的所有元素结肠 操作符(: ). |
coder.varsize (“X”(4, 4), [1]);X = 0 (2);X(:) = [];
|
0-by-0 |
1-by-0 |
方法删除行向量的所有元素结肠 操作符(: ). |
coder.varsize (“X”[1,4], [0, 1]);X = 0 (1,4);X(:) = [];
|
0-by-0 |
1-by-0 |
方法删除列向量的所有元素结肠 操作符(: ). |
coder.varsize (“X”(4,1), (1,0));X = 0 (4,1);X(:) = [];
|
0-by-0 |
0-by-1 |
通过每次删除一个元素来删除列向量的所有元素。 |
coder.varsize (“X”(4,1), (1,0));X = 0 (4,1);为i = 1:4 X(1)= [];结束 |
1-by-0 |
0-by-1 |
生成的代码在以下情况下可能不会产生与MATLAB相同的浮点数值结果:
生成的代码可能不会产生完全相同的模式南
和正
值作为MATLAB代码,当这些值在数学上没有意义时。例如,如果MATLAB输出包含a南
,则生成的代码的输出还应包含南
,但不一定在同一个地方。
在浮点类型中,值0
有正号或负号。用算术方法,0
等于-0
.除0
生产正
,而除以-0
生产负
.
如果代码生成器检测到浮点变量只接受合适范围的整数值,则代码生成器可以在生成的代码中为该变量使用整数类型。如果代码生成器为变量使用整数类型,则该变量存储-0
作为+ 0
因为整数类型不存储值的符号0
.如果生成的代码将变量强制转换回浮点类型,则符号0
是正的。除0
生产正
,而不是负
.
的coder.target
函数在MATLAB中返回的值与生成的代码中的值不同。其目的是帮助您确定您的函数是在MATLAB中执行,还是已经为模拟或代码生成目标编译。看到coder.target
.
在代码生成之前,在类加载时,MATLAB计算类的默认值。代码生成器使用MATLAB计算的值。它不会重新计算默认值。如果属性定义使用函数调用来计算初始值,则代码生成器不会执行该函数。如果函数有副作用,比如修改全局变量或持久变量,那么生成的代码可能会产生与MATLAB产生的结果不同的结果。有关更多信息,请参见为代码生成定义类属性.
当具有属性访问方法的对象是入口点函数或外部函数的输入或输出时,如果满足以下条件,则MEX函数结果可能与MATLAB结果不同:
get方法读取属性值并在返回之前修改该值。
set方法在将输入值分配给属性之前修改输入值。
get方法或set方法具有副作用,例如修改全局变量或写入文件。
如果属性访问方法修改属性值或有副作用,则在MATLAB和生成的代码相互传递对象时,由于属性访问方法的使用不一致,结果可能会不同。当您调用带有对象输入的MEX函数时,或者从外部函数返回对象时,MATLAB将对象传递给生成的代码。生成的代码创建自己的对象版本。为了向对象创建过程提供属性值,MATLAB调用get方法。对象创建过程将这些属性值从MATLAB直接分配给新对象,而不调用set方法。
当您从一个MEX函数返回一个对象,或者使用一个对象作为输入调用一个外部函数时,MEX函数将该对象传递给MATLAB。为了向MATLAB提供属性值,而不是使用get方法,生成的代码直接读取属性值。要在对象的MATLAB版本中分配属性值,创建过程使用set方法。
为了避免MATLAB和MEX函数之间的结果差异,对于作为入口点函数或外部函数的输入或输出的对象,不要使用修改属性值或具有其他副作用的属性访问方法。
有关更多信息,请参见为代码生成定义类属性.
在这些情况下,生成代码中的句柄类析构函数的行为可能与MATLAB中的行为不同:
几个独立对象的销毁顺序在MATLAB中可能与在生成的代码中不同。
生成代码中对象的生命周期可能与MATLAB中的生命周期不同。
生成的代码不会破坏部分构造的对象。如果在运行时未完全构造句柄对象,则生成的代码将生成错误消息,但不会调用删除
方法用于该对象。对于System对象™,如果中存在运行时错误setupImpl
时,生成的代码不会调用releaseImpl
对于那个物体。
MATLAB会调用删除
方法来销毁部分构造的对象。
有关更多信息,请参见句柄类析构函数的代码生成.
看到复杂数据的代码生成.