MISS_HIT includes a linter tool
(mh_lint). It is a classic
bug-finding tool that focusses on code quality that is
automatic, but not sound or complete.
Static analysis for MATLAB / Octave
Work In Progress
Checks
Classification
MISS_HIT Lint issues "check" messages for any potential
problem it detects. These are further classified into three
categories:
- low - These are problems that MISS_HIT is somewhat unsure about if it is a problem or not, or problems that - if they manifest - are unlikely to be silently undetected bugs. Something that makes your entire program crash or obviously doesn't work is not as bad as something that quitely mis-behaves.
- high - These are problems that MISS_HIT is very sure will cause major problems. Fix these!
- medium - Anything else.
Checks
Incomplete block comments
Block comments are special comments that span multiple
lines. The documentation states that they must appear on their
own line without any other text surrounding them, otherwise
the behaviour is left undefined.
MH Lint emits a check on all comments that may be block
comments, for example:
disp 1; %{ disp 2; %{ disp 3; %} disp 4; %} disp 5;The second block comment is not actually a block comment (creating the first warning). The third comment closes the first comment; but the last one does not close the second, since it's not a block comment (creating the second warning). The output of this code is 1, 4, 5 which is maybe not what you would expect.
Chaining relational operators
It is possible to chain operators, e.g. 1 + 2 + 3 which
performs as expected. However it is also possible to chain
relational operators, which does not work as expected:
lower = 5; upper = 20; if lower < var < upper disp('var is in bounds'); else disp('error: var is not in bounds'); end
This condition always evaluates to true. Lets say var is
100. Chained operators are evaluated left-to-right, lower <
var will evaluate to 1, which in turn means 1 < upper is
always true.
MH Lint emits a check on all chained relations.
Shadowing of built-in functions ("builtin_shadow")
This rule attempts to find cases where we assign to, or
shadow, a MATLAB® builtin function (e.g. re-defining false
to be 1). For assignments, this rule works on a hand-curated
list of "high impact" built-in functions, where it is likely
this re-definition will result in confusion. So we complain
e.g. about "true", but we do not complain about "bar". For
script files, function files, and class files we check a much
broader set of built-ins.
Filename matching entity within
A class or top-level function must match the name of the file
it is declared in: other functions can only reliably access it
if this is the case. If it does not match, you must use the
name of the file instead of the function or class name, which
is just not right.
Name-value pairs in function calls
This is a new (since MATLAB® 2021a) and extremely confusing use
of = in function calls. It means something completely
different to what it means in any other language, it also
clashes with Octave, and finally it is next to impossible to
parse correctly.
Consider for example:
foo(a=b);
- In MATLAB® < 2021a, this is just a syntax error.
-
In MATLAB® >= 2021a, this is actually two arguments, and
is equivalent to
foo('a', b)
Note that this is totally different to what you'd expect if you come from e.g. Python or Ada. - In Octave, this is a side-effect assignment to a, so is
equivalent to
a = b; foo(b);
It gets worse, when you consider how to parse or semantically
analyze the code fragment
foo(a=b)Is it allowed or not? This may depend on the calling context, for example if foo is a lambda function it would be fine, but if it is an array, it is not.
Contents.m only contains comments
A file called Contents.m must only contain comments,
as it
has special
significance for the MATLAB® help system.
Correct format for TestTags
The required syntax for TestTags
is documented,
but subtle. We've seen some cases where incorrect TestTags
cause the entire test to be silently ignored; so to guard
against this MH Lint enforces the correct syntax.