About a week ago, I published the "Three Interviews About Static Code Analyzers" article at Habrahabr. This article presents opinions of three experienced programmers from the companies Acronis, AlternativaPlatform and Echelon Company concerning software development methodologies as well as some of their ideas about using static code analyzers.
Since the article was sponsored by the OOO "Program Verification Systems" company, developer of the PVS-Studio static analyzer, I asked Andrey Karpov (CTO) to answer some questions too. In particular, I asked him to comment upon the most interesting aspects and ideas of all the three interviews and say a few words for colleagues and readers, too. Here's what we've got - one more interesting interview.
While visiting some conferences and having informal conversations in the foyer or at dinner, I was asked a couple of times by fellow programmers, "Does anybody really write programs in C++ nowadays?" And they were sincerely surprised at my answer, "Yes, and that's one of the most widely used languages." It's just that it is not much mentioned nowadays, when you've got such languages as PHP, Ruby and Go all around. It may seem now that C++ "was a long time ago and never happened anyway". And I'm pleased to find evidence to the contrary when reading in that article that Acronis Backup, for instance, is written in C++ and has a team of 70 programmers to work on it. Personally I don't worry about the future of the C and C++ languages. It's just surprising why many programmers consider C++ a dead language.
It was also pleasant to know that Acronis extensively uses the Code Review technique. This method of software quality improvement is often underestimated or thought to be too time-consuming. But a cheapskate pays twice.
By the way, I know at least one example when multiplying one sizeof by another may make sense in practice. For instance, such multiplication is done when sizeof() is used to take the number of items in an array. I mean cases like this:
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
That 'arraysize' protects the code from accidental passing of an ordinary pointer instead of an array as an argument. Look here for details.
It may well result in a construct like "sizeof(float) * (sizeof(ArraySizeHelper(array)))". But the PVS-Studio analyzer knows about cases like this and doesn't generate warnings on them.
I'm not familiar with Java that well, so I can't say for sure how well this language protects code from errors. Of course, the absence of manual memory management alone simplifies programmers' life a lot. But I believe not all errors depend on the language. For example, such are the consequences of using the Copy-Paste method. I think using a static analyzer to find typos would be quite relevant for Java too. But again, I don't know what existing code analyzers have to offer to Java.
Their answers certainly feel a bit too official. It might be that the specifics of their work and type of documents they have to prepare influence the language they use. On the one hand, I don't like such texts because they are too boring to read. On the other hand, I envy their authors. Texts like that make an impression of grand and serious work behind them. We don't write about PVS-Studio in that manner. We write much about how to use PVS-Studio but too little about the analyzer itself and how important it is. Guess we should try writing solid descriptive papers about our tool too.
I'd also like to take the opportunity and bring up the following topic. Our users, both current and potential, do not treat PVS-Studio as a tool capable of detecting vulnerabilities at all. I don't get that. True, we don't seek beetles in code. We are oriented toward searching bugs rather than defects making software vulnerable. But I still can't understand that black-and-white view of the situation. Many errors can be treated as vulnerabilities too, can't they? You just have to look at them from a different angle.
Take, for instance, the UltimateTCPIP project. PVS-Studio detects the following bug in it:
char *CUT_CramMd5::GetClientResponse(LPCSTR ServerChallenge)
{
...
if (m_szPassword != NULL)
{
...
if (m_szPassword != '\0')
{
...
}
V528 It is odd that pointer to 'char' type is compared with the '\0' value. Probably meant: *m_szPassword != '\0'. UTMail ut_crammd5.cpp 333
We speak of this error as a simple typo. The pointer by mistake fails to be dereferenced, which results in a failure of an empty string check. The fixed code should look as follows:
if (*m_szPassword != '\0')
But on the other hand, it's a true and real vulnerability. Let's put aside the question if anyone can exploit it and how dangerous it is. The main point is that a check for typos may reveal a real breach in code security. What if anything goes wrong if the program starts working with an empty password?
Here is another example from PostgreSQL:
char *
px_crypt_md5(const char *pw, const char *salt,
char *passwd, unsigned dstlen)
{
....
unsigned char final[MD5_SIZE];
....
/* Don't leave anything around in vm they could use. */
memset(final, 0, sizeof final);
....
}
V597 The compiler could delete the 'memset' function call, which is used to flush 'final' buffer. The RtlSecureZeroMemory() function should be used to erase the private data. pgcrypto crypt-md5.c 157
In this code, PVS-Studio finds that the 'final' array is not cleared before leaving the function. To find out why, see the description of the V597 diagnostic.
So I don't get why PVS-Studio's diagnostics are "not very good at revealing vulnerabilities".
Static analysis is OK in general. The related toolkit is rapidly developing and growing more and more popular.
I'd like to see that happen faster in Russia too, though. We have almost no static analysis tools market nowadays. Just take a look at the number of visits to our website, demo version downloads and sales statistics. Half of the entire traffic activity is done by visitors from Russia. But Russian customers make only a few percent instead of 50%. That's sad.
An appeal like "use static analysis in your work" would sound trivial. So I'll touch upon an unusual subject.
I wish that employers and employees get on well with each other. A head's directions may often look strange, to say the least. But we should never forget that company authorities often have wider knowledge about the project in general. And what an employee may find strange might be a thing which appears to be very useful or simply forced at the higher level. Unfortunately, programmers' bosses often come from the programmer community themselves and therefore tend to be introversive. In other words, when setting a task, they don't think it is important to explain why something should be done. We should understand and forgive them. And then, when asking questions, try to understand the reasons for such strange directions. Most likely, your boss will gladly explain. It's just that he has forgotten about that or "optimized" the time spent on a conversation by reducing a complex task to the "do it this way" direction. Therefore, I also wish that authorities don't forget to explain their steps and decisions.
And thanks to the interview organizer.
So, dear readers, that was a kind of a bonus material we have just offered to you. The author hopes you were enjoying reading it. Let's finish here. Write quality code and don't forget to use a wide variety of useful tools. Good luck! See you soon.