Table of Contents

MonkeyProof MATLAB Coder Compatibility Standard

Table of Contents

Introduction

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:

  1. Install CC4M If you have not purchased the tool yet, you can do so here. Alternatively, you could request a free trial license there.
  2. 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.
  3. Select whether you want to check one or more files, all files in a folder, or all files in a MATLAB Project.
  4. Select what files/folder/project to check.
  5. Further customization is available, for example checking a folder including or excluding all subfolders.
  6. 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

IDA unique guideline identifier.
TitleBrief description of the guideline.
PriorityPriority 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.
DescriptionA more elaborate description of the guideline. Can include the reasoning behind the guideline: how does your code improve when applying the guideline?
RationaleOne or multiple words describing what the guideline is about. Examples: Compatibility, Stability.

Coder-compatibility function calls

IDCC-1
TitleDo not use built-in functions that are not supported by MATLAB Coder.
PriorityMandatory
Severity level1
DescriptionDo 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.
RationaleCompatibility.
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

IDCC-2
TitlePrevent or suppress Code Analyzer messages.
PriorityStrongly recommended
Severity level4
DescriptionPrevent 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.
RationalePerformance, Stability

Error function

IDCC-3
TitleDo not use the built-in error.
PriorityMandatory
Severity level1
DescriptionDo not use the built-in function error.
RationaleCompatibility
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

IDCC-4
TitleDo not use the built-in pause.
PriorityMandatory
Severity level4
DescriptionDo not use the built-in function pause.
RationaleCompatibility
The function pause has many platform-dependent differences in implementation and behaviour.

Struct manipulation

IDCC-5
TitleDefine all fields of a struct in a single, contiguous block of code.
PriorityMandatory
Severity level1
DescriptionDefine 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.
RationaleCompatibility

Dynamic fields

IDCC-6
TitleDo not use dynamic struct field or property names.
PriorityMandatory
Severity level1
DescriptionDo not use dynamic struct field or property names. More on dynamic fieldnames
RationaleCompatibility
Dynamic fieldnames are not supported for code generation.

If else

IDCC-7
TitleEvery if shall have a matching else section.
PriorityMandatory
Severity level4
DescriptionEvery if shall have a matching else section, even if it does not contain executable code.
RationaleCompleteness

Switch otherwise

IDCC-8
TitleEvery switch shall have a matching otherwise section.
PriorityMandatory
Severity level4
DescriptionEvery switch shall have a matching otherwise section, even if it does not contain executable code.
RationaleBy 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 cases 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

IDCC-9
TitleUse short-circuit logical operators (&&, ||) only in conditional statements.
PriorityMandatory
Severity level6
DescriptionUse short-circuit logical operators (&&, \|\|) only in conditional statements. In other statements, you can use & or \| instead.
RationaleCompatibility, 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

IDCC-10
TitleDo not shadow built-in MATLAB functionality.
PriorityMandatory
Severity level3
DescriptionFunctions, 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.
RationaleShadowing 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

IDCC-11
TitleDo not use the shell escape function.
PriorityMandatory
Severity level1
DescriptionDo not use the shell escape function. It is not supported by the MATLAB Coder.
RationaleCompatibility

Scripts

IDCC-12
TitleDo not use scripts.
PriorityMandatory
Severity level1
DescriptionDo not use scripts because these are not supported by the MATLAB Coder.
RationaleCompatibility

Parentheses for precedence

IDCC-13
TitleUse sufficient parentheses to clarify the order of execution in expressions.
PriorityStrongly recommended
Severity level5
DescriptionUse sufficient parentheses to clarify the order of execution in mathematical and logical expressions. Without them, the generated code may display unexpected behavior.
RationaleReadability, Robustness

Floating-point comparisons

IDCC-14
TitleDo not compare floating-point values using == or ~=.
PriorityStrongly recommended
Severity level3
DescriptionDo 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.
RationaleRobustness

Avoid:

out = myFcn(in) == sqrt(3);

Instead use:

out = abs(myFcn(in) - sqrt(3)) < 1e-12;

Binary expressions

IDCC-15
TitleBinary expressions should not make an assumption on the evaluation order of their operands.
PriorityStrongly recommended
Severity level5
DescriptionBinary 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.
RationaleRobustness

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

IDCC-16
TitleDo not use brackets to concatenate struct array field values or object array property values.
PriorityMandatory
Severity level3
DescriptionPerforming concatenation on an expanded array is not supported by the Coder before MATLAB R2020b.
RationaleCompatibility

Avoid:

a = [myStruct(:).b];

Instead use:

len = numel(myStruct);
a   = zeros(len);

for iMyStruct = 1:len
  a(iMyStruct) = myStruct(iMyStruct).b;
end