3

I'm stuck with a "conflict" between with AnsiStrings sprintfmember function and Cppcheck's built-insprintf` knowledge.

In cases like this,

const char* name = "X";
int version = 1;

return AnsiString().sprintf("%s.H%02d", name, version); // <-- HERE

I'm getting this warning in the Cppcheck GUI

Id: wrongPrintfScanfArgNum

Summary: sprintf format string requires 0 parameters but 1 is given.

Message: sprintf format string requires 0 parameters but 1 is given.

which shows that Cppcheck is talking about the sprintf function, but I'm using a member function of the VCL class AnsiString with the same name.

As to get rid of this false positive, I could use

  • an inline suppression: // cppcheck-suppress wrongPrintfScanfArgNum
  • an intermediate variable: AnsiString result; result.printf(...); return result;
  • the sprintf function, which means handle the buffer space manually

But all these options work local, and make the code harder to read/maintain.

How can I teach Cppcheck to differentiate between overloaded names?


Edits:

  • I wrote override, but meant overloading, I corrected that in the current text.
  • added literal initialization of variables, which is important for name
Community
  • 1
  • 1
Wolf
  • 9,679
  • 7
  • 62
  • 108
  • 1
    Perhaps raise a bug with the actual author of the tool? This seems like the wrong place to ask. – Lightness Races in Orbit Sep 05 '16 at 11:00
  • 1
    BTW, editorial nitpick incoming: you emphasise `sprintf` being a _function_, but in fact your `AnsiString::sprintf` is a _function_ also. That it is a member function (what you are calling a "method", though this terminology does not exist in C++) does not make it not a function. The key point is that it's not `std::sprintf` (or `::sprintf`). – Lightness Races in Orbit Sep 05 '16 at 11:02
  • 2
    Also, as an aside, `AnsiString` is poorly designed. Sure, CppCheck should be smarter than this, but it could be equally confusing for a human. Why re-use the name "`sprintf`" and change its parameters? Silly. I suggest you stick to standard technologies and well-regarded third-party libraries only; not Turbo C++ nonsense! – Lightness Races in Orbit Sep 05 '16 at 11:04
  • 1
    Hah, that's weird; I'd opened a few tabs of new questions as well as notifications on old questions. After commenting here, I moved to the next in my list, on which I'd received an upvote. There I found lots of comments and edits from you from 2014 :D – Lightness Races in Orbit Sep 05 '16 at 11:11
  • 1
    @LightnessRacesinOrbit (concerning *`wrong place to ask`*) well, sometimes it's not a bug, but lack of documentation (or reading skills), I expected that overriden functions should be a problem for naive analysis approaches but I know that Cppcheck doesn't check on a simplistic lexical level, so I shared my problem here, hoping someone else had already a working solution... – Wolf Sep 05 '16 at 12:04
  • 1
    A great alternative to sprintf in any form is `boost::format` IMHO. You get the advantages of readability and automatic memory management. – Richard Hodges Sep 05 '16 at 12:37
  • 1
    Of course, it's not overriding, but overloading. Sorry for the confusion. – Wolf Sep 06 '16 at 08:12

2 Answers2

2

Interesting.

Yes I agree this should be reported in http://trac.cppcheck.net. Looks like bugs.

I can see 2 bugs.

The AST does not show proper type information for the 'AnsiString()' even when I add a AnsiString class.

The Library should not match sprintf in that code. It is clear that some method is called.

Daniel Marjamäki
  • 2,907
  • 15
  • 16
  • 1
    It really has to do with **the name `sprintf`**, see my [answer](http://stackoverflow.com/a/39343710/2932052)/[bug report](http://trac.cppcheck.net/ticket/7726) – Wolf Sep 06 '16 at 08:08
1

It really is a bug.[1] Cppcheck 1.75 is smart in checking format strings, but obviously only in some cases, one of them is the second parameter of every function called printf, so the problem has nothing to do with AnsiString::sprintf but with every alternate implementation.


[1] #7726 (False positive: format string checked for every function called 'sprintf') – Cppcheck

Wolf
  • 9,679
  • 7
  • 62
  • 108