Generate mlint warning when variable is not unused

mlint gives a warning when a variable is unsed. E.g. in the following code, mlint gives a warning in line (1)
a = 2; % (1) - here mlint gives a warning (which I know why, and which I do not care about)
a = 3; % (2)
Is it possible to generate a warning when a variable name is not used. More exactly, I would like to have the following behaviour:
a = 2; % (3) - I want no warning here, because the variable name is used again in line (4) and/or line (5)
a = 3; % (4)
func( a ); % (5)
a = 2; % (6) - I want a warning here, because the variable name is not used again later on in all paths
if( some_condition );
a = 3;
end

5 Comments

"because the variable from line (3) is used"
How exactly is the variable from line (3) used ?
My bad, my example is misleading. I edited it.
a = 1;
b = 2;
c = 3;
myfun1(a)
myfun2(b)
myfun3(c)
function myfun1(x)
end
function myfun2(y)
y;
end
function myfun3(z)
if rand() > 0.5
z;
end
end
To clarify, you would want mlint to produce warnings for a=1 and c=3 but not for b=2 ? Because the call to myfun1(a) does not use the variable at all, and the call to myfun3(c ) only uses the variable sometimes?
a = 1;
fid = fopen('test.txt', 'w');
if fid > 0
fprintf(fid, '%d\n', a);
fclose(fid);
end
and in this case you would want a = 1 to be flagged because the fopen might fail so the fprintf() might not be called?
Yes. But I am already satisfied when it works not across function call boundaries, i.e. no difference in behaviour for the variables a and b here. (Since mlint quite surely does not analyse the called functions for its warning, I doubt this would be possible at all).
So, if I inline all the functions from your example, the behaviour should be:
a = 1; % warning, because it is not used anymore
b = 2; % no warning, because it is used later
c = 3; % warning, because it is only conditionally used later
b = b
if rand() > 0.5;
c;
end;

Sign in to comment.

 Accepted Answer

Is it possible to generate a warning when a variable is not used. More exactly, I would like to have the following behaviour:
a = 2; % (3) - I want no warning here, because the variable is used again in line (4) and/or line (5)
a = 3; % (4)
func( a ); % (5)
It is possible to suppress the Code Analyzer warning on the line labeled 3 as Jatin suggested. But I'd like you to clarify what you mean by "used" in your comment.
The variable name a is assigned to on the lines labeled 3 and 4 and referenced on the line labeled 5. But the value that you set on the line labeled 3 is not used. That's the whole point of the message.
Suppose that instead of assigning the value 2 to a on that line you assigned the result of a computation that took 5 minutes to a on that line. You then turn around and throw that value that MATLAB spent 5 minutes working on in the trash and stick the value 3 in its place. That's potentially a waste of 5 minutes, and that's why Code Analyzer warns you on the line labeled 4. Code Analyzer is basically asking you "Did you really mean to throw away that work I did? Or did you perhaps mistype the variable name on one of the lines?"
In this case, 2 doesn't take any time to compute. But it's the principle: the fact that you assigned data to a variable name then immediately discarded it suggests that you may not be doing what you intended.

7 Comments

I know why there is a warning. And if you read carefully my question, it is not about "Why there is warning", or "How to get rid of the warning", but about "How to produce a warning for a totally different use case."
And as you correctly wrote: "the variable name is used, not the value". I do indeed care only about the name. I clarified my example further.
So let's take a sample small function.
function y = myfun(x)
a = 2; % (6) - I want a warning here, because the variable name is not used again later on in all paths
if( x > 3 )
a = 3;
end
y = 1;
When I write this in MATLAB Editor, both the first and second references to a are flagged as potentially unused. This is correct. The first reference to a is indeed unused, as whether or not x is greater than 3 there's no usage of the variable a later in the code. The second reference is also unused, as there's still no usage of the variable a later in the code.
With a slight modification to the function:
function a = myfun2(x)
a = 2; % (6) - I want a warning here, because the variable name is not used again later on in all paths
if( x > 3 )
a = 3;
end
y = 1;
Now neither reference to a is flagged as potentially unused. This too is correct IMO. The variable named a is used later on in the code, as the output argument from myfun2. Now is it possible that the function will not return a with the value of 2 when called, depending on the value of the input? Yes. Can Code Analyzer's static analysis of the code tell that? No. That is a run-time decision.
So if there were a Code Analyzer message on that first use of a, it would almost have to be a very soft warning. "The variable used on this line may or may not be used depending on the specific value of the input argument." or something like that. There likely would need to be enough caveats for realistic cases and enough false positives that I'm not sure the message would be useful.
But let me take a step back. We've been talking about analyzing the code as though it would be run in MATLAB. Are you hoping to use this type of Code Analyzer message to identify potential problems for a code generation workflow? MATLAB Coder is stricter about certain language constructs / patterns, so it might make sense to have a "MATLAB for Code Generation" Code Analyzer message that flags this pattern if that's your use case. If it isn't, can you say more about what action you would consider taking if that Code Analyzer message appears for a particular line of code?
Thanks for the long answer, from which I deduced that my original goal is not even of "academic value" to me: I already knew before asking that question, that I actually should solve the problem I have differently. But I thought, maybe will I learn some tricks about Matlab if I do it that way.
Now my answer to you:
My usecase which I had in mind is the following:
I have a function which needs to compute a value xx and return it. How to compute xx depends on a lot of conditions. If I have a programming error, and xx does not get computed, the function shall still not throw an exception, because my whole application should be very failure tolerant. So I write it like this:
function [ xx ] = func()
xx = 1; % fallback value, if something goes wrong so that no exception is thrown
if( condition1 )
xx = 2;
% very complicated if things continue
xx = 3;
% very complicated if things continue
elseif( condition2 )
xx = 4;
if( condition4 )
xx = 5;
elseif( condition3 )
% very complicated if things continue
xx = 6;
% very complicated if things continue
xx = 7;
% very complicated if things continue
% very complicated if things continue
% very complicated if things continue
end
end
end
So I had the stupid idea, maybe I can get the matlab linter warn me whenever xx does not get accessed again in at least one branch. But this is not possible, because I need xx as the return value, so xx is always touched again. And thus, my goal is not feasible.
What is more, if I do not define xx at the beginning, then matlab will most likely warn me, that xx may be undefined if a certain branch is taken - which is exactly what I wanted to acchieve.
Thanks again.
What is more, if I do not define xx at the beginning, then matlab will most likely warn me, that xx may be undefined if a certain branch is taken - which is exactly what I wanted to acchieve.
It won't warn you. That's a hard error as long as you're calling the function with enough output arguments that MATLAB needs to know the value of that variable that doesn't exist to return that value to the caller. [If it doesn't need to know that output, because it's not returning that value to its caller, it's neither an error nor a warning. See the third example below.]
myfun(2)
Assigned the value 2 to the variable z. End of call to myfun with 0 outputs.
ans = 2
y = myfun(2)
Assigned the value 2 to the variable z. End of call to myfun with 1 outputs.
y = 2
myfun(1)
End of call to myfun with 0 outputs.
y = myfun(1)
End of call to myfun with 1 outputs.
Output argument "z" (and possibly others) not assigned a value in the execution with "solution>myfun" function.
function z = myfun(x)
if x > 1
z = 2;
fprintf("Assigned the value 2 to the variable z.\n")
end
fprintf("End of call to myfun with %d outputs.\n", nargout)
end
That being said, I usually assign a value that can't be valid for that variable (NaN often works for numeric data, and more generally I'd use missing for things like string arrays.)
If you happen to be working with single or double,
function [ xx ] = func()
xx = nan; % fallback value, if something goes wrong so that no exception is thrown
if( condition1 )
xx = 2;
% very complicated if things continue
xx = 3;
% very complicated if things continue
elseif( condition2 )
xx = 4;
if( condition4 )
xx = 5;
elseif( condition3 )
% very complicated if things continue
xx = 6;
% very complicated if things continue
xx = 7;
% very complicated if things continue
% very complicated if things continue
% very complicated if things continue
end
end
if isnan(xx)
fprintf("Failed to assign to xx\n");
end
end
This is a dynamic warning rather than a static warning, so it will not be triggered until the first time you happen to miss an assignment.
Thanks for this nice idea.

Sign in to comment.

More Answers (1)

The warning message about “Value assigned to variable might be unused” at line 3 in your example is becausemlintworks by finding variables that are defined but not used before being overwritten or the script ends.
In MATLAB “mlint” does not provide a way to customize warnings as you describe, but you can suppress warning messages in MATLAB scripts using few ways described below:
1. You can add “%#ok<NASGU>” at the line with warning to suppress “Value assigned to variable might be unused.” warning message, see example below:
function a = mlintcheck()
c = 2; %#ok<NASGU>
b = 5;
if(b > 1)
c = 1;
end
end
2. Using User Interface: Right click on the underline of warning message and select: Suppress Message >> On This Line.
In the provided example, line 6 assigns a value to the variable a, but it does not use a afterward, which should typically trigger a warning about the variable being unused. However, if the variable a were to be used as a return value from a function or passed to another function later, the script might not generate this warning.
Note: MATLAB recommends using “checkcodein place of “mlint” which gives better integration with MATLAB’s Code Analyzer.
Kindly refer to the documentation below to know more about “mlint” and “Adjust Code Analyzer Message Indicators and Messages”:

2 Comments

Dear Jatin, please understand the question before you post an answer.
Dear tommsch, I attempted to clarify your questions based on the comments you provided in the code. I recommend framing your questions in more detail for better understanding.

Sign in to comment.

Categories

Find more on Programming Utilities in Help Center and File Exchange

Products

Asked:

on 30 Aug 2024

Commented:

on 1 Sep 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!