
More than a year has passed since we analyzed Notepad++ with PVS-Studio. We wanted to see how much better the PVS-Studio analyzer has become since then and which of the previous errors have been fixed in Notepad++.
I decided to find out if there is practical sense in writing ++iterator instead of iterator++ when handling iterators. My interest in this question arouse far not from my love to art but from practical reasons. We have intended for a long time to develop PVS-Studio not only in the direction of error search but in the direction of prompting tips on code optimization. A message telling you that you'd better write ++iterator is quite suitable in the scope of optimization.
But how much relevant is this recommendation nowadays? In ancient times, for instance, it was advised not to repeat calculations. It was a good manner to write:
TMP = A + 10;
X = TMP + B;
Y = TMP + C;
instead of
X = A + 10 + B;
Y = A + 10 + C;
Such subtle manual optimization is meaningless now. The compiler would handle this task as well. It's just unnecessary complication of code.
Introduction
C ++ is unmanaged language, because the programs can escape without saving the user’s data and give the error messages, etc. For example, it takes only to get into an uninitialized memory. For example:
void fall()
{
char * s = "short_text";
sprintf(s,"This is very long text");
}
or
void fall()
{
int * pointer = NULL;
*pointer = 13;
}
It would be better if we could "catch" a program crash just like in java we are catching exceptions, as well we could do anything before the program will crash (save the user’s document, display a dialog with the error message, etc.)A task does not have a general solution, as C ++ does not have its own model of exception handling that is work-related with the memory. Nevertheless, we will consider two methods that are using the features of the operating system that caused an exception.
Unlike most assemblers, the result of multiplication has the same number of digits as the multipliers in C / C + +. In order not to lose the accuracy, sometimes it is needed to perform additional operations for the multiplication.
Let us consider the task. The system determines the time since starting the program in the microprocessor’s ticks by calling the function:
unsigned long long getTickCount ();
Length unsigned long long - 64 bits. Converting to the physical units of time in the system, there is a constant:
const unsigned long long TICKS_PER_SECOND = 1999000000ULL;
It is required to determine the function of transferring ticks in a nanoseconds getNsec (unsigned long long ticks) with semantics:
unsigned long long getNsecNaive (unsigned long long ticks) {
static const unsigned long long NSEC_PER_SECOND = 1000000000ULL;
unsigned long long nsec = NSEC_PER_SECOND * ticks / TICKS_PER_SECOND;
return nsec;
}