The goal of this standard that can be automatically checked is to help you write consistent, clean, understandable and maintainable m-code. The resulting code will be more readable for both yourself and others. These rules are no strict rules that must be followed at all cost. They are simply there to help you write m-code well and you can deviate from them as you please.
Most of the rules described here can be checked using CC4M by MonkeyProof Solutions. The checkable rules are indicated by this logo at the top. These rules are configured in the predefined MonkeyProofMATLABCodingStandard configurations set available with the tool. For instructions on how to check your code against a coding standard, see the video below. The steps are also described below the video.
You can check your code for compliance with the rules 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.
This coding standard has been constructed in consultation with multiple large companies that are using MATLAB on a daily basis. With years of experience in the industry, they are able to provide invaluable input on what MATLAB-related coding rules to follow and why.
With the help of -among others- Paul Jansen of TIOBE, we have been able to come to a coding standard that reflects the needs and wishes of professional teams trying to write clean and reliable MATLAB code that is easy to read and maintain.
The rules are grouped under specific categories to help keep things organized:
Naming conventions: Rules in this chapter describe how variables, functions etc. can be named in a consistent and insightful manner.
Layout & comments: This chapter contains rules to help improve readability of your code for yourself and for others. There are rules on whitespace, comments and more.
Statements & expressions: The rules in this chapter are about how to use constructs such as if/else blocks, what built-in functions or keywords to avoid, how to best structure your statements etc.
Higher level rules: This chapter contains (among others) rules on higher-level objects such as functions or files.
Security: This chapter contains rules on potential security risks.
Priority of the rule can be one of Mandatory, Strongly recommended and Recommended.
Severity level
Severity level of the rule can be in the range from 1 to 10. The most important ones are of severity level 1 and next levels are reserved for more pedantic issues. Each of the levels is described below.
Description
A more elaborate description of the rule. Can include exceptions.
Rationale
Rationale or justification behind the rule: why should you apply this rule and how does your code improve when applying it or deteriorate when violating it?
Exception (Optional)
An exception might apply to a rule, i.e. a case for which the rule does not hold.
The following definition of the severity levels is used as a guide to make it easier to group the different rules and coding standards.
Level 1 - Certainly a programming error
Level 2 - Very likely a programming error
Level 3 - Programming pitfall/undesired programming construct/accident waiting to happen
Level 4 - Design issue with high impact on reliability or maintainability
Level 5 - Design issue with low impact on reliability or maintainability
Level 6 - Portability or performance issue or high impact other issue
Level 7 - Comment related issue or medium impact other issue
Level 8 - Naming convention or low impact other issue
Level 9 - Style related issue
Level 10 - Controversial issue or issue with a relatively high false positive rate
Each rule in this coding standard has a severity level attached to it. These severity levels are set in the CC4M and one can configure for which severity levels to check. The severity levels are related to the severity levels of Tiobe's TICS tooling.
Iterator variables shall be prefixed with i, j, k etc.
Priority
Recommended
Severity level
8
Description
Iterator variable names shall be at least 3 characters long. In nested for-loops, the starting letters of the iterator names shall be subsequent letters in the alphabet.
Rationale
Iterator variables of for-loops are easily distinguishable from other variables by using these prefixes.
Functions and variables shall not shadow MATLAB-installed functionality or other code.
Priority
Mandatory
Severity level
3
Description
Functions 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.
Names of classes, functions, variables, properties and struct fields should not start with temp, my, etc.
Priority
Recommended
Severity level
8
Description
Names of classes, functions, variables, properties and struct fields should not start with temp, my and they should not have names such as myClass, testFunction, etc.
Rationale
Names like these do not properly indicate what the class, function or variable is for.
A function name should consist of a verb and a noun.
Priority
Recommended
Severity level
8
Description
All function names shall consist of a verb followed by a noun.
Rationale
This way it is more likely to be clear what the function does and if there is no suitable name following this rule, (for example because the function does more than one thing) the function may have to be refactored.
Name-value pairs shall be UpperCamelCased without numbers in them.
Priority
Recommended
Severity level
8
Description
Name-value pairs shall be UpperCamelCased (PascalCased) and contain no numbers, both when using the arguments block and when using the inputParser function.
Rationale
Consistency in name-value pair naming improves readability of the code and predictability of calling syntax. Name-value pairs in MATLAB functions are UpperCamelCased as well, which means that user-defined functions are more easily integrated with those as well.
Variable names shall be at most 63 characters long. Function names shall be at least 3 and at most 63 characters long.
Priority
Recommended
Severity level
8
Description
Variable names shall be at most 63 characters long. Function names shall be at least 3 and at most 63 characters long.
Rationale
Names shall be descriptive, so should not be too short. However, variable names can sometimes be single characters (x, y) and still be descriptive. MATLAB can not handle names of more than 63 characters long.
The prefix n should be used for variables that represent a number of things.
Priority
Strongly recommended
Severity level
8
Description
The prefix n should be used for variables that represent a number of things. Do not use the prefix for other purposes and do not use other prefixes for representing the number of things.
Rationale
Variables starting with this prefix can easily be identified.
classdef CarAnalyzer
methods
function velocity = initialVelocity(theCar)
velocity = theCar.velocity;
end
function position = initialPosition(theVehicle)
position = theVehicle.position;
end
end
end
classdef CarAnalyzer
methods
function velocity = initialVelocity(theCar)
velocity = theCar.velocity;
end
function position = initialPosition(theCar)
position = theCar.position;
end
end
end
This chapter contains rules to help improve readability of your code for yourself and for others.
The rules on indentation and whitespace make the code more visually appealing whereas rules on comments increase the usability of the code they reference.
By using ample whitespace, your code will look clean and the more complicated statements maintain their readability.
Comment blocks (with %{ notation) shall not be used. Every first comment on a line shall start with a comment indicator (% or ...). Use CTRL-R and CTRL-T to comment/uncomment blocks of code.
Indent function bodies on the root level of a file.
Priority
Recommended
Severity level
10
Description
Bodies of all functions (at any level) shall be indented. By default, only method bodies in a classdef file and nested functions are indented. This can be changed in the MATLAB preferences under Editor/Debugger / Language / Indenting by setting the Function indenting format to Indent all functions.
Rationale
This helps maintain the consistency with all other blocks in MATLAB.
Surround the following operators with spaces: = : ^ == <= >= < > ~= & && | || + - * .* / Do not add a space between the unary minus-sign and its operand.
Rationale
Whitespace around operators often leads to improved readability. As an exception, do not use spaces around the equals signs when using the Name=Value syntax introduced in MATLAB R2021a.
Lines shall be no more than 120 characters long, including comments. Use the MATLAB preference for displaying a vertical line at 120 characters. Comments can be automatically wrapped by setting a MATLAB preference.
Rationale
A line of code should fit on a screen. Long lines of code are difficult to interpret and generally indicate great complexity.
Combine multiple blocks of properties or methods with equal attributes into one.
Priority
Recommended
Severity level
9
Description
Combine multiple properties and methods blocks with equal attribute values into one. Do not set attributes to their default values.
Rationale
Having multiple blocks with the exact same attributes is unnecessary and decreases the readability of classdef files. Group properties and method declarations using comments.
Do not use tab characters. Use spaces instead. By default, MATLAB inserts spaces when the TAB key is pressed.
Rationale
The number of characters used to display a tab character may vary depending on the MATLAB preferences. Inserting spaces prevents any display issues related to this.
Write header comments providing user documentation.
Priority
Recommended
Severity level
7
Description
Write header comments with text markup to provide user documentation useful both in-file and when using the help and lookfor functions. Optionally add syntax and see also sections.
Rationale
This increases readability, and makes the code more likely to be found and less likely to be reinvented.
function [avg, maxSize] = measureSize(obj, dim)
%MEASURESIZE Computes the size of the Item object.
%
% Input:
% obj The Item object.
% dim Dimension to measure.
%
% Output:
% avg Average size of the item.
% maxSize Maximum size of the item.
avg = mean(obj.Size, dim);
maxSize = max(obj.Size, dim);
end
The rules in this chapter are about how to use constructs such as if/else blocks, what built-in functions or keywords to avoid or how to best structure your statements.
Following these rules will ensure the individual statements in your code are complete and easy to read.
Define and document numeric values as variables before using them in an expression.
Priority
Strongly recommended
Severity level
5
Description
Do not use magic numbers in your expression. Define them as variables before using them.
Rationale
This encourages reuse and documentation of numerical constants and improves overall readability. As an exception, unit conversion (for example, multiplying by 1e6) can be directly applied.
Every if shall have an else section, even if it does not contain executable code.
Rationale
By including an else section, no execution paths are overlooked. Additionally, code coverage can be accurately reported because without else, it is unclear whether the if-condition is ever false.
Exceptions
else sections may be omitted in case of input processing or error handling.
Every switch shall have an 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 cases occur.
Use parentheses to clarify precedence in logical expressions.
Priority
Strongly recommended
Severity level
5
Description
Use parentheses to clarify the precedence of operands in expressions with multiple logical operators. No parentheses are required when only one type of logical operator is used. For example: d = a && b && c;.
Rationale
By clarifying the precedence of the operands in such expressions, readability is improved and unexpected behaviour is prevented.
Use parentheses to clarify precedence in mathematical expressions.
Priority
Strongly recommended
Severity level
5
Description
Use parentheses to clarify the precedence of operands in expressions with multiple mathematical operators. No parentheses are required when only one type of mathematical operator is used. For example: d = a * b * c;.
Rationale
By clarifying the precedence of the operands in such expressions, readability is improved and unexpected behaviour is prevented.
Make sure all functions called are known by MATLAB.
Priority
Mandatory
Severity level
1
Description
Make sure all functions called are known and accessible by MATLAB. Be aware that functions might be unknown with core MATLAB only, they might require the install of toolboxes.
Rationale
Attempting to access packages, classes and functions not on the MATLAB path will result in an error.
Only use the try construct for exception handling.
Priority
Strongly recommended
Severity level
5
Description
Only use the try construct for exception handling. An exception object must be assigned or created and an error function must be called in the catch. Do not use try/catch to suppress errors or to express simple conditions. There are other, more suitable options for that.
Rationale
Using try for simple error suppression can result in poor performance and unexpected behaviour. When a different error occurs than the one expected, it can go undetected because of the try/catch.
Every if that has an elseif section shall have an else section.
Priority
Strongly recommended
Severity level
4
Description
Every if with an elseif section shall have an else section, even if it does not contain executable code.
Rationale
By including an else section, default execution paths are not overlooked. Additionally, code coverage can be accurately reported because without else, it is unclear whether it is ever the case that neither the if nor the elseif conditions are true.
Keep number of lines of code and cyclomatic complexity to an acceptable level, especially for nested functions and methods in a classdef file. Use the values of the table below.
Rationale
Short functions are more likely to be readable, reusable and testable.
Every constructor shall have exactly one output: an object of the class.
Rationale
A second constructor output is unusual, so will be unexpected for readers of the code.
Exception
The second output may be used to indicate whether or not construction was successful. Alternatively, this is done by either throwing an error or by using a property for this.
Use functions even if there are no inputs or outputs.
Rationale
The scope of variables in a script is not bounded as one might expect. It is therefore safer to use functions instead. Additionally, scripts are not compatible with Matlab Coder.
Exception
Initialization of a project, or specifically creating base workspace structures that are used in models, without the need for assignin.
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.
Rationale
The messages usually indicate that improvements can be made to the performance or stability of the code. Adding file-wide Code Analyzer suppressions is discouraged because new triggers of the messages may be overlooked.
Ownership of a structure resides with the creator of that structure.
Priority
Strongly recommended
Severity level
4
Description
Ownership of a structure resides with the creator of that structure, so do not add or remove fields from an existing structure outside of the function in which it was created.
Rationale
Adding or removing fields from an existing structure outside of the function in which it was created reduces the robustness of the code. Related to coder compatibility, in generated code, adding a new field to a structure that has already been read or indexed will cause an error.
Functions should do precisely one thing well, and encapsulate a single idea.
Priority
Strongly recommended
Severity level
4
Description
Single responsibility principle : all sub-functions and most functions should do one thing very well, and encapsulate a single idea.
Rationale
The single responsibility principle makes code more readable, modular, and testable. Multi-purpose functions can often be split up into atomic units which are called on the input data in sequence. Functions should not try to be all things to all users.
% data is a table or struct of arrays.
density = data.mass ./ (data.height .* data.width .* data.length);
% Alternatively, with individual vectors.
density = mass ./ (theHeight .* theWidth .* theLength);
Function input arguments must be independent, and the function must not assume a dependency between them.
Rationale
Assuming a dependency between independent input parameters reduces the robustness of the code. Conversely, if the inputs to a function are dependent, treating them as independent also reduces robustness.
The first output of a constructor should be the object of the class.
Priority
Mandatory
Severity level
1
Description
The first output of a constructor should be the object of the class.
Rationale
If the first output is not the object of the class, it will result in a runtime error. It is not logical and harder to read if the first output of a constructor is not the object of the class.
Do not use iterator variables outside the for loop.
Priority
Mandatory
Severity level
2
Description
Do not use iterator variables outside the for loop, since this might lead to unexpected behavior.
Rationale
Using a loop iterator variable outside the for loop might indicate a programming error. For example if the for loop is not entered, the iterator variable becomes an empty double.
function processTemperatures(Tin1, Tin2, Tin3)
x = calculateMaxTemperature(Tin1, Tin2, Tin3);
end
function out = calculateMaxTemperature(Tin1, Tin2)
out = max(Tin1, Tin2);
end
function processTemperatures(Tin1, Tin2, Tin3)
x = calculateMaxTemperature(Tin1, Tin2);
end
function out = calculateMaxTemperature(Tin1, Tin2)
out = max(Tin1, Tin2);
end
Classes shall not implement properties inherited from superclasses.
Priority
Mandatory
Severity level
1
Description
Classes shall not implement concrete properties that are inherited from a superclass. In order to assign default values to concrete properties inherited from a superclass, assign the values in the constructor of the subclass, or make the properties Abstract in the superclass.
Rationale
Attempting to use such a class will result in a runtime error.
Exception
There are two separate conditions under which you can redefine superclass properties: The inherited property is abstract. The values of the superclass property SetAccess and GetAccess attributes are private.
classdef Measurement
properties
measurementDate
end
end
classdef Pressure < Measurement
methods
function obj = Pressure()
obj.measurementDate = today();
end
end
end
This chapter contains rules to help avoiding potential security risks.
The topic of (online) security is very broad and solutions can be applied in many gradations of strictness. Therefore, it is recommended to discuss the topic with those familiar with the company policies, to determine which security considerations should be taken into account for your application.
These guidelines help to avoid some common security risks, but are by no means a substitute for a good design and security analysis by a professional.
Do not use the built-in eval. Minimize the use of feval, evalin and evalc.
Priority
Mandatory
Severity level
3
Description
Do not use the built-in eval. Minimize the use of feval, evalin and evalc.
Rationale
These functions can have harmful results and statements using them are usually difficult to read and maintain. Additionally, it may be overlooked when variables are defined or altered by calls to these functions.
When using the weboptions or matlab.net.http.HTTPOptions classes, do not set an empty certificate file name.
Priority
Mandatory
Severity level
4
Description
When using the weboptions or matlab.net.http.HTTPOptions classes, do not empty the CertificateFilename option.
Rationale
For security reasons, it is discouraged to empty the CertificateFilename property of a weboptions or matlab.net.http.HTTPOptions object because that disables certificate validation.
When reading an XML file, set the AllowDoctype option to false.
Priority
Mandatory
Severity level
3
Description
When using the xmlread or matlab.io.xml.dom.Parser functions, make sure to set AllowDoctype to false.
Rationale
In XML, doc type definitions can contain exploding content that -if not caught- can cause unexpected behavior. Therefore, doc types should not be allowed to be read.
content = xmlread(myFile, "AllowDoctype", false);
% For matlab.io.xml.dom.Parser configurations, AllowDoctype is false by default.
p = matlab.io.xml.dom.Parser();
p.parseFile(myFile);
Avoid constant variable names as: username, loginname, password etc.
Priority
Mandatory
Severity level
3
Description
Avoid the use of contant variable names as: username, loginname, password, credentials etc, instead obtain these via a user input action or read them from a (secured) file.
Rationale
For security reasons, it is discouraged to use hard-coded username and or password since this way they can be easily shared with others accidentally.
Do not use hard-coded values for Username and Password.
Priority
Mandatory
Severity level
3
Description
Do not use hard-coded values for the properties Username and Password, instead obtain these via a user input action or read them from a (secured) file.
Rationale
For security reasons, it is discouraged to use hard-coded username and password since this way they can be easily shared with others accidentally.
import matlab.net.http.Credentials
% Ask the user to provide a username and password, for example using a dialog or prompt:
[username, password] = showLoginDialog();
creds = Credentials('Username', username, 'Password', password);
weboptions("Username", username, "Password", password);
Note: This is just one example of how to obtain credentials without hardcoding them. Ask your IT department for the available options.