Table of Contents

MonkeyProof MATLAB Coding Standard

Table of Contents

Introduction

Introduction

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.

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 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:

  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.

Realization

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.

Structure of this document

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.

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.
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 exceptions.
RationaleRationale 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.

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.

Naming conventions

The rules in this chapter describe how variables, functions etc. can be named in a consistent and insightful manner.

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

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

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

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.

Function names document their use

IDNAMING-16
TitleNames of functions should document their use.
PriorityRecommended
Severity level8
DescriptionThe names of functions should document their use.
RationaleBy choosing a clear and descriptive name, the code becomes more readable.

Function name construction

IDNAMING-17
TitleA function name should consist of a verb and a noun.
PriorityRecommended
Severity level8
DescriptionAll function names shall consist of a verb followed by a noun.
RationaleThis 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 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 length cc4m_logo_inline

IDNAMING-20
TitleVariable names shall be at most 63 characters long. Function names shall be at least 3 and at most 63 characters long.
PriorityRecommended
Severity level8
DescriptionVariable names shall be at most 63 characters long. Function names shall be at least 3 and at most 63 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. MATLAB can not handle names of more than 63 characters long.

Avoid:

maximumValueOfTheEntireSetOfDataPoints = max(data);

Instead use:

maxData = max(data);

Descriptive names

IDNAMING-21
TitleUse precise and descriptive names for functions, classes, packages and variables.
PriorityStrongly recommended
Severity level8
DescriptionUse precise and descriptive names for functions, classes, packages and variables.
RationaleThis increases the readability of the code.

Avoid:

function tk = convC2k(temp)

Instead use:

function temperatureK = convertCelsiusToKelvin(temperatureC)

The 'is' prefix

IDNAMING-22
TitleReserve the is prefix for logical values.
PriorityRecommended
Severity level8
DescriptionThe is prefix shall be used for functions returning logical values or properties and variables holding logical values.
RationaleThis increases the readability of the code as it is clear from the name of the function/property/variable what data type can be expected.

Abbreviations

IDNAMING-23
TitleDo not use abbreviations in variable names.
PriorityStrongly recommended
Severity level8
DescriptionVariable names shall not contain abbreviations.
RationaleMaintain readability by not abbreviating words in your variable names. Common acronyms are allowed.

Avoid:

arrTim

Instead use:

arrivalTime

Units in variable names

IDNAMING-24
TitleDo not use units in variable names.
PriorityStrongly recommended
Severity level8
DescriptionVariable names shall not contain units. Instead, add units as end-of-line comments in square brackets.
RationaleMaintain readability by using concise variable names.

Avoid:

accelerationInMillimetersPerSecondSquared = 1000;

Instead use:

acceleration = 1000; % [mm/s^2]

The 'n' prefix

IDNAMING-25
TitleThe prefix n should be used for variables that represent a number of things.
PriorityStrongly recommended
Severity level8
DescriptionThe 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.
RationaleVariables starting with this prefix can easily be identified.

Avoid:

numberOfFiles
nrCars
lineCount

Instead use:

nFiles
nCars
nLines

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 statements cc4m_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 cc4m_logo_inline

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.'];

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 exact same attributes is unnecessary and decreases the readability of classdef files. Group properties and method declarations using comments.

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 come before all methods blocks.
RationaleFor readability, it is advisable to have all properties blocks before the methods blocks in classdef files.

Help text

IDLAYOUT-15
TitleWrite header comments providing user documentation.
PriorityRecommended
Severity level7
DescriptionWrite 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.
RationaleThis increases readability, and makes the code more likely to be found and less likely to be reinvented.

Avoid:

function [avg, maxSize] = measureSize(obj, dim)
avg = mean(obj.Size, dim);
maxSize = max(obj.Size, dim);
end

Instead use:

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

Whitespace around blocks of code

IDLAYOUT-16
TitleSeparate blocks of code by one or more blank lines.
PriorityRecommended
Severity level9
DescriptionSeparate coherent blocks of code by one or more blank lines.
RationaleIncreases the readability of the code.

Avoid:

deltaX          = mean(xIn);
xOut            = xIn - deltaX;
scalingFactor   = newZ / currentZ;
xOut            = xOut .* scalingFactor;
xOut            = xOut + deltaX;

Instead use:

% Shift to origin.
deltaX  = mean(xIn);
xOut    = xIn - deltaX;

% Calculate scaling.
scalingFactor   = newZ / currentZ;
xOut            = xOut .* scalingFactor;

% Shift back.
xOut = xOut + deltaX;

Correct spelling

IDLAYOUT-17
TitleUse correct spelling and punctuation in comments and write in complete sentences.
PriorityRecommended
Severity level7
DescriptionUse correct spelling and punctuation in comments and write in complete sentences, starting with a capital letter and ending in a period.
RationaleThis increases the readability of code. Error-strewn and poorly constructed comments reflect on the code they accompany.

Avoid:

% get sclaing factor
scaling_factor = new_z / current_z;
x_out = x_out * scaling_factor; % now recslaed

Instead use:

% Get the scaling factor.
scalingFactor = newZ / currentZ;
xOut = xOut * scalingFactor; % Now rescaled.

Align struct definition

IDLAYOUT-18
TitleKeep name-value pairs aligned in a struct declaration.
PriorityRecommended
Severity level9
DescriptionWhen defining a struct, align the names and values of the struct fields.
RationaleThis improves readability of the code by making it clearer what fields are defined and by what values.

Avoid:

s = struct("name", "Albert", "age", 2021 - 1979, "isValid", ismember("Albert", allNames));

Instead use:

s = struct(...
    "name",     "Albert", ...
    "age",      2021 - 1979, ...
    "isValid",  ismember("Albert", allNames))

Constants with end of line comments

IDLAYOUT-19
TitleDocument constants with end of line comments.
PriorityRecommended
Severity level7
DescriptionDocument constants with end of line comments.
RationaleAlthough variable names should generally speak for themselves, comments can be useful to provide additional information such as units.

Avoid:

THRESHOLD = 10;

Instead use:

THRESHOLD = 10; % [dB] Max noise level

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:

persistent x, y

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

Instead use:

persistent x
persistent y 

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

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;

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;

Workspace variable ans cc4m_logo_inline

IDSTAT-22
TitleDo not use the workspace variable ans.
PriorityMandatory
Severity level3
DescriptionDo not use the workspace variable ans since this might lead to undesired behavior.
RationaleUse of the workspace variable ans reduces the robustness and security of the code.

Avoid:

function out = get_value(in)
3 + 3;

out = ans + in;

Instead use:

function out = get_value(in)
var1 = 3 + 3;

out = var1 + in;

Debugging functions cc4m_logo_inline

IDSTAT-23
TitleDo not use debugging functions that interact with the MATLAB debugger.
PriorityMandatory
Severity level3
DescriptionDo not use debugging functions such as dbstep, dbcont, dbquit, keyboard or other functions that interact with the MATLAB debugger.
RationaleThese functions that interact with the MATLAB debugger reduce the robustness of the code.

Elseif else cc4m_logo_inline

IDSTAT-24
TitleEvery if that has an elseif section shall have an else section.
PriorityStrongly recommended
Severity level4
DescriptionEvery if with an elseif section shall have an else section, even if it does not contain executable code.
RationaleBy 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.

Avoid:

if x > 0
    y = 10;
elseif x == 0
    y = 0;
end

Instead use:

if x > 0
    y = 10;
elseif x == 0
    y = 0;
else
    y = -1;
end

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

Accessing other workspaces cc4m_logo_inline

IDSTAT-27
TitleAvoid using functions that access or depend on workspaces outside the scope of the current function.
PriorityMandatory
Severity level3
DescriptionDo not use functions accessing workspaces outside the scope of the current function such as assignin, evalin, clc.
RationaleThese functions reduce the portability, robustness and readability of the code.
ExceptionApplication development and Simulink tools.

Logical indexing

IDSTAT-28
TitleUse logical indexing instead of linear or subscript indexing where possible.
PriorityStrongly recommended
Severity level6
DescriptionTo speed up your code, use logical indexing instead of linear or subscript indexing where possible.
RationaleLogical indexing is faster and more readable.

Avoid:

index = intersect(find(v > MIN), find(v < MAX));

Instead use:

index = (v > MIN) & (v < MAX);

Loop vectorization

IDSTAT-29
TitleVectorize loops where feasible.
PriorityStrongly recommended
Severity level6
DescriptionInstead of looping over the elements of arrays, apply operations to them in their entirety. Use scalar and implicit expansion, if applicable.
RationaleVectorized loops are faster, more robust, more readable, and more maintainable.

Avoid:

dataResult = false(size(dataset));

for iElem = 1 : numel(dataset)
    if dataset(iElem) < limit(iElem)
        dataResult(iElem) = true;
    else
        dataResult(iElem) = false;
    end
end

Instead use:

dataResult = dataset < limit;

Use switch blocks

IDSTAT-30
TitleUse a switch block instead of many if-elseif-else statements.
PriorityRecommended
Severity level5
DescriptionUse a switch block instead of many if-elseif-else statements when possible.
RationaleThe notation of a switch block is more concise and therefore, more readable and easier to maintain.

Avoid:

if name == "Bill"
    ...
elseif ismember(name, ["Judith", "Bob"])
    ...
elseif name == "Steve"
    ...
else
    ...
end

Instead use:

switch name
    case "Bill"
        ...
    case {"Judith", "Bob"}
        ...
    case "Steve"
        ...
    otherwise
        ...
end

Variable in one unit

IDSTAT-31
TitleUse a variable in one unit as much as possible.
PriorityRecommended
Severity level8
DescriptionUse a variable in one unit as much as possible. Use a named constant for converting to another unit if conversion is truly necessary.
RationaleMaintain readability by using the same unit of measure throughout a function.

Avoid:

halfLifeTime = 580; % [s]
halfLifeTime = halfLifeTime / 3600; % [h]

Instead use:

SECONDS_TO_HOURS    = 1 / 3600;
halfLifeTime        = 580; % [s]
halfLifeTime        = halfLifeTime * SECONDS_TO_HOURS; % [h]

Undocumented functions

IDSTAT-32
TitleDo not use undocumented MATLAB-installed functions.
PriorityMandatory
Severity level2
DescriptionDo not use undocumented MATLAB-installed functions since these functions might be changed or removed in a future MATLAB release.
RationaleUsing undocumented MATLAB-installed functions is very likely a programming error in the future.

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.
ExceptionThe 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.

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.

Repeated code

IDFCNS-9
TitleDo not use the same block of code more than once in a function/in multiple functions.
PriorityStrongly recommended
Severity level4
DescriptionIf a function contains a block of code that is repeated more than one time, refactor it into a single function.
RationaleRefactoring of repeated blocks of code into single functions increases the maintainability, readability and reusability of the code.

Ownership structure

IDFCNS-10
TitleOwnership of a structure resides with the creator of that structure.
PriorityStrongly recommended
Severity level4
DescriptionOwnership 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.
RationaleAdding 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.

Avoid:

function [out] = calculateSpeed(car)

out = car;

% do not remove fields from existing struct
car = rmfield(car, 'speed');

Instead use:

function [out] = calculateSpeed(car)

out = car;

% clear the field
car.speed = [];

Single responsibility

IDFCNS-11
TitleFunctions should do precisely one thing well, and encapsulate a single idea.
PriorityStrongly recommended
Severity level4
DescriptionSingle responsibility principle : all sub-functions and most functions should do one thing very well, and encapsulate a single idea.
RationaleThe 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.

Commented out code

IDFCNS-12
TitleRemove commented out code.
PriorityStrongly recommended
Severity level7
DescriptionRemove commented-out lines of code.
RationaleRemoving commented-out code increases readability and it prevents someone from unintentionally enabling it again.

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

Rewriting existing functions

IDFCNS-14
TitleWhen rewriting existing functions, do not make a new copy of them with slightly modified code.
PriorityRecommended
Severity level4
DescriptionDo not copy-paste an existing function as a local function of your code. Instead, use a wrapper around existing functionality.
RationaleMultiple forks, duplications and reinventions of the wheel make a code base less modular and less maintainable.

Columns with implicit meaning

IDFCNS-15
TitleAvoid the use of matrices in which rows or columns have implicit meaning.
PriorityStrongly recommended
Severity level5
DescriptionAvoid the use of matrices in which rows or columns have implicit meaning. Use individual vectors, structs or tables instead.
RationaleUsing matrices with implicit row or column meanings reduces the readability and robustness of the code.

Avoid:

% data is a matrix.
density = data(:, 1) ./ (data(:, 2) .* data(:, 3) * data(:, 4));

Instead use:

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

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.

Input parameter dependency

IDFCNS-17
TitleFunction input arguments must be independent.
PriorityStrongly recommended
Severity level5
DescriptionFunction input arguments must be independent, and the function must not assume a dependency between them.
RationaleAssuming 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.

Avoid:

function [meanV, meanA] = getMeanVandA(velocities, distances, timePts)
meanV = sum(distances) ./ sum(timePts);
meanA = velocities(end) ./ sum(timePts);
end

function vectorOut = processVector(vectorIn, vectorLength)
for iIdx = 1 : vectorLength
    vectorOut(ii) = processScalar(vectorIn(ii));
end
end

Instead use:

function [meanV, meanA] = getMeanVandA(distances, timePts)
meanV      = sum(distances) ./ sum(timePts);
velocities = distances ./ timePts;
meanA      = velocities(end) ./ sum(timePts);
end

function vectorOut = processVector(vectorIn)
for iIdx = 1 : length(vectorIn)
    vectorOut(ii) = processScalar(vectorIn(ii));
end
end

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

Security

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.

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:

% Ask the user to provide a username and password, for example using a dialog:
[username, password] = showLoginDialog();

Note: This is just one example of how to obtain credentials without hardcoding them. Ask your IT department for the available options.

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.

Release notes

Release 1.3.0 (May 2023)

Added

  • Created a specific chapter for security related rules.
  • A rule server certificate usage.
  • A rule on not setting the option AllowDoctype to false when reading an XML file.
  • A rule on not using constant variable names as username, loginname, password etc.
  • A rule on not using hard-coded username and or password.

Changed

  • Moved the rule about not using eval-functions from the chapter Statements to Security, so STAT-14 became SECURITY-1.
  • Moved the rule about not using the shell escape function from the chapter Statements to Security, so STAT-16 became SECURITY-2.

Release 1.2.0 (October 2022)

Added

  • A rule on consistent naming for class objects.
  • A rule on not instantiating abstract classes.
  • A rule on not using the command syntax.
  • A rule on not using iterator variables outside the for loop.
  • A rule on having the object of the class as the first output of a constructor.
  • A rule on a consistent class object name.
  • A rule on not calling functions with more input arguments than are expected.
  • A rule on classes not implementing properties inherited from superclasses.
  • A rule on not having Java dependencies in your code.
  • A rule on having the same method access permissions as those from of a superclass.

Release 1.1.0 (August 2022)

Added

  • A rule on not using tab characters.
  • A rule on having all properties blocks before all methods blocks in classdef files.
  • A rule on including an else section to ifs that have an elseif section.
  • A rule on not using undocumented MATLAB-installed functions.
  • A rule on not missing method declarations and implementations.
  • A rule on mismatches between input and output declarations and implementations for methods.

Changed

  • The descriptions of the severity levels to match those currently used by TIOBE's TICS.
  • The severity levels and priorities of several rules.

Release 1.0.0 (January 2022)

Initial release