"warning takes sprintf-like arguments directly" not entirely true?
Mostra commenti meno recenti
If I write this:
message = sprintf('%d %d %d', [1 2 3])
warning(message)
I get a warning from MATLAB Code Analyzer at the second line, saying "warning takes sprintf-like arguments directly".
However if I follow its recommendation and I type:
warning('%d %d %d', [1 2 3])
I get the error "Formatted arguments cannot be non-scalar numeric matrices.".
Is this the desired behaviour?
4 Commenti
KALYAN ACHARJYA
il 19 Set 2018

Massimiliano Zanoli
il 19 Set 2018
Modificato: Massimiliano Zanoli
il 19 Set 2018
Risposte (2)
Image Analyst
il 19 Set 2018
Get rid of the brackets so you have scalars instead of a vector:
>> warning('%d %d %d', [1 2 3])
Error using warning
Formatted arguments must be scalar.
>> warning('%d %d %d', 1, 2, 3)
Warning: 1 2 3
So it must not like that fact that you're trying to put in one matrix with 3 format specifiers (%d).
2 Commenti
Massimiliano Zanoli
il 20 Set 2018
Paul Wintz
il 5 Ott 2021
You can use mat2str to convert arrays to strings.
This is the documented behavior [EDITED] since R2018b:
doc warning
You find:
warning(msg,A1,...,An)
A1,...,An — Values
character vector | string scalar | numeric scalar
Values that replace the conversion specifiers in msg, specified as a
character vector, string scalar, or numeric scalar.
[1,2,3] is not a numeric scalar.
So either use sprintf or provide the elements separately:
data = [1,2,3];
dataC = num2cell(data);
warning('%d %d %d', dataC{:})
While it is documented, one could still discuss, if this is the "desired" behavior. I did not struggle with this feature in the last 20 years.
8 Commenti
Cedric
il 19 Set 2018
We did not struggle with this because it used to be supported. On my 2017b:
A1,...,An — Numeric or character arrays
scalar | vector | matrix | multidimensional array
Jan
il 19 Set 2018
@Cedric: Oh! I've searched in the release notes and did not find a corresponding hint: https://www.mathworks.com/help/matlab/release-notes.html?rntext=warning&startrelease=R2017a&endrelease=R2018b&groupby=release&sortby=descending&searchHighlight=warning.
Massimiliano Zanoli
il 19 Set 2018
There are several "things" going on here actually.
The usual way of using FPRINTF, SPRINTF, and also WARNING, ERROR, ASSERT, is to pass as many extra args as there are data fields in the formatSpec. The classic way is given by Image Analyst in his answer: you have three data fields defined by %d in the formatSpec '%d %d %d', and therefore you pass three extra args for three values and not a vector of values (which is a single arg):
warning( '%d %d %d', 1, 2, 3 ) ;
and not
warning( '%d %d %d', [1,2,3] ) ;
Now F/SPRINTF and formerly WARNING, ERROR, and ASSERT would repeat the formatSpec as many times as needed for matching the size of vectors and arrays of values (when possible), and you could do the following:

You can see this as the program "eating the data with bites of size the number of data fields in the formatSpec".
What is not supported anymore apparently is this behavior, which (after thinking a bit about it) should legitimately not be used in error/warning messages, because it messes up the formatting when you pass inappropriate vectors/arrays and people would certainly misunderstand and make mistakes:

Here you see that the formatSpec with a single data field is repeated nine times (the number of elements in the array), which is neither appropriate nor useful.
Walter Roberson
il 20 Set 2018
Which is why you might want to sprintf first to construct the message and then warning() it... only for mlint to tell you that you should have used warning() directly even though it no longer supports doing the same thing.
Massimiliano Zanoli
il 20 Set 2018
An old topic - but still annoying for those not switching to new matlab releases every year...
IMHO totally undesired behaviour. I liked using sprintf-like arguments to warning (and error) - as the message hint STILL suggests. All code relying on dealing array values to multiple format specifiers breaks with the change to R2018b or later with no hint to be found in the release notes or the code analyzer :'(
distrib = [0.23 3.1415 123.4]; % dummy values
% warning('bad distrib (1%%/median/99%%): %.1f/%.2f/%.1f', distrib) % used to work
warning('bad distrib (1%%/median/99%%): %.1f/%.2f/%.1f', distrib(1), distrib(2), distrib(3)) % how is this better?
distribC = num2cell(distrib);
warning('bad distrib (1%%/median/99%%): %.1f/%.2f/%.1f', distribC{:}) % or this?
A solution (apart from repeating the variable name holding the data to be printed) that does not require an extra line of code before each warning/error would still be interesting. Maybe we'll get something like python's *args? I've tried this
expand = @(x) x{:};
warning('bad distrib (1%%/median/99%%): %.1f/%.2f/%.1f', expand(num2cell(distrib)))
but no luck because the function only 'sees' one argout, thus only reports the first value...
No mlint warning for this, at least not in current releases:
distrib = [0.23 3.1415 123.4]; % dummy values
SIT = @(x) struct('d', num2cell(x));
warning('bad distrib (1%%/median/99%%): %.1f/%.2f/%.1f', SIT(distrib).d)
This relies upon a somewhat new feature, that the return value of a function call may now be indexed with dot notation. Unfortunately I am having difficulty finding the appropriate release notes entry to say which release this started with.
Categorie
Scopri di più su Profile and Improve Performance in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
