MonkeyProof MATLAB Coder Compatibility Standard
Version 1.3
© 2023 MonkeyProof Solutions BV
T: +31 (0)76 8200 314
Table of Contents
MonkeyProof MATLAB Coder Compatibility Standard
- Function calls
- Editor warnings
- Error function
- Pause function
- Struct manipulation
- Dynamic fields
- If else
- Switch otherwise
- Short-circuit operators
- Functionality shadowing
- Shell escape function
- Scripts
- Parentheses for precedence
- Floating-point comparisons
- Binary expressions
- Concatenate array
Introduction
The goal of this set of coding standards that can be automatically checked is to help you write MATLAB code that is Coder-compatible. The resulting code will be more suitable for code generation. For more information on MATLAB Coder, see the MathWorks website.
If you are looking for more generic coding standards that are not specifically aimed at Coder-compatibility, see our MonkeyProof MATLAB Coding Standard.
Automatic compliance checking
The coding standards described here can be checked using CC4M by MonkeyProof Solutions.
They are configured in the predefined CoderCompatibility
configurations set available with the tool. For instructions on how to check your code against coding standards, see the video below. The steps are also described below the video.
You can check your code for compliance with the guidelines described here as follows:
- Install CC4M If you have not purchased the tool yet, you can do so here. Alternatively, you could request a free trial license there.
- Open CC4M in one of two ways:
- Click the shortcut created at the top of the screen next to the documentation search bar: .
- Run
monkeyproof.cc4m.start()
from the command window.
- Select whether you want to check one or more files, all files in a folder, or all files in a MATLAB Project.
- Select what files/folder/project to check.
- Further customization is available, for example checking a folder including or excluding all subfolders.
- Click the Run button at the bottom to start checking your code.
The guidelines that require human judgment or are simply not possible to check statically in MATLAB are not described here.
Guideline template
Every guideline is structured as follows:
Guideline name
ID | A unique guideline identifier. |
Title | Brief description of the guideline. |
Priority | Priority of the guideline can be one of Mandatory, Strongly recommended and Recommended. Exactly what each of these means for your case is up to you to decide. |
Description | A more elaborate description of the guideline. Can include the reasoning behind the guideline: how does your code improve when applying the guideline? |
Rationale | One or multiple words describing what the guideline is about. Examples: Compatibility, Stability. |
Coder-compatibility function calls
ID | CC-1 |
Title | Do not use built-in functions that are not supported by MATLAB Coder. |
Priority | Mandatory |
Severity level | 1 |
Description | Do not use MATLAB-installed functions that are not supported by MATLAB Coder. Calls to functions that have remarks in the documentation about Coder-compatibility need to be manually inspected. |
Rationale | Compatibility. Unsupported functions result in code generation errors. Using functions with remarks might result in a runtime error or differences between a run in MATLAB and a run of the generated code. |
Editor warnings
ID | CC-2 |
Title | Prevent or suppress Code Analyzer messages. |
Priority | Strongly recommended |
Severity level | 4 |
Description | Prevent or suppress Code Analyzer messages shown in the MATLAB editor. When the messages cannot be prevented, suppress them on an individual basis and add the reason in the comments. The messages often indicate that improvements can be made to performance or stability of the code. |
Rationale | Performance, Stability |
Error function
ID | CC-3 |
Title | Do not use the built-in error . |
Priority | Mandatory |
Severity level | 1 |
Description | Do not use the built-in function error . |
Rationale | Compatibility During code generation the error function is ignored, so the execution just continues, with unexptected behaviour. Note that MEX-based validations can be misleading, as generating code for the MEX-target, still includes calls to the error function (as the MEX runs within MATLAB). |
Pause function
ID | CC-4 |
Title | Do not use the built-in pause . |
Priority | Mandatory |
Severity level | 4 |
Description | Do not use the built-in function pause . |
Rationale | Compatibility The function pause has many platform-dependent differences in implementation and behaviour. |
Struct manipulation
ID | CC-5 |
Title | Define all fields of a struct in a single, contiguous block of code. |
Priority | Mandatory |
Severity level | 1 |
Description | Define the entire struct in a single, contiguous block of code. Do not manipulate the layout of a structure after it was created. Do not use built-ins setfield , getfield , rmfield , orderfield and addfield , they are not supported by the Coder. |
Rationale | Compatibility |
Dynamic fields
ID | CC-6 |
Title | Do not use dynamic struct field or property names. |
Priority | Mandatory |
Severity level | 1 |
Description | Do not use dynamic struct field or property names. More on dynamic fieldnames |
Rationale | Compatibility Dynamic fieldnames are not supported for code generation. |
If else
ID | CC-7 |
Title | Every if shall have a matching else section. |
Priority | Mandatory |
Severity level | 4 |
Description | Every if shall have a matching else section, even if it does not contain executable code. |
Rationale | Completeness |
Switch otherwise
ID | CC-8 |
Title | Every switch shall have a matching otherwise section. |
Priority | Mandatory |
Severity level | 4 |
Description | Every switch shall have a matching otherwise section, even if it does not contain executable code. |
Rationale | By including an otherwise section, no execution paths are overlooked. Additionally, code coverage can be accurately reported because without otherwise , it is unclear whether it happens that none of the case s occur. |
Avoid:
switch reply
case "Yes"
saveData()
case "No"
clearData()
end
Instead use:
switch reply
case "Yes"
msg = "ok";
saveData()
case "No"
msg = "ok";
clearData()
otherwise
% Should not get here.
msg = "wrong reply";
end
Short-circuit operators
ID | CC-9 |
Title | Use short-circuit logical operators (&&, ||) only in conditional statements. |
Priority | Mandatory |
Severity level | 6 |
Description | Use short-circuit logical operators (&& , \|\| ) only in conditional statements. In other statements, you can use & or \| instead. |
Rationale | Compatibility, Completeness |
Avoid:
test1 = a > b;
test2 = b < a.^2;
result = test1 || test2;
Above will not work for vector values for a
and b
. Use elementwise logical operator |
instead.
Instead use:
result = test1 | test2;
Functionality shadowing
ID | CC-10 |
Title | Do not shadow built-in MATLAB functionality. |
Priority | Mandatory |
Severity level | 3 |
Description | Functions, classes and variables shall not shadow MATLAB-installed functionality or other code. This includes MATLAB files (.m , .p , .mlapp , .mlx ), mex-files (.mexw32 etc.) and Simulink files (.mdl , .slx ). Be aware that with toolboxes installed you might shadow MATLAB-installed functions which you do not shadow with core MATLAB only. |
Rationale | Shadowing code can result in unexpected behaviour, because it is unclear and not properly defined for example what function is called when multiple ones share the same name. |
Shell escape function
ID | CC-11 |
Title | Do not use the shell escape function. |
Priority | Mandatory |
Severity level | 1 |
Description | Do not use the shell escape function. It is not supported by the MATLAB Coder. |
Rationale | Compatibility |
Scripts
ID | CC-12 |
Title | Do not use scripts. |
Priority | Mandatory |
Severity level | 1 |
Description | Do not use scripts because these are not supported by the MATLAB Coder. |
Rationale | Compatibility |
Parentheses for precedence
ID | CC-13 |
Title | Use sufficient parentheses to clarify the order of execution in expressions. |
Priority | Strongly recommended |
Severity level | 5 |
Description | Use sufficient parentheses to clarify the order of execution in mathematical and logical expressions. Without them, the generated code may display unexpected behavior. |
Rationale | Readability, Robustness |
Floating-point comparisons
ID | CC-14 |
Title | Do not compare floating-point values using == or ~= . |
Priority | Strongly recommended |
Severity level | 3 |
Description | Do not compare floating-point values using == or ~= . Rounding errors due to algorithm design or machine precision can cause unexpected results. Use a tolerance instead. Generated code can produce floating-point results different from the MATLAB results. |
Rationale | Robustness |
Avoid:
out = myFcn(in) == sqrt(3);
Instead use:
out = abs(myFcn(in) - sqrt(3)) < 1e-12;
Binary expressions
ID | CC-15 |
Title | Binary expressions should not make an assumption on the evaluation order of their operands. |
Priority | Strongly recommended |
Severity level | 5 |
Description | Binary expressions should not make an assumption on the evaluation order of their operands. Generated code does not enforce the order of evaluation in expressions. It is therefore advised to define variables to enforce a specific evaluation order. For more info, see The Mathworks. |
Rationale | Robustness |
avoid
if (aFcnCall(z) || anotherFcnCall(z))
instead use
First compute the intermediate results in desired order:
isApprovedForA = aFcnCall(z);
isApprovedForB = anotherFcnCall(z);
if (isApprovedForA || isApprovedForB)
or in case you really need the conditional execution:
isApproved = aFcnCall(z);
if (~isApproved)
% not yet approved
isApproved = anotherFcnCall(z);
else
% allready approved
end
if (isApproved)
Concatenate array
ID | CC-16 |
Title | Do not use brackets to concatenate struct array field values or object array property values. |
Priority | Mandatory |
Severity level | 3 |
Description | Performing concatenation on an expanded array is not supported by the Coder before MATLAB R2020b. |
Rationale | Compatibility |
Avoid:
a = [myStruct(:).b];
Instead use:
len = numel(myStruct);
a = zeros(len);
for iMyStruct = 1:len
a(iMyStruct) = myStruct(iMyStruct).b;
end