mlint - Check M-files for possible problems

GUI Alternatives

From the Current Directory browser, click the Actions button , and then select Reports > M-Lint Code Check Report. See also Checking M-File Code for Problems Using the M-Lint Code Analyzer in the Editor.

Syntax

mlint('filename')
mlint('filename','-config=settings.txt')
mlint('filename','-config=factory')
inform=mlint('filename','-struct')
msg=mlint('filename','-string')
[inform,filepaths]=mlint('filename')
inform=mlint('filename','-id')
inform=mlint('filename','-fullpath')
inform=mlint('filename','-notok'
mlint('filename','-cyc')
mlint('filename','-eml')
%#eml
%#ok

Description

mlint('filename') displays M-Lint information about filename, where the information reports potential problems and opportunities for code improvement, referred to as suspicious constructs. The line number in the message is a hyperlink that opens the file in the Editor, scrolled to that line. If filename is a cell array, information is displayed for each file. For mlint(F1,F2,F3,...), where each input is a character array, MATLAB software displays information about each input file name. You cannot combine cell arrays and character arrays of file names. Note that the exact text of the mlint messages is subject to some change between versions.

mlint('filename','-config=settings.txt') overrides the default M-lint active settings file with the M-Lint settings that enable or suppress messages as indicated in the specified settings.txt file.

For information about creating a settings.txt file, see Setting Preferences for M-Lint. If you specify an invalid file, mlint returns a message indicating that it cannot open or read the file you specified. In that case, mlint uses the factory default settings.

mlint('filename','-config=factory') ignores all settings files and uses the factory default M-lint preference settings.

inform=mlint('filename','-struct') returns the M-Lint information in a structure array whose length is the number of suspicious constructs found. The structure has the fields that follow.

Field

Description

message

Message describing the suspicious construct that M-Lint caught.

line

Vector of M-file line numbers to which the message refers.

column

Two-column array of M-file columns (column extents) to which the message applies. The first column of the array specifies the column in the Editor where the M-Lint message begins. The second column of the array specifies the column in the Editor where the M-Lint message ends. There is one row in the two-column array for each occurrence of an M-Lint message.

If you specify multiple file names as input, or if you specify a cell array as input, inform contains a cell array of structures.

msg=mlint('filename','-string') returns the M-Lint information as a string to the variable msg. If you specify multiple file names as input, or if you specify a cell array as input, msg contains a string where each file's information is separated by 10 equal sign characters (=), a space, the file name, a space, and 10 equal sign characters.

If you omit the -struct or -string argument and you specify an output argument, the default behavior is -struct. If you omit the argument and there are no output arguments, the default behavior is to display the information to the command line.

[inform,filepaths]=mlint('filename') additionally returns filepaths, the absolute paths to the file names, in the same order as you specified them.

inform=mlint('filename','-id') requests the message ID from M-Lint, where ID is a string of the form ABC.... When returned to a structure, the output also has the id field, which is the ID associated with the message.

inform=mlint('filename','-fullpath') assumes that the input file names are absolute paths, so that M-Lint does not try to locate them.

inform=mlint('filename','-notok') runs mlint for all lines in filename, even those lines that end with the mlint suppression syntax, %#ok.

mlint('filename','-cyc') displays the McCabe complexity (also referred to as cyclomatic complexity) of each function in the file. Higher McCabe complexity values indicate higher complexity, and there is some evidence to suggest that programs with higher complexity values are more likely to contain errors. Frequently, you can lower the complexity of a function by dividing it into smaller, simpler functions. In general, smaller complexity values indicate programs that are easier to understand and modify. Some people advocate splitting up programs that have a complexity rating over 10.

mlint('filename','-eml') enables Embedded MATLAB™ messages for display in the Command Window.

If you include %#eml anywhere within an M-file, except within a comment, it causes mlint to behave as though you specified —eml for that file. For more information, see Adding the Compilation Directive %#eml. MATLAB comments can follow the %#eml directive.

If you include %#ok at the end of a line in an M-file, mlint ignores that line. mlint ignores specified messages id1 through idn on a given line when %#ok< id1,id2,...idn> appears at the end of that line. mlint ignores specified messages 1 through n throughout the file when %#ok<*id1,*id2,...*idn> appears at the end of a line. To determine the id for a given message, use the following command, where filename is the name of the file that elicits the message:

mlint filename -id 

For information on adding the %#ok directive using the Editor context menu, see Suppressing M-Lint Indicators and Messages.

Examples

The following examples use lengthofline.m, which is a sample M-file with code that can be improved. You can find it in matlabroot/help/techdoc/matlab_env/examples. If you want to run the examples, save a copy of lengthofline.m to a location on your MATLAB path.

Running mlint on a File with No Options

To run mlint on the example file, lengthofline.m, run

mlint('lengthofline')

MATLAB displays M-Lint messages for lengthofline.m in the Command Window:

L 22 (C 1-9): The value assigned here to variable 'nothandle' might never be used.
L 23 (C 12-15): NUMEL(x) is usually faster than PROD(SIZE(x)).
L 24 (C 5-11): 'notline' might be growing inside a loop. Consider preallocating for speed.
L 24 (C 44-49): Use STRCMPI(str1,str2) instead of using LOWER in a call to STRCMP.
L 28 (C 12-15): NUMEL(x) is usually faster than PROD(SIZE(x)).
L 34 (C 13-16): 'data' might be growing inside a loop. Consider preallocating for speed.
L 34 (C 24-31): Use dynamic fieldnames with structures instead of GETFIELD.
                Type 'doc struct' for more information.
L 38 (C 29): Use || instead of | as the OR operator in (scalar) conditional statements.
L 39 (C 47): Use || instead of | as the OR operator in (scalar) conditional statements.
L 40 (C 47): Use || instead of | as the OR operator in (scalar) conditional statements.
L 42 (C 13-16): 'data' might be growing inside a loop. Consider preallocating for speed.
L 43 (C 13-15): 'dim' might be growing inside a loop. Consider preallocating for speed.
L 45 (C 13-15): 'dim' might be growing inside a loop.Consider preallocating for speed.
L 48 (C 52): There may be a parenthesis imbalance around here.
L 48 (C 53): There may be a parenthesis imbalance around here.
L 48 (C 54): There may be a parenthesis imbalance around here.
L 48 (C 55): There may be a parenthesis imbalance around here.
L 49 (C 17): Terminate statement with semicolon to suppress output (in functions).
L 49 (C 23): Use of brackets [] is unnecessary. Use parentheses to group, if needed.

For details about these messages and how to improve the code, see Making Changes Based on M-Lint Messages in the MATLAB Desktop Tools and Development Environment documentation.

Running mlint with Options to Show IDs and Return Results to a Structure

To store the results to a structure and include message IDs, run

inform=mlint('lengthofline', '-id')

MATLAB returns

inform = 

19x1 struct array with fields:
    message
    line
    column
    id

To see values for the first message, run

inform(1)

MATLAB displays

ans = 

    message: 'The value assigned here to variable 'nothandle' might never be used.'
       line: 22
     column: [1 9]
         id: 'NASGU'

Here, the message is for the value that appears on line 22 that extends from column 1–9 in the M-file.NASGU is the ID for the message 'The value assigned here to variable 'nothandle' might never be used.'.

Suppressing Specific Messages with mlint

When you add %#ok to a line, it suppresses all mlint messages for that line. However, suppose there are multiple messages in a line and you want to suppress some, but not all of them. Or, suppose you want to suppress a specific message, but not all messages that might arise in the future due to changes you make to that line. Use the %#ok syntax in conjunction with message IDs.

This example uses the following code, displayAnonymousFunction.m:

function displayAnonymousFunction
% mini tutorial on anonymous function handles.

disp('  ');
disp('  Here is an example of an anonymous function that');
disp('  retrieves the last modified date of a given file:');
disp('  ');
fileDate = @(f)getfield(dir(f),'date')

disp('  ');
disp('  You can call it by passing a filename into the ');
disp('  function_handle variable.  We will use the currently');
disp('  running M-file for example purposes:');
disp('  ');
thisFile = which(mfilename('fullpath'))

disp('  ');
disp('  Now call the anonymous function handle as you would');
disp('  call any function or function_handle: fileDate(thisFile)');
disp('  ');
fileDate(thisFile)

Run mlint with the -id option on displayAnonymousFunction.m:

mlint('displayAnonymousFunction','-id')

Results displayed to the Command Window show two messages for line 8:

L 8 (C 10): NOPRT: Terminate statement with semicolon to suppress output (in functions).
L 8 (C 16-23): GFLD: Use dynamic fieldnames with structures instead of GETFIELD. 
               Type 'doc struct' for more information.

To suppress the first message on the line (about using a semicolon), use its message ID, NOPRT, with the %#ok syntax as shown here:

fileDate = @(f)getfield(dir(f),'date') %#ok<NOPRT>

When you run mlint for displayAnonymousFunction.m, only one message now displays for line 8.

To suppress multiple specific messages for a line, separate message IDs with commas in the %#ok syntax:

fileDate = @(f)getfield(dir(f),'date') %#ok<NOPRT,GFLD>

Now when you run mlint for displayAnonymousFunction.m, no messages display for line 8.

Suppressing Specific Messages Throughout a File with mlint

To suppress a specific message throughout a file, use the %#ok syntax in conjunction with a message ID preceded by an asterisk (*).

Run mlint with the -id option on the original displayAnonymousFunction.m code presented in the previous example:

mlint('displayAnonymousFunction','-id')

Results displayed to the Command Window show two messages for line 8:

L 8 (C 10): NOPRT: Terminate statement with semicolon to suppress output (in functions).
L 8 (C 16-23): GFLD: Use dynamic fieldnames with structures instead of GETFIELD. 
                     Type 'doc struct' for more information.

To suppress the semicolon message throughout the file, use its message ID, NOPRT, with an asterisk in the %#ok syntax as shown here:

fileDate = @(f)getfield(dir(f),'date') %#ok<*NOPRT>

When you run mlint for displayAnonymousFunction.m, the semicolon message is suppressed throughout the file and only one message displays for line 8.

To suppress multiple specific messages throughout a file, separate message IDs with commas in the %#ok syntax, and precede each message ID with an asterisk:

fileDate = @(f)getfield(dir(f),'date') %#ok<*NOPRT,*GFLD>

Now when you run mlint for displayAnonymousFunction.m, both the NOPRT andGFLD messages are suppressed throughout the file.

Error Message: An M-Lint message Was Once Suppressed Here, But the Message No Longer Appears

This examples shows how to interpret the message, "An M-Lint message was once suppressed here, but the message no longer appears."

Suppose you direct mlint to ignore line 15, in the M-file, displayAnonymousFunction.m (the code for which is presented in the third example in this section) by adding %#ok to the end of line 15:

thisFile = which(mfilename('fullpath') %#ok

When you run mlint for displayAnonymousFunction.m, typically no message is shown for line 15, because it contains the %#ok message suppression syntax. However, there are some exceptions, as follows:

If any one of these cases is true for line 15, then the following message now appears at line 15:

"An M-Lint message was once suppressed here, but the message no longer appears."

To remove this message, use the context menu and select Remove the Message Suppression. The %#ok directive is removed and now no M-Lint messages appear for line 15 of displayAnonymousFunction.m.

Displaying McCabe Complexity with mlint

To display the McCabe complexity of an M-File, run mlint with the -cyc option, as shown in the following example (assuming you have saved lengthofline.m to a local directory).

mlint lengthofline.m -cyc

Results displayed in the Command Window show the McCabe complexity of the file, followed by the M-File messages, as shown here:

L 1 (C 23-34): The McCabe complexity of 'lengthofline' is 12.
L 22 (C 1-9): The value assigned here to variable 'nothandle' might never be used.
L 23 (C 12-15): NUMEL(x) is usually faster than PROD(SIZE(x)).
L 24 (C 5-11): 'notline' might be growing inside a loop. Consider preallocating for speed.
L 24 (C 44-49): Use STRCMPI(str1,str2) instead of using UPPER/LOWER in a call to STRCMP.
L 28 (C 12-15): NUMEL(x) is usually faster than PROD(SIZE(x)).
L 34 (C 13-16): 'data' might be growing inside a loop. Consider preallocating for speed.
L 34 (C 24-31): Use dynamic fieldnames with structures instead of GETFIELD. Type 'doc struct' for more information.
L 38 (C 29): Use || instead of | as the OR operator in (scalar) conditional statements.
L 39 (C 47): Use || instead of | as the OR operator in (scalar) conditional statements.
L 40 (C 47): Use || instead of | as the OR operator in (scalar) conditional statements.
L 42 (C 13-16): 'data' might be growing inside a loop. Consider preallocating for speed.
L 43 (C 13-15): 'dim' might be growing inside a loop. Consider preallocating for speed.
L 45 (C 13-15): 'dim' might be growing inside a loop. Consider preallocating for speed.
L 48 (C 52): There may be a parenthesis imbalance around here.
L 48 (C 53): There may be a parenthesis imbalance around here.
L 48 (C 54): There may be a parenthesis imbalance around here.
L 48 (C 55): There may be a parenthesis imbalance around here.
L 49 (C 17): Terminate statement with semicolon to suppress output (in functions).
L 49 (C 23): Use of brackets [] is unnecessary.  Use parentheses to group, if needed.

See Also

mlintrpt, profile

  


Recommended Products

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.

 © 1984-2009- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS