Table of Contents

MonkeyProof MATLAB Coding Standard++

Table of Contents

Introduction

Introduction

The goal of this set of coding standards 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.

Automatic compliance checking

Most of the rules described here can be checked using CC4M by MonkeyProof Solutions. The checkable rules are indicated by this logo cc4m_logo_inline at the top. These rules are configured in the predefined MonkeyProofSolutions 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:

  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.

Structure of this document

The coding standards and 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 and coding standards 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) coding standards on higher-level objects such as functions or files.
  • Security: This chapter contains rules on potential security risks.

Rule template

Every rule is structured as follows:

Rule name

IDA unique rule identifier.
TitleBrief description of the rule.
PriorityPriority of the rule can be one of Mandatory, Strongly recommended and Recommended. Exactly what each of these means for your case is up to you to decide.
Severity levelSeverity 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.
DescriptionA more elaborate description of the rule. Can include the reasoning behind the rule: how does your code improve when applying the rule?
RationaleOne or multiple words describing what the rule is about. Examples: Readability, Stability.

Avoid:

One or more code examples to avoid using.

Instead use:

The example(s) above improved by complying with the rule.

Severity levels

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.

Expansion of the MonkeyProof MATLAB Coding Standard

This standard includes the rules of the MonkeyProof MATLAB Coding Standard which can be found here and mainly adds naming conventions to it amongst some other rules. Each unique rule has its own unique rule identifier.

The following rules are different:

  • NAMING-1 in this standard replaces NAMING-20 from the MonkeyProof MATLAB Coding Standard. This rule is about the length of variable names.

The following rules are an addition:

  • NAMING-5 a rule on variable casing.
  • NAMING-6 a rule on function casing.
  • NAMING-7 a rule on class casing.
  • NAMING-8 a rule on property casing.
  • NAMING-9 a rule on package casing.
  • NAMING-10 a rule on event casing.
  • NAMING-11 a rule on struct field casing.
  • NAMING-12 a rule on enumeration member casing.
  • NAMING-13 a rule on enumeration member casing.
  • STAT-15 a rule on minimizing the use of return.
  • STAT-20 a rule on avoiding the use of cell arrays.
  • LAYOUT-10 a rule on binary operators in multi-line statements.
  • FCNS-27 a rule on writing interpretable code.

Naming conventions

The rules in this chapter describe how variables, functions etc. can be named in a consistent and insightful manner. If you wish to deviate from the casing rules (for example if you want your variable names snake_cased) at least make sure to apply consistent casing. Use the same casing scheme throughout your code so that classes, functions etc. can be easily identified by their name.

Name length cc4m_logo_inline

IDNAMING-1
TitleVariable names shall be at most 32 characters long. Function names shall be at least 3 and at most 32 characters long.
PriorityRecommended
Severity level8
DescriptionVariable names shall be at most 32 characters long. Function names shall be at least 3 and at most 32 characters long.
RationaleNames shall be descriptive, so should not be too short. However, variable names can sometimes be single characters (x, y) and still be descriptive. Names that are too long can reduce readability because they introduce long lines of code.

Avoid:

maximumValueOfTheEntireSetOfDataPoints = max(data);

Instead use:

maxData = max(data);

Loop iterator naming cc4m_logo_inline

IDNAMING-2
TitleIterator variables shall be prefixed with i, j, k etc.
PriorityRecommended
Severity level8
DescriptionIterator 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.
RationaleIterator variables of for-loops are easily distinguishable from other variables by using these prefixes.

Avoid:

for nodeIdx = 1 : 10
    for j = 1 : 3
        myGraph(nodeIdx).plotIt(j);
    end
end

Instead use:

for iNode = 1 : 10
    for jPoint = 1 : 3
        myGraph(iNode).plotIt(jPoint);
    end
end

Negated boolean names cc4m_logo_inline

IDNAMING-3
TitleNegated boolean variable names shall be avoided.
PriorityStrongly recommended
Severity level8
DescriptionAvoid variable names including the word not.
RationaleReadability decreases when variables have negated boolean names, especially in combination with the ~ operator.

Avoid:

if ~notValid && isNotFound
    error('My error message.')
end

Instead use:

if isValid && ~isFound
    error('My error message.')
end

Parent / child name redundancy cc4m_logo_inline

IDNAMING-4
TitleNames of fields and properties shall not contain their parent's name.
PriorityRecommended
Severity level8
DescriptionNames of fields and properties shall not contain their parent struct or object's name.
RationaleWhen referenced, the fields and properties can have the same phrase multiple times in a row, which is unnecessary.

Avoid:

Beam.beamThickness
chair.weightOfChair

Instead use:

Beam.thickness
chair.weight

Variable casing cc4m_logo_inline

IDNAMING-5
TitleVariable names shall be lowerCamelCased.
PriorityRecommended
Severity level8
DescriptionVariable names including acronyms shall be lowerCamelCased.
RationaleConsistency in function naming improves readability and maintainability of the code.

Avoid:

foo_bar = 1;
EggsBenedict = 0;
theHTMLPage = "www.test.com";

Instead use:

fooBar = 1;
eggsBenedict = 0;
theHtmlPage = "www.test.com";

Function casing cc4m_logo_inline

IDNAMING-6
TitleUser-defined functions and methods shall be lowerCamelCased.
PriorityRecommended
Severity level8
DescriptionUser-defined functions and methods shall be lowerCamelCased. This excludes a class's constructor because it must be named after its class.
RationaleConsistency in function naming improves readability of the code.

Avoid:

compute_values()
GetBestCandidates()

Instead use:

computeValues()
getBestCandidates()

Class casing cc4m_logo_inline

IDNAMING-7
TitleClass names shall be UpperCamelCased.
PriorityRecommended
Severity level8
DescriptionClass names shall be UpperCamelCased (PascalCased).
RationaleConsistency in class naming improves readability of the code.

Avoid:

theClassName
other_class_name

Instead use:

TheClassName
OtherClassName

Property casing cc4m_logo_inline

IDNAMING-8
TitleProperty names shall be lowerCamelCased.
PriorityRecommended
Severity level8
DescriptionClass property names shall be lowerCamelCased.
RationaleConsistency in class property naming improves readability of the code.

Avoid:

Chair.ArmRest
Chair.sell_price

Instead use:

Chair.armRest
Chair.sellPrice

Package casing cc4m_logo_inline

IDNAMING-9
TitlePackage folder names shall be lower-cased.
PriorityRecommended
Severity level8
DescriptionPackage folder names shall be completely lower-cased and not contain underscores.
RationaleThis way, package folders are easily identified as such.

Avoid:

+thePackageName
+another_package

Instead use:

+thepackagename
+anotherpackage

Event casing cc4m_logo_inline

IDNAMING-10
TitleEvent names shall be UpperCamelCased.
PriorityRecommended
Severity level8
DescriptionEvent names shall be UpperCamelCased (PascalCased).
RationaleConsistency in event naming improves readability of the code.

Avoid:

classdef AmplitudeControl < handle
    events
        buttonPushed
        BUTTON_RELEASED
    end
end

Instead use:

classdef AmplitudeControl < handle
    events
        ButtonPushed
        ButtonReleased
    end
end

Struct field casing cc4m_logo_inline

IDNAMING-11
TitleNames of struct fields shall be lowerCamelCased.
PriorityRecommended
Severity level8
DescriptionNames of struct fields shall be lowerCamelCased.
RationaleUsing different naming conventions for struct fields and class properties facilitates a clear distinction between the two.

Avoid:

circleData.Coordinates
circleData.radius_std

Instead use:

circleData.coordinates
circleData.radiusStd

Constant casing cc4m_logo_inline

IDNAMING-12
TitleConstant variable names shall be SCREAMING_SNAKE_CASED.
PriorityRecommended
Severity level8
DescriptionConstant variable names shall be written in all-caps with underscores separating the words.
RationaleBy applying this naming convention, constant variables are easily identified as such.

Avoid:

r = 2.86e-23;
base_response = "Hello mr/ms ";

Instead use:

R = 2.86e-23;
BASE_RESPONSE = "Hello mr/ms ";

Enumeration member casing cc4m_logo_inline

IDNAMING-13
TitleEnumeration members shall be UpperCamelCased and shall not contain numbers.
PriorityRecommended
Severity level8
DescriptionMembers of an enumeration class shall be UpperCamelCased (PascalCased) and shall not contain numbers.
RationaleConsistency in enumeration member naming improves readability of the code.

Avoid:

classdef TheClass < handle
    enumeration
        chargingFrom0
        FULL
    end
end

Instead use:

classdef TheClass < handle
    enumeration
        ChargingFromEmpty
        Full
    end
end

Name shadowing cc4m_logo_inline

IDNAMING-14
TitleFunctions and variables shall not shadow MATLAB-installed functionality or other code.
PriorityMandatory
Severity level3
DescriptionFunctions 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).
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.

Names to avoid cc4m_logo_inline

IDNAMING-15
TitleNames of classes, functions, variables, properties and struct fields should not start with temp, my, etc.
PriorityRecommended
Severity level8
DescriptionNames 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.
RationaleNames like these do not properly indicate what the class, function or variable is for.

Name-value pair casing cc4m_logo_inline

IDNAMING-18
TitleName-value pairs shall be UpperCamelCased without numbers in them.
PriorityRecommended
Severity level8
DescriptionName-value pairs shall be UpperCamelCased (PascalCased) and contain no numbers, both when using the arguments block and when using the inputParser function.
RationaleConsistency 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.

Avoid:

function plotMeasurement(options)

arguments
    options.number_of_lines             = 3
    options.precision                   = 2.5
    options.SHOW_LEGEND (1, 1) logical  = true
end

...

end

Instead use:

function plotMeasurement(options)

arguments
    options.NumberOfLines               = 3
    options.Precision                   = 2.5
    options.ShowLegend (1, 1) logical   = true
end

...

end

The 'test' suffix cc4m_logo_inline

IDNAMING-19
TitleReserve the suffix Test for unit test file names.
PriorityRecommended
Severity level8
DescriptionUse the suffix Test only for unit test file names.
RationaleThis increases the readability of the code as it is clear from the name of the file that it is a unit test file.

Name class object

IDNAMING-26
TitleThe class object name should be consistent within the entire class.
PriorityRecommended
Severity level8
DescriptionThe class object name should be consistent within the entire class. Choose a descriptive and relevant name.
RationaleThis increases the readability and maintanability of the code.

Avoid:

classdef CarAnalyzer
	methods
		function velocity = initialVelocity(theCar)
			velocity = theCar.velocity;
		end
		
		
		function position = initialPosition(theVehicle)
			position = theVehicle.position;
		end
	end
end

Instead use:

classdef CarAnalyzer
	methods
		function velocity = initialVelocity(theCar)
			velocity = theCar.velocity;
		end
		
		
		function position = initialPosition(theCar)
			position = theCar.position;
		end
	end
end

Layout & comments

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 cc4m_logo_inline

IDLAYOUT-1
TitleComment blocks shall not be used.
PriorityRecommended
Severity level7
DescriptionComment 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.
RationaleConsistent comment syntax improves readability.

Avoid:

%{ This is a comment.
This is also a comment.
%}

Instead use:

% This is a comment.
% This is also a comment.

Function indentation cc4m_logo_inline

IDLAYOUT-2
TitleIndent function bodies on the root level of a file.
PriorityRecommended
Severity level10
DescriptionBodies 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.
RationaleThis helps maintain the consistency with all other blocks in MATLAB.

Avoid:

function computeWeight(in)
weight = 2 * in;
end

Instead use:

function computeWeight(in)
    weight = 2 * in;
end

Whitespace in statementscc4m_logo_inline

IDLAYOUT-3
TitleSurround operators with spaces.
PriorityRecommended
Severity level9
DescriptionSurround the following operators with spaces:
= : ^ == <= >= < > ~= & && | || + - * .* /
Do not add a space between the unary minus-sign and its operand.
RationaleWhitespace 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.

Avoid:

isValid=y>0&&x==-1;

Instead use:

isValid = y > 0 && x == -1;

Whitespace after characters cc4m_logo_inline

IDLAYOUT-4
TitleCommas, semicolons and keywords shall be followed by a space unless at the end of the statement.
PriorityRecommended
Severity level9
DescriptionCommas, semicolons and keywords (for, while, if etc.) shall be followed by a space unless at the end of the statement.
RationaleA clear separation of keywords from other code improves readability.

Avoid:

while(ismember(x, [3,5,7,11,13]))
    x = x + 2;
end

Instead use:

while ismember(x, [3, 5, 7, 11, 13])
    x = x + 2;
end

Line length cc4m_logo_inline

IDLAYOUT-5
TitleLines shall be no more than 120 characters long.
PriorityRecommended
Severity level10
DescriptionLines 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.
RationaleA line of code should fit on a screen. Long lines of code are difficult to interpret and generally indicate great complexity.

Avoid:

theText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut luctus arcu ex, at viverra nibh malesuada ac. Proin vel arcu leo.';

Instead use:

theText = ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. ', ...
            'Ut luctus arcu ex, at viverra nibh malesuada ac. Proin vel arcu leo.'];

Indentation length cc4m_logo_inline

IDLAYOUT-6
TitleIndentation shall be four spaces long.
PriorityRecommended
Severity level9
DescriptionIndentation shall be four spaces long. This is the default setting in the MATLAB editor.
RationaleUsing an adequate and consistent number of spaces for indentation improves readability and prevents unnecessary changes when others work on the code.

Avoid:

if x > 0
  if x < 2
    disp(x)
  end
end

Instead use:

if x > 0
    if x < 2
        disp(x)
    end
end

Comments on poorly written code

IDLAYOUT-7
TitleComments should not justify poorly written code.
PriorityStrongly recommended
Severity level7
DescriptionDo not use comments to justify or mock poorly written code.
Write proper code that requires no justification instead.
RationaleReadability will be improved if issues with the code are fixed immediately instead of documented in the comments.

Avoid:

x = 2;
y = 3 * x; % TODO: take z into account.

% FIXME: This piece of ugly code is copied from StackExchange.
z=[1,23,8.1]*(x^3.1415)*sqrt(y);

Instead use:

x = 2;
y = 3 * x + z; 

z = [1, 23, 8.1] * (x ^ 3.1415) * sqrt(y);

Equals sign alignment cc4m_logo_inline

IDLAYOUT-8
TitleAlign equals signs within a block of assignments.
PriorityRecommended
Severity level9
DescriptionAlign equals signs within the same block of assignments using proper indentation.
RationaleAligning equals signs improves readability.

Avoid:

carWeight = 1.7 * 600;
nWheels = 2 + 2;
maximumSpeed = 190;

Instead use:

carWeight       = 1.7 * 600;
nWheels         = 2 + 2;
maximumSpeed    = 190;

Commas in rows cc4m_logo_inline

IDLAYOUT-9
TitleUse commas to separate elements in a row.
PriorityRecommended
Severity level9
DescriptionUse commas to separate elements in a row. Place the comma directly after the element.
RationaleThis improves readability, especially in arrays of strings or character vectors.

Avoid:

fig.Position    = [0 1000 1.5 130];
saying          = ['An apple a ' period ' keeps the doctor away.'];

Instead use:

fig.Position    = [0, 1000, 1.5, 130];
saying          = ['An apple a ', period, ' keeps the doctor away.'];

Line continuation with operators cc4m_logo_inline

IDLAYOUT-10
TitleBinary operators in multi-line statements shall be placed at the start and not at the end of the line.
PriorityRecommended
Severity level9
DescriptionPlace binary operators in multi-line statements at the start and not at the end of the line.
RationaleBy placing binary operators at the start of the line, it is immediately clear what the line does.

Avoid:

isDone = isImplemented && ...
    isTested && ...
    isDocumented;

Instead use:

isDone = isImplemented ...
    && isTested ...
    && isDocumented;

Methods/Properties blocks with duplicate attributes cc4m_logo_inline

IDLAYOUT-11
TitleCombine multiple blocks of properties or methods with equal attributes into one.
PriorityRecommended
Severity level9
DescriptionCombine multiple properties and methods blocks with equal attribute values into one. Do not set attributes to their default values.
RationaleHaving multiple blocks with the same attributes is unnecessary and decreases the readability of classdef files.

Avoid:

classdef Rocket
    properties (Access = public, Hidden = false, Constant)
        Fuel = "Nuclear"
    end
    
    properties (Constant = true)
        Capacity = 2
    end
end

Instead use:

classdef Rocket
    properties (Constant)
        Fuel = "Nuclear"
        Capacity = 2
    end
end

Whitespace in statements cc4m_logo_inline

IDLAYOUT-12
TitleDo not use whitespace at the end of a line.
PriorityRecommended
Severity level9
DescriptionTo keep things clean, do not use white space at the end of a line of code unless it is followed by a comment.
RationaleThis prevents smart-indenting a file from inducing changes to those lines.

Tab characters cc4m_logo_inline

IDLAYOUT-13
TitleDo not use tab characters. Use spaces instead.
PriorityRecommended
Severity level9
DescriptionDo not use tab characters. Use spaces instead. By default, MATLAB inserts spaces when the TAB key is pressed.
RationaleThe 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.

Properties blocks before methods blocks cc4m_logo_inline

IDLAYOUT-14
TitleAll properties blocks should come before all methods blocks in classdef files.
PriorityRecommended
Severity level9
DescriptionIn classdef files all properties blocks should be before all method blocks.
RationaleFor readability, it is advisable to have all properties blocks before the method blocks in classdef files.

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 or how to best structure your statements. Following these rules will ensure the individual statements in your code are complete and easy to read.

Constant definitions at top cc4m_logo_inline

IDSTAT-1
TitlePlace constant definitions at the top of the function.
PriorityRecommended
Severity level9
DescriptionConstant definitions shall be placed at the top of the function, after defining global/persistent variables.
RationaleThat way they can easily be found and identified.

Avoid:

function testConstants(x)
y = 3 * x;
MAX_Z = 100;
z = min(y, MAX_Z);
end

Instead use:

function testConstants(x)
MAX_Z = 100;

y = 3 * x;
z = min(y, MAX_Z);
end

Magic numbers cc4m_logo_inline

IDSTAT-2
TitleDefine and document numeric values as variables before using them in an expression.
PriorityStrongly recommended
Severity level5
DescriptionDo not use magic numbers in your expression. Define them as variables before using them.
RationaleThis 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.

Avoid:

for iPick = 1 : 52
    disp(randi(13));
end

Instead use:

DECK_SIZE   = 52;
N_VALUES    = 13;

for iPick = 1 : DECK_SIZE
    disp(randi(N_VALUES));
end

Function calls without inputs cc4m_logo_inline

IDSTAT-3
TitleAdd empty parentheses to function calls without input arguments.
PriorityRecommended
Severity level9
DescriptionAdd empty parentheses to function calls without input arguments.
RationaleThis helps to emphasize the fact that they are function calls and not variables or properties.

Avoid:

x = rand * 2;

Instead use:

x = rand() * 2;

One statement per line cc4m_logo_inline

IDSTAT-4
TitleWrite one statement per line.
PriorityRecommended
Severity level9
DescriptionWrite at most one statement per line.
RationaleMaintain readability of your code by having each line of code do exactly one thing.

Avoid:

for iNode = 1 : 3, x = x + iNode; disp(x); end

Instead use:

for iNode = 1 : 3
    x = x + iNode;
    disp(x);
end

If else cc4m_logo_inline

IDSTAT-5
TitleEvery if shall have an else section.
PriorityRecommended
Severity level9
DescriptionEvery if shall have an else section, even if it does not contain executable code.
RationaleBy 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.
Exceptionselse sections may be omitted in case of input processing or error handling.

Avoid:

if x > 0
    saveData()
end

Instead use:

if x > 0
    saveData()
else
    % Do not save data.
end

Switch otherwise cc4m_logo_inline

IDSTAT-6
TitleEvery switch shall have an otherwise section.
PriorityStrongly recommended
Severity level4
DescriptionEvery switch shall have an 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"
        saveData()
    case "No"
        clearData()
    otherwise
        % Should not get here.
        error("Unknown reply " + reply)
end

Mixed types in expressions cc4m_logo_inline

IDSTAT-7
TitleDo not use multiple operand types per operator.
PriorityMandatory
Severity level3
DescriptionDo not use multiple operand types per operator. For example, do not mix logical and numerical operands with a multiplication operator.
RationaleMixing operand types per operator can cause unexpected results and may lead to errors in case of true incompatibilities.

Avoid:

d = a * b && c;

Instead use:

d = (a * b > 0) && c;

Parentheses in logical expressions cc4m_logo_inline

IDSTAT-8
TitleUse parentheses to clarify precedence in logical expressions.
PriorityStrongly recommended
Severity level5
DescriptionUse 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;.
RationaleBy clarifying the precedence of the operands in such expressions, readability is improved and unexpected behaviour is prevented.

Avoid:

d = a && b || c;

Instead use:

d = (a && b) || c;

Parentheses in mathematical expressions cc4m_logo_inline

IDSTAT-9
TitleUse parentheses to clarify precedence in mathematical expressions.
PriorityStrongly recommended
Severity level5
DescriptionUse 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;.
RationaleBy clarifying the precedence of the operands in such expressions, readability is improved and unexpected behaviour is prevented.

Avoid:

d = a * b + c;
h = f / 2 * g;

Instead use:

d = (a * b) + c;
h = (f / 2) * g;

Assert inputs cc4m_logo_inline

IDSTAT-10
TitleEvery assert call shall have an error ID and a message as the 2nd and 3rd inputs.
PriorityMandatory
Severity level5
DescriptionEvery call to the built-in assert function shall have an error identifier and a message as second and third inputs.
RationaleIncluding an identifier allows for better testing and exception handling. Including a proper error message directly clarifies the problem.

Avoid:

assert(~isempty(list))

Instead use:

assert(~isempty(list), 'ClassName:MethodName:ListIsEmpty', 'The list shall not be empty.')

Global variables cc4m_logo_inline

IDSTAT-11
TitleDo not use global variables.
PriorityMandatory
Severity level4
DescriptionThe global keyword should not be used.
RationaleThe value of global variables can change from anywhere, which can make things unnecessarily complicated.

Constant conditional statements cc4m_logo_inline

IDSTAT-12
TitleDo not use conditions like if true and similar.
PriorityMandatory
Severity level3
DescriptionDo not use conditions that are always true or always false such as if true or elseif 0. MATLAB's Code Analyzer warns about some of these cases.
RationaleThese constructs may cause unreachable code or unintended behaviour.

Avoid:

if x > 0 || true
    disp(x)
end   

Instead use:

disp(x)

Group struct field definitions cc4m_logo_inline

IDSTAT-13
TitleAll fields of a struct shall be defined in a single, contiguous block of code.
PriorityStrongly recommended
Severity level6 when the code is meant for code generation, otherwise 9
DescriptionNo fields shall be added to a struct after using it.
RationaleLines of code or functions using the struct might assume that all fields are already there, resulting in an error if the field is not there.

Avoid:

s = struct("f", 2, "g", 3);

computeCost(s);
s.h = 'new field';

Instead use:

s = struct("f", 2, "g", 3, "h", 'new field');

computeCost(s);

Return keyword cc4m_logo_inline

IDSTAT-15
TitleMinimize the use of return.
PriorityRecommended
Severity level9
DescriptionMinimize the use of the return keyword.
RationaleUsing return decreases readability because the end of the function is not always reached. By avoiding the return keyword, the flow of the code remains clear.

Avoid:

if isempty(x)
    return
end

<rest of the code>

Instead use:

if isempty(x)
    % No further actions.
else
    <rest of the code>
end

Dependencies are known cc4m_logo_inline

IDSTAT-17
TitleMake sure all functions called are known by MATLAB.
PriorityMandatory
Severity level1
DescriptionMake 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.
RationaleAttempting to access packages, classes and functions not on the MATLAB path will result in an error.

Try for exception handling cc4m_logo_inline

IDSTAT-18
TitleOnly use the try construct for exception handling.
PriorityStrongly recommended
Severity level5
DescriptionOnly 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.
RationaleUsing 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.

Avoid:

try
    nElems = container.nElements;
catch
    nElems = 0;
end

Instead use:

if isfield(container, 'nElements')
    nElems = container.nElements;
else
    nElems = 0;
end

Floating-point comparisons cc4m_logo_inline

IDSTAT-19
TitleDo not compare floating-point values using == or ~=.
PriorityStrongly recommended
Severity level3
DescriptionDo not compare floating-point values using == or ~=. Use a tolerance instead.
RationaleRounding errors due to algorithm design or machine precision can cause unexpected inequalities.

Avoid:

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

Instead use:

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

Cell arrays cc4m_logo_inline

IDSTAT-20
TitleAvoid using cell arrays except for harnessing character arrays or objects of different classes.
PriorityRecommended
Severity level5 if the code is meant for code generation, otherwise 7
DescriptionDo not use cell arrays for anything other than character arrays of objects of different classes.
RationaleCell arrays may be disadvantageous for the performance of the code. Readability is decreased as well when cell arrays are used instead of regular, homogeneous arrays.

Avoid:

data    = {12, 3; 4, 5};
names   = {"Neo", "Trinity", "Smith"};

Instead use:

data    = [12, 3; 4, 5];
names   = ["Neo", "Trinity", "Smith"];

Zero before decimal point cc4m_logo_inline

IDSTAT-21
TitleAlways use a zero before the decimal point in numeric expressions.
PriorityRecommended
Severity level9
DescriptionAlways use a zero before the decimal point in numeric expressions.
RationaleIncreases the readability of the code.

Avoid:

THRESHOLD = .5;

Instead use:

THRESHOLD = 0.5;

Abstract class instantiation cc4m_logo_inline

IDSTAT-25
TitleDo not attempt to instantiate abstract classes.
PriorityMandatory
Severity level1
DescriptionDo not attempt to instantiate abstract classes because this will result in an error.
RationaleOnly concrete classes can be instantiated. If any of the methods or properties are abstract, the entire class is considered abstract.

Do not use the command syntax cc4m_logo_inline

IDSTAT-26
TitleDo not use the command syntax.
PriorityStrongly recommended
Severity level7
DescriptionDo not use command syntax statements in the code.
RationaleReadability and maintanability of the code decreases by the use of command syntax statements.

Avoid:

verifyNameLength namePersonA namePersonB

Instead use:

verifyNameLength("namePersonA", "namePersonB")

Higher level rules

The rules in this chapter transcend individual statements. These higher-level rules treat things like code complexity and function types.

Complexity cc4m_logo_inline

IDFCNS-1
TitleKeep functions short and simple.
PriorityStrongly recommended
Severity level4
DescriptionKeep 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.
RationaleShort functions are more likely to be readable, reusable and testable.



Function typeMaximum cyclomatic complexityMaximum number of lines of code
Main20100
Local (Sub)1550
Methods in a classdef1020
Nested510

Number of function arguments cc4m_logo_inline

IDFCNS-2
TitleLimit the number of inputs and outputs of a function.
PriorityRecommended
Severity level8
DescriptionLimit the number of inputs and outputs of a function to five. If necessary, combine multiple arguments into a struct.
RationaleThis helps prevent a long calling syntax, which in turn improves the readability and reusability of the code.

Avoid:

out = computeWeight(blockHeight, blockWidth, blockDepth, density, nBlocks, idx);

Instead use:

out = computeWeight(blockData, nBlocks, idx);

Constructors with single output cc4m_logo_inline

IDFCNS-3
TitleEvery constructor shall have exactly one output.
PriorityMandatory
Severity level5
DescriptionEvery constructor shall have exactly one output: an object of the class.
RationaleA second constructor output is unusual, so will be unexpected for readers of the code.

Avoid:

classdef Computer
    methods
        function [obj, out2] = Computer(in)
            obj.value = in;
            out2 = 2 * in;
        end
    end
end

Instead use:

classdef Computer
    methods
        function obj = Computer(in)
            obj.value = in;
        end
    end
end

Scripts cc4m_logo_inline

IDFCNS-4
TitleDo not use scripts. Use functions instead.
PriorityStrongly recommended
Severity level4
DescriptionUse functions even if there are no inputs or outputs.
RationaleThe 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.
ExceptionInitialization of a project, or specifically creating base workspace structures that are used in models, without the need for assignin.

Editor warnings cc4m_logo_inline

IDFCNS-5
TitlePrevent or suppress Code Analyzer messages.
PriorityStrongly recommended
Severity level5
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.
RationaleThe 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.

Avoid:

%#ok<*ABCDE> Suppress a Code Analyzer warning in the entire file.

Instead use:

%#ok<ABCDE> Suppress the Code Analyzer warning on this line alone.

Getters and setters cc4m_logo_inline

IDFCNS-6
TitleMinimize the use of Getters and Setters.
PriorityStrongly recommended
Severity level5
DescriptionDo not write methods using the get.<property> and set.<property> syntax. Write explicit methods for getting or setting property values if necessary.
RationaleProperty getters and setters can cause unexpected behaviour because code is run unexpectedly when the property's value is changed or requested.

Mex-files cc4m_logo_inline

IDFCNS-7
TitleWhen using a mex-function in your code, make sure versions of the file are available for all platforms.
PriorityMandatory
Severity level3
DescriptionWhen using a mex-function in your code, make sure versions of the file are available for Windows (32 and 64 bit), MacOS and Unix.
RationaleThis increases the chance your code will run successfully on other platforms as well.

Nesting depth cc4m_logo_inline

IDFCNS-8
TitleLimit nesting depth to a maximum of five.
PriorityStrongly recommended
Severity level5
DescriptionDo not nest blocks of code deeper than five levels. If necessary, refactor into multiple functions.
RationaleDeeply nested code is often less readable and it can be a sign of inefficient code.

Reuse of iterator variables cc4m_logo_inline

IDFCNS-13
TitleDo not reuse iterator variables within a function.
PriorityStrongly recommended
Severity level5
DescriptionDo not reuse iterator variables within the same function. Limit the scope of an iterator variable to its for loop.
RationalePrevents renaming all iterators when only the one for a specific loop must be renamed. Also improves readability.

Avoid:

for iNode = 1 : numel(nodes)
    ...
end

for iNode = 1 : 2 : 11
    ...
end

Instead use:

for iNode = 1 : numel(nodes)
    ...
end

for iValue = 1 : 2 : 11
    ...
end

Nested functions cc4m_logo_inline

IDFCNS-16
TitleUse nested functions sparingly/only when really beneficial.
PriorityStrongly recommended
Severity level5
DescriptionUse nested functions sparingly/only when really beneficial.
RationaleNested functions reduce the readability and robustness of the code and can not be tested independently.
ExceptionBecause variables can be shared, nested functions can be useful to prevent a massive interface with a lot of inputs and outputs.

Missing methods declarations and implementations cc4m_logo_inline

IDFCNS-18
TitleAll methods that are declared in a classdef file need to be implemented as well.
PriorityMandatory
Severity level2
DescriptionAll methods that are declared in a classdef file need to be implemented as well, and vice versa.
RationaleMissing method declarations or implementations is very likely a programming error.

Mismatch input and output declarations and implementations cc4m_logo_inline

IDFCNS-19
TitleThe input and output declarations and implementations for methods should match.
PriorityMandatory
Severity level2
DescriptionAll inputs and outputs that are declared in a classdef file, for a method, need to be implemented as well, and vice versa.
RationaleA mismatch between input and output declarations and implementations, is very likely a programming error.

Avoid:

methods(Static)
    out1 = getFolder(in2, in1)	
end

function [reportsFolder, isOk] = getFolder(in1, in2)
....
end

Instead use:

methods(Static)
    [reportsFolder, isOk] = getFolder(in1, in2)	
end

function [reportsFolder, isOk] = getFolder(in1, in2)
....
end

The first output of a constructor should be the object of the class

IDFCNS-20
TitleThe first output of a constructor should be the object of the class.
PriorityMandatory
Severity level1
DescriptionThe first output of a constructor should be the object of the class.
RationaleIf 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.

Avoid:

classdef ConstructorDesign

   properties
      computedValue
   end

	methods
		function x = ConstructorDesign()
			obj.computedValue = 100;
			x                 = 101
		end
		
	end
end

Instead use:

classdef ConstructorDesign

   properties
      computedValue
   end

	methods
		function obj = ConstructorDesign()
			obj.computedValue = 100;
			x                 = 101
		end
		
	end
end

Use of iterator variables outside the for loop cc4m_logo_inline

IDFCNS-21
TitleDo not use iterator variables outside the for loop.
PriorityMandatory
Severity level2
DescriptionDo not use iterator variables outside the for loop, since this might lead to unexpected behavior.
RationaleUsing 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.

Avoid:

for iNode = 1 : numel(nodes)
    if valueIn(iNode) > threshold
		break;
	end
end

valueOut = iNode + 10;

Instead use:


idx      = 0;

for iNode = 1 : numel(nodes)
    ...
	
	if valueIn(iNode) > threshold
		idx      = iNode;
		break
	end
end

valueOut = idx + 10;

More input arguments than expected cc4m_logo_inline

IDFCNS-22
TitleDo not call functions with more input arguments than expected.
PriorityMandatory
Severity level1
DescriptionFunctions should not be called with more inputs than they can handle according to their implementation.
RationaleIf a function is called with more input arguments than expected, it will result in a runtime error.

Avoid:

function processTemperatures(Tin1, Tin2, Tin3)
	x = calculateMaxTemperature(Tin1, Tin2, Tin3);
end

function out = calculateMaxTemperature(Tin1, Tin2)
	out = max(Tin1, Tin2);
end

Instead use:

function processTemperatures(Tin1, Tin2, Tin3)
	x = calculateMaxTemperature(Tin1, Tin2);
end

function out = calculateMaxTemperature(Tin1, Tin2)
	out = max(Tin1, Tin2);
end

Superclass property implementation cc4m_logo_inline

IDFCNS-23
TitleClasses shall not implement properties inherited from superclasses.
PriorityMandatory
Severity level1
DescriptionClasses 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.
RationaleAttempting to use such a class will result in a runtime error.
ExceptionThere 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.

Avoid:

classdef Measurement
    properties
        measurementDate
    end
end

classdef Pressure < Measurement
    properties
        measurementDate = today()
    end
end

Instead use:

classdef Measurement
    properties
        measurementDate
    end
end

classdef Pressure < Measurement
    methods
        function obj = Pressure()
            obj.measurementDate = today();
        end
    end
end

Avoid Java dependency cc4m_logo_inline

IDFCNS-24
TitleDo not use Java dependencies in your code.
PriorityStrongly recommended
Severity level3
DescriptionBe independent of Java and therefore do not use Java dependencies in your code, dependencies such as: javacomponent, javaMethod, javaObjectEDT etc.
RationaleJava packages and subpackages will not be available in MATLAB in a future release.

Method access permissions cc4m_logo_inline

IDFCNS-25
TitleMethod access permissions shall not differ from those of a superclass.
PriorityMandatory
Severity level1
DescriptionMethod access permissions of a class shall equal those of its superclass(es) (if any).
RationaleDefining inconsistent method access permissions results in a runtime error.

Avoid:

classdef Table
    methods (protected)
        computeMass(obj)
    end
end

classdef Desk < Table
    methods
        function computeMass(obj)
            ...
        end
    end
end

Instead use:

classdef Table
    methods (protected)
        computeMass(obj)
    end
end

classdef Desk < Table
    methods (protected)
        function computeMass(obj)
            ...
        end
    end
end

Write interpretable codecc4m_logo_inline

IDFCNS-27
TitleWrite code that can be interpreted by MATLAB.
PriorityMandatory
Severity level1
DescriptionWrite code that can be interpreted by MATLAB. Files should not contain a parse error or have invalid characters.
RationaleCode that can not be intrepreted by MATLAB can not run.

Security

This chapter contains rules to help avoiding potential security risks.

Eval-functions cc4m_logo_inline

IDSECURITY-1
TitleDo not use the built-in eval. Minimize the use of feval, evalin and evalc.
PriorityMandatory
Severity level3
DescriptionDo not use the built-in eval. Minimize the use of feval, evalin and evalc.
RationaleThese 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.

Shell escape cc4m_logo_inline

IDSECURITY-2
TitleDo not use the shell escape function.
PriorityMandatory
Severity level3
DescriptionDo not use the shell escape function. If necessary, use the system function instead.
RationaleWhen using the !program_to_execute syntax to execute external programs, no dynamic input or program names can be used.
ExceptionApplication development.

Avoid:

!mycommand

Instead use:

system('mycommand')

Security Server Certificate Usage cc4m_logo_inline

IDSECURITY-3
TitleWhen using the weboptions or matlab.net.http.HTTPOptions classes, do not set an empty certificate file name.
PriorityMandatory
Severity level4
DescriptionWhen using the weboptions or matlab.net.http.HTTPOptions classes, do not empty the CertificateFilename option.
RationaleFor security reasons, it is discouraged to empty the CertificateFilename property of a weboptions or matlab.net.http.HTTPOptions object because that disables certificate validation.

Avoid:

% During construction
opts = weboptions("CertificateFilename", "");
opts = matlab.net.http.HTTPOptions("CertificateFilename", "");

% Post-construction
opts.CertificateFilename = "";

Instead use:

%% Do not specify "CertificateFilename" at all:

% During construction
opts = weboptions();
opts = matlab.net.http.HTTPOptions();

%% Specify default certificates:

% During construction
opts = weboptions("CertificateFilename", "default");
opts = matlab.net.http.HTTPOptions("CertificateFilename", "default");

% Post-construction
opts.CertificateFilename = "default";

%% Specify a certificate file explicitly:

% During construction
opts = weboptions("CertificateFilename", "MyFile.crt");
opts = matlab.net.http.HTTPOptions("CertificateFilename", "MyFile.crt");

% Post-construction
opts.CertificateFilename = "MyFile.crt";

Security XML reading cc4m_logo_inline

IDSECURITY-4
TitleWhen reading an XML file, set the AllowDoctype option to false.
PriorityMandatory
Severity level3
DescriptionWhen using the xmlread or matlab.io.xml.dom.Parser functions, make sure to set AllowDoctype to false.
RationaleIn 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.

Avoid:

content = xmlread(myFile);
p = matlab.io.xml.dom.Parser();
p.Configuration.AllowDoctype = true;
p.parseFile(myFile);

Instead use:

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);

Constant variable names cc4m_logo_inline

IDSECURITY-5
TitleAvoid constant variable names as: username, loginname, password etc.
PriorityMandatory
Severity level3
DescriptionAvoid 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.
RationaleFor security reasons, it is discouraged to use hard-coded username and or password since this way they can be easily shared with others accidentally.

Avoid:

username = 'myName';
password = 'myPassword';

Instead use:

username = fileread('C:\Users\my.name\name.txt');
password = fileread('C:\Users\my.name\pwd.txt');

Security Username and Password cc4m_logo_inline

IDSECURITY-6
TitleDo not use hard-coded values for Username and Password.
PriorityMandatory
Severity level3
DescriptionDo 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.
RationaleFor security reasons, it is discouraged to use hard-coded username and password since this way they can be easily shared with others accidentally.

Avoid:

import matlab.net.http.Credentials

creds = Credentials('Username', 'John', 'Password', 'secret');
weboptions("Username", "John", "Password", "secret");

Instead use:

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.