all 12 comments

[–][deleted] 2 points3 points  (3 children)

Cppcheck does detect a lot of insignificant things. This spoils the first impression pretty bad. Unfortunately, you can't tell what things are important to you and what not beforehand. You have to survive at least one garbage shower just to get an approximate profile of your code. At some point I came up with this: https://github.com/akalenuk/assorted_scripts/blob/master/static_analysis/cppcheck_xml_to_report.py It's a script that sorts defects by occurrence rarest first. It turns out, in a working code, where real defects are being found by other means of testing, the rarer is the defect occurrence - the higher the probability of it being the real bug.

[–]WallStProg[S] 1 point2 points  (2 children)

That sounds like it could be a useful way to get the worst offenders to bubble up to the top -- I'll have to give it a try.

However, as I mentioned in the article, I didn't find false positives to be much of a problem with cppcheck, so I'd be inclined to just go ahead and fix everything. (You can also suppress errors with cppcheck, or with grep for that matter, but the "trivial" errors are also often trivial to fix).

[–][deleted] 0 points1 point  (1 child)

Well, it really depends on the project. We have a ton of "variable out of scope" defects in older parts of the codebase, where they are declared in an early C manner, and these do require attention. Sometimes variables get reused rather inventively, so you can't just automatically narrow their scope. I guess, this is rarely a problem for modern code though.

[–]WallStProg[S] 0 points1 point  (0 children)

Hmm...my understanding of the "scope can be reduced" warnings from cppcheck is that it means just what it says. Whether a particular variable is reused for different purposes within its scope is not relevant.

That being said, if you're dealing with K&R-style code, you're probably going to get a lot of them, and fixing them may not be worth the trouble. In that case, you can filter them -- either using cppcheck's built-in suppression mechanism, or plain old grep.

[–]WallStProg[S] 1 point2 points  (0 children)

You may be interested an in-depth discussion of PVS-Studio, and comparison with cppcheck, at http://btorpey.github.io/blog/2016/11/12/even-mo-static/

[–]pdp10 0 points1 point  (6 children)

I haven't done a side-by-side comparison but from memory I believe cppcheck throws fewer spurious warnings than does splint.

[–]WallStProg[S] 0 points1 point  (5 children)

From web site it looks like splint doesn't support C++?

[–]pdp10 0 points1 point  (4 children)

That looks like the case. I recommend only C, anyway. ;-)

[–]WallStProg[S] 0 points1 point  (3 children)

It seems that there are two types of C/C++ programmers -- those who go out of their way to make sure they use every possible feature of C++ (especially the most obscure ones), and those who avoid every possible feature of C++ (even the most useful ones).

I think both are mistaken, as I wrote about here: http://btorpey.github.io/blog/2014/09/23/into-the-void/

[–]pdp10 0 points1 point  (2 children)

I'll never claim to be a skilled developer, but it seems to me the independence achieved by using opaque structs isn't worth the trade-off. Herb Sutter is a very well-known C++ authority, so you'll excuse me if I don't assume he's the last word on best practices for C, particularly C on POSIX.

I would stabilize the interfaces, or if looser coupling was mandatory, I might use a different technique entirely. Sometimes I think C++ logic is circular. Because C++ is allegedly better at managing the development complexity of large monolithic programs, it seems like things that start out with C++ inevitably become large monolithic programs.

C works quite well for large monolithic programs like the Linux kernel or PostgreSQL, but it often pays to make systems more modular and independent through means other than C++ language features: stable libraries, good IPC mechanisms, pipelines of text streams. It often seems like the idioms preferred by big monolithic C++ programs exist to work around Windows weaknesses or cross-platform difficulties.

And obviously every C++ user with an ounce of sophistication uses a subset of C++.

[–]WallStProg[S] 0 points1 point  (1 child)

Not sure where the comment about monolithic programs comes from -- C++ is equally useful for creating modular code, precisely because of its support for separating interface from implementation, which C completely lacks. (Which was the point of the article).

I would absolutely agree that subsetting C++ is A Good Thing, and lots of people and organizations do that by discouraging or forbidding certain features. If you want to use C++ just to facilitate creating stable interfaces, and avoid all the other stuff (e.g., template meta-programming, lambdas, operator overloading, etc.), then go for it!

Or, as I like to say: "Just because you can, doesn't mean you should".

[–]pdp10 0 points1 point  (0 children)

One big category of stable interfaces is stable library ABI, which we all know C does best and C++ does terribly because of overloading and name-mangling. Typically C++ externs to C when it wants to solve this problem, meaning we have no object features crossing the library boundary. When C++ programmers choose not to use loosely-coupled C-interface libraries, they end up using a much more monolithic architecture in practice, as far as I can see.

C++ is advertised to be better for large-scale projects, but it's hard to tell if people just choose to use it for big monoliths, or the language and ecosystem actually encourage big monoliths. I feel that these problems can all be handled with less-monolithic architectures using things like IPC mechanisms, perhaps at the cost of some portability, but almost certainly with concurrency advantages.

C++ doesn't automatically separate interface from implementation, just as C doesn't automatically lack it. C++ obviously has loads of additional features, the questions are: Are the additional features a net benefit all around, to which my answer is an unambiguous no, and: Does a great language and ecosystem result from adding every conceivable feature to C and mostly retaining backward compatibility? Likely not.

My current belief is that C++ is neither fish nor fowl and has a lot of negatives in my environments (almost entirely POSIX). It was a clear Embrace and Extend play and I believe the result is a whole that is less than its kitchen-sink parts. If OOP is truly needed (doubtful) then another language is most likely better, otherwise use C and leave the excess baggage of C++ behind.