
I want to devote this article to an issue that few people think about. More and more widely applied modeling of various processes using a computer. This is a wonderful opportunity to save time and materials on meaningless chemical, biological, physical and other experiments. Having blown a wing model on a computer can several times reduce the number of layouts, which will then be tested in a real wind tunnel. Numerical experiments are trusted more and more. However, behind the triumph of numerical simulation, no one pays attention to the increasing complexity of programs. In the computer and to the programs they see only a tool to get the result. It worries me that not everyone knows and thinks that an increase in the size of a program leads to a non-linear increase in the number of errors. It is dangerous to use the computer as just a great calculator. I think we need to convey this idea to other people.
Big calculator
At the beginning, I wanted to call this article something like, “If programmers cannot manufacture medicines, then why can doctors program?”. An abstract programmer can not do the invention and manufacture of drugs. The reason is clear - he does not have an appropriate education. But programming is not so simple. It seems that the abstract physician, having mastered the programming, will automatically benefit. Fortunately, learning how to program is easier than understanding organic chemistry and the principles of creating medicines.
')
Here lies the catch. Numerical experiment requires no less accuracy than the real one. They learn to wash the tubes after the experiments and monitor their sterility. But few people are seriously concerned about the problem that a certain array may accidentally be uninitialized.
Programmers know that the more complex the software, the more difficult and less obvious the errors are. In other words, I am talking about a
non-linear increase in the number of errors with an increase in the size of the code. But the program for chemical and other calculations is not simple. Here lies the trouble. It is not scary that the medical programmer makes mistakes. They are made by any programmer, regardless of professionalism. It is terrible that such results are beginning to increasingly trust. They counted something and went on to go about their business.
Those whose main activity is programming know the danger of such an approach. They know what undefined behavior is and how a program can pretend that it produces the correct result. There are articles and books on how to write unit tests and how best to check the correctness of calculations.
This is the world of programmers. In the world of chemists / physicists / physicians, I'm afraid this is not the case. They do not write a complex program. Rather, they do not think in this direction. They simply use the computer as a large calculator. This comparison led one of the readers. I will quote him in full here, so that after translating the article, English-speaking readers can also get to know it.
I have something to say on this subject based on personal experience. Being a professional programmer, by education I am a hereditary physicist. It just so happened that at that moment when I was choosing a university, the voice of blood was stronger than faith in the bright future of IT. And I enrolled in a fairly prestigious physical high school by local standards, which, in fact, is a “kindergarten” at a large scientific research institute in its native city of Nizhny Novgorod. People who know the topic will recognize both the research institutes and the name of the school.
Throughout my studies, it turned out quite naturally that I was one of the best in terms of programming (including mathematical methods of physical modeling). And the following facts were clarified there:
1. Physicists consider a computer as a large multifunctional calculator that allows you to build a graph of This dependence on Theta with Gamma tending to infinity. Moreover, in an obvious way, for them the goal is the schedule, and not at all the program that draws it.
2. As a consequence of this fact, a programmer is not a profession. A programmer is simply the person who knows how to use the Big Calculator to build a designated graph. How the schedule will be built does not matter. Totally. How-how did you say? Static analysis? Version Control? Okst, my dear! C ++ is a language for programmers. Physicists write in FORTRAN!
3. As a consequence of the preceding paragraph, a person who aspires to devote his life to writing programs of nat. modeling, even universal, even very, very cool - no more than an application to the calculator. He is not a man at all, but also ... And this, by the way, extended not only to me (where I really, needy), but even to the best calculator in the research institute who taught us numerical methods and that when I came to do his coursework, told me almost in plain language: "You will be despised, get ready to endure."
I did not want to endure, and after graduation I left modeling in an area where programmers are not considered second-class people. I hope this example explains why initiatives like entering static analysis even for relatively large (up to 20-30 people) mathematical modeling projects are a bad thing. There simply may not be a person who knows what it is. And if there is such a person, they will most likely be trampled on him, because they don’t need these new-fangled programmer gadgets. We have lived without them for a hundred years and will continue to live.
And for those who are not bored, the second example. My father, being in retirement age, nevertheless works in a very large defense engineering enterprise, here, in Nizhny (the largest in the city and one of the largest in the country - those who guess again;)). He programmed all his life in FORTRAN. He started with punched cards. I don't blame him for not learning C ++. It was too late for him 10 years ago - he still holds up well. But at the enterprise, where 2/3 of the employees are somehow programming something, the following security measures have been taken:
1. No internet. Totally. Need literature - go to the local library. Stack Overflow? What is it? Even if you want to send a letter by e-mail, you have to write a statement to the boss, where you will explain to whom this letter is and why. The Internet "on receipt" is only for the elect. Thank God, although there is an internal network.
2. No administrative rights on the work computer. Perhaps this rule is reasonable for office plankton, but I find it hard to imagine a programmer who would suit it.
3. (not relevant, just an illustration) You can not even carry a phone with a camera (and where have you seen others now)?
As a result, even youngsters write on Fortran, and there are very few really literate ones in programming. I know, because I was programming a guy about 25 years old, who was my father, and was recommended as a promising one.
My verdict: there are 80s. Even though they pay well there, I will not go there for any price.
These are two examples from the life of the intellectual elite. I do not want to blacken anyone - people do their job well and so, but sometimes looking with what windmills a father sometimes fights with, whom I recently (thank God!) Could still transplant into git, my heart contracts. No OOP in the project under a million lines of code, no static analysis.
Simply, people tend to be very conservative in areas that are not their main “fad.”(Ilya Maysus.
Original comment .)
The most important thing here is that the computer is just a Big Calculator. And if so, then you can know no more about it than its younger relative deserves - “pocket calculator”. Yes, that is how it is used. In different areas. Let's digress for a second and look into the world of physics. Let's see how another theory finds confirmation. To do this, I will again have to give a big quote. The source is Brian Green's book “The Elegant Universe (superstrings, hidden dimensions and the search for the ultimate theory)” [1]:
We all huddled around Morrison's computer, which stood in our office. Aspinwall explained to Morrison how to start the program and what exact form the data entered into it should have. Morrison brought the results obtained at night to the desired form, and now everything was ready.The calculation that had to be carried out, roughly speaking, was reduced to determining the mass of a particular particle, which is the vibrational mode of the string as it moves in the universe, of which we studied the Calabi-Yau component all autumn. We hoped that, in accordance with our chosen strategy, the mass would be exactly the same as the mass in the case of the Calabi-Yau variety that arose after the flop surgery with a discontinuity of space. The last mass was easy to calculate, and we did it a few weeks earlier. The answer turned out to be 3 in the specific system of units that we used. And since numerical calculation was now carried out on a computer, the expected result should have been close to the number 3, something like 3.000001 or 2.999999; the difference from the exact answer would be due to rounding errors.Morrison sat down at the computer. His finger hovered above the "Enter" key. The tension was increasing. Morrison exhaled "go" and launched the program. After a couple of seconds, the computer gave the answer: 8,999999. My heart sank. Is it true that flop tuning with a gap in space violates mirror symmetry, and therefore, it is unlikely to exist in reality? But the next moment we realized that there was some kind of stupid mistake. If there is indeed a difference in the masses of particles on the two manifolds, it is almost unbelievable that a computer would produce a result so close to an integer. If our ideas are wrong, then with the same success a computer could produce a response consisting of completely random numbers. We received the wrong answer, but its incorrectness was of the kind from which it was suggested that somewhere we made a banal mistake. Aspinwall and I went to the board, and instantly the error was found: we forgot the multiplier 3 in a “simple” calculation a few weeks ago, so the correct result should have been 9. Therefore, the computer’s response is exactly what we hoped for.Of course, the coincidence of the result after an error is found is only half convincing. If you know the desired result, it is very easy to find a way to get it. We urgently needed another example. Having all the necessary programs, to invent it was not difficult. We calculated the mass of one more particle on the upper Calabi-Yau manifold, this time with special care to avoid another error. The answer was number 12. We again surrounded the computer and started the program. A few seconds later the answer was received 11,999999. Consent. We have proven that the proposed mirror space is a mirror space, and floppy rearrangements with space gaps are part of string theory.I jumped up from the chair and, intoxicated with victory, made a circle around the room. Morrison, beaming, sat at the computer. And only Aspinwall's reaction was non-standard. “Great. “I didn’t doubt that everything would be like that,” Aspinwall said calmly. “Where's my beer?”I believe that they are geniuses. But let us imagine that with such an approach the value of the integral was calculated by ordinary students. I do not think that then programmers would consider such an approach serious. And if the program immediately issued 3? What then? An error in the program would be considered a proof? I think, then the error would emerge when rechecked by them or by other scientists. But still, the “perfect spherical programmer in a vacuum” is frightened by this approach.
Here is such a reality. This is how not only personal computers are used, but also cluster systems in scientific computing. And most importantly, people trust the results of the programs. And the further, the more such a calculation will be. And the greater will be the danger of the existence of errors in their code.
Maybe it's time to change something?
I have the right to stick a patch to myself. I can recommend that, in my opinion, it is worth a drink with a cold. But not more. I can't drill a tooth or write a prescription.
Perhaps, when the responsibility of the created software system goes beyond a certain framework, its developers should also confirm their qualifications?
I know about the various certifications. But I'm talking about something else. Certification aims to ensure that the code of the program meets certain standards. Indirectly, it partially protects against hack-work. However, the list of areas where certification is required is quite narrow. It clearly does not cover the entire spectrum, where inaccurate handling of the Big Calculator can harm.
Example of danger
I think many of my experiences seem too abstract. Therefore, let's consider something from practice. There is an open package
Trans-Proteomic Pipeline (TPP) for solving problems in the field of biology. It is clearly used. It is used by those who develop and possibly third-party organizations. It seems to me that the presence of any error in it is a potential problem. Are there any mistakes in it? Yes there is. And there are all new. A year ago, we checked this project and wrote a note “
Verifying the Trans-Proteomic Pipeline (TPP) project ”.
Has something changed since then? Nothing changed. The project continues to evolve and grow into new bugs. Big Calculator won. Developers are not busy writing a high-quality project with the least possible number of errors. They just solve problems. If not, they would somehow have reacted to the previous article and thought about the introduction of some static analysis tools. I do not mean that they were obliged to choose PVS-Studio. There are many other static code analyzers. It is important that typical errors continue to appear in the responsible application. Let's see what's new.
1. Some kind of craps keeps writing wrong cycles
In the previous article, I already wrote about incorrect conditions in cycles. There are such errors and a new version of the package.
double SpectraSTPeakList::calcDot(SpectraSTPeakList* other) { .... for (i = this->m_bins->begin(), j = other->m_bins->begin(); i != this->m_bins->end(), j != other->m_bins->end(); i++, j++) { d = (*i) * (*j); dot += d; } .... }
Diagnostic message PVS-Studio: V521 Such expressions using the ',' operator are dangerous. Make sure the expression is correct. spectrastpeaklist.cpp 504
In the “i! = This-> m_bins-> end (), j! = Other-> m_bins-> end ()” test, the expression before the comma does not check anything. The comma operator ',' is used to perform expressions on both sides of it in the order from left to right and
returns the value of the right expression . The correct check should look like this:
i != this->m_bins->end() && j != other->m_bins->end()
Similar mistakes can be seen here:
- spectrastpeaklist.cpp 516
- spectrastpeaklist.cpp 529
- spectrastpeaklist.cpp 592
- spectrastpeaklist.cpp 608
- spectrastpeaklist.cpp 625
- spectrastpeaklist.cpp 696
2. Null pointer dereferencing
Such an error will not lead to incorrect calculation results. There will be a program crash, which is much better. However, not to write about these errors will also be strange.
void ASAPRatio_getDataStrctRatio(dataStrct *data, ....) { .... int *outliers, *pepIndx=NULL; ....
PVS-Studio diagnostic message: V522 Dereferencing of the null pointer 'pepIndx' might take place. asapcgidisplay2main.cxx 534
The null pointer is also dereferenced here:
- Pointer 'peptides'. asapcgidisplay2main.cxx 556
- Pointer 'peptides'. asapcgidisplay2main.cxx 557
- Pointer 'peptides'. asapcgidisplay2main.cxx 558
- Pointer 'peptides'. asapcgidisplay2main.cxx 559
- Pointer 'peptides'. asapcgidisplay2main.cxx 560
- Pointer 'pepIndx'. asapcgidisplay2main.cxx 569
3. Uncleaned arrays
static void clearTagNames() { std::vector<const char *>ptrs; for (tagname_set::iterator i = tagnames.begin(); i!=tagnames.end();i++) { ptrs.push_back(*i); } for (tagname_set::iterator j = attrnames.begin(); j!=attrnames.end();j++) { ptrs.push_back(*j); } tagnames.empty(); attrnames.empty(); for (size_t n=ptrs.size();n--;) { delete [] (char *)(ptrs[n]);
The analyzer noticed here two uncleaned arrays:
V530 tag.cxx 72
V530 tag.cxx 73
Instead of the empty () function, call the clear () function.
4. Uninitialized class objects
class ExperimentCycleRecord { public: ExperimentCycleRecord() { ExperimentCycleRecord(0,0,0,True,False); } ExperimentCycleRecord(long lExperiment, long lCycleStart, long lCycleEnd, Boolean bSingleCycle, Boolean bRangleCycle) { .... } .... }
PVS-Studio diagnostic message: V603 The object was created. If you wish to call the constructor, 'this-> ExperimentCycleRecord :: ExperimentCycleRecord (....)' should be used. mascotconverter.cxx 101
Constructor ExperimentCycleRecord () does not fulfill its purpose. It does not initialize anything. A developer can be a good chemist, but if he doesn’t know how to work with the C ++ language, then the computation that uses uninitialized memory is worthless. It's like taking a dirty test tube.
The line "ExperimentCycleRecord (0,0,0, True, False);" the place to call another constructor, creates a temporary object that will be destroyed. I considered this pattern of errors in more detail in the article "
Without knowing the ford, do not climb into the water - part one ."
Similar incorrect constructors can be found here:
- asapratiopeptideparser.cxx 57
- asapratiopeptidecgidisplayparser.cxx 36
- cruxdiscrimfunction.cxx 36
- discrimvalmixturedistr.cxx 34
- mascotdiscrimfunction.cxx 47
- mascotscoreparser.cxx 37
- tandemdiscrimfunction.cxx 35
- tandemkscoredf.cxx 37
- tandemnativedf.cxx 37
5. Comments that violated the logic
int main(int argc, char** argv) { .... if (getIsInteractiveMode())
PVS-Studio Diagnostic Message: V628 It's possible that the line was commented out improperly, thus altering the program's operation logics. interprophetmain.cxx 175
After the 'if' operator, the lines that perform actions were commented out. As a result, the logic of the program changed not in the way the programmer planned. He wanted nothing to happen when the condition was met. Instead, the if statement affects the code below. The result - the launch of tests now depends not only on the condition “testType! = NO_TEST”, but also on the condition “getIsInteractiveMode ()”. The test may not test anything.
I highly recommend not relying entirely on one testing methodology (for example, TDD).
6. Typos
Typos are everywhere and always. It is not scary if due to such an error in the game you will have fewer lives after the explosion than planned. And what do the wrong data in chemical calculations mean?
void ASAPRatio_getProDataStrct(proDataStrct *data, char **pepBofFiles) { .... if (data->indx == -1) { data->ratio[0] = -2.; data->ratio[0] = 0.; data->inv_ratio[0] = -2.; data->inv_ratio[1] = 0.; return; } .... }
PVS-Studio diagnostic message: V519 The 'data-> ratio [0]' variable is assigned values ​​twice successively. Perhaps this is a mistake. Check lines: 130, 131. asapcgidisplay2main.cxx 131
Randomly two times recorded values ​​in the same variable. It should have been:
data->ratio[0] = -2.; data->ratio[1] = 0.;
And then, they copied this fragment to other places of the program:
- asapcgidisplay2main.cxx 338
- asapcgidisplay2main.cxx 465
- asapratioproteincgidisplayparser.cxx 393
- asapratioproteincgidisplayparser.cxx 518
7. Comparison of signed and unsigned numbers.
It is necessary to be able to compare signed and unsigned numbers. In ordinary calculators, there are no unsigned numbers. And in C ++ there is.
size_type size() const; void computeDegenWts() { .... int have_cluster = 0; .... if ( have_cluster > 0 && ppw_ref.size() - have_cluster > 0 ) .... }
PVS-Studio diagnostic message: V555 The expression 'ppw_ref.size () - have_cluster> 0' will work as 'ppw_ref.size ()! = Have_cluster'. proteinprophet.cpp 6767
I wanted to check “ppw_ref.size ()> have_cluster”. But it turned out quite different.
For simplicity, let our size_t type be 32-bit. Suppose the function “ppw_ref.size ()” returns the number 10, and the variable have_cluster is 15. The function ppw_ref.size () returns the unsigned type 'size_t'. According to C ++ rules, before subtraction, the right operator in the minus operation will also become of the 'size_t' type. So far, so good. On the left we have 10u, on the right 15u.
Subtract:
10u - 15u
And here is the trouble. All the same C ++ rules say that the result of subtracting two variables of unsigned type will also have an unsigned type.
This means that 10u - 15u = FFFFFFFBu. And, as you know, 4294967291 more than 0.
Riot Big Calculator succeeds. It is not enough to write the correct theoretical algorithm. We still have to write the correct code.
A spiritually similar error is present here:
double SpectraSTPeakList::calcXCorr() { .... for (int tau = -75; tau <= 75; tau++) { float dot = 0.0; for (unsigned int b = 0; b < numBins; b++) { if (b + tau >= 0 && b + tau < (int)numBins) { dot += (*m_bins)[b] * theoBins[b + tau] / 10000.0; } } .... .... }
PVS-Studio diagnostic message: V547 Expression 'b + tau> = 0' is always true. Unsigned type value is always> = 0. spectrastpeaklist.cpp 2058
As can be seen from the code, the variable 'tau' takes values ​​in the range [-75, 75]. In order not to go beyond the boundary of the array there is a check: b + tau> = 0. I think you have already understood that this check does not work. The variable 'b' is of type 'unsigned'. This means that the expression “b + tau” is of unsigned type. An unsigned value is always greater than or equal to 0.
8. Strange cycle
const char* ResidueMass::getStdModResidues(....) { .... for (rmap::const_iterator i = p.first; i != p.second; ++i) { const cResidue &r = (*i).second; if (r.m_masses[0].m_nterm) { n_term_aa_mod = true; } else if (r.m_masses[0].m_cterm) { c_term_aa_mod = true; } return r.m_residue.c_str(); } if(! strcmp(mod, "+N-formyl-met (Protein)")) { return "n"; } if (! strcmp(mod, "13C6-15N2 (K)")) { return "K"; } if (! strcmp(mod, "13C6-15N4 (R)")) { return "R"; .... }
Alert issued by PVS-Studio: V612 An unconditional 'return' within a loop. residuemass.cxx 1442
Inside the loop there is a 'return' statement that is called anyway. A loop can perform only one iteration, after which the function ends. I think here there is either a typo or not enough conditions before the 'return' operator.
9. Rough calculations
double RTCalculator::getUsedForGradientRate() { if (rts_.size() > 0) return used_count_ / rts_.size(); return 0.; }
Alert issued by PVS-Studio: V636 The 'used_count_ / rts_.size ()' expression was implicitly casted from 'int' type to 'double' type. Consider using a fractional part. An example: double A = (double) (X) / Y ;. rtcalculator.cxx 6406
Since the function returns double values, it is reasonable to assume the following.
If the variable 'used_count_' is 5, and the function rts_.size () returns 7, then the result should be approximately equal to 0.714. Here only function getUsedForGradientRate () in this case returns 0.
The variable 'used_count_' is of type int. The rts_.size () function also returns a value of type 'int'. Integer division occurs. The result is obvious. It is zero. Then zero is implicitly cast to double. But it does not matter.
To remedy the situation, you can write this:
return static_cast<double>(used_count_) / rts_.size();
Similar shortcomings:
- cgi_pep3d_xml.cxx 3203
- cgi_pep3d_xml.cxx 3204
- asapratiopeptideparser.cxx 4108
10. The Great and Mighty Copy-Paste
The setPepMaxProb () function contains several large blocks of the same type. Immediately it is felt that without the Copy-Paste methodology, this was not done. And as a result, the code contains an error. I had to shorten the code of the example VERY much. In an abbreviated version of the error is easily visible. In the program code, it is almost impossible to notice it. Yes, this is an advertisement of static analysis tools in general, and
PVS-Studio in particular.
void setPepMaxProb( bool use_nsp, bool use_fpkm, bool use_joint_probs, bool compute_spectrum_cnts ) { double prob = 0.0; double max2 = 0.0; double max3 = 0.0; double max4 = 0.0; double max5 = 0.0; double max6 = 0.0; double max7 = 0.0; .... if ( pep3 ) { ... if ( use_joint_probs && prob > max3 ) ... } .... if ( pep4 ) { ... if ( use_joint_probs && prob > max4 ) ... } .... if ( pep5 ) { ... if ( use_joint_probs && prob > max5 ) ... } .... if ( pep6 ) { ... if ( use_joint_probs && prob > max6 ) ... } .... if ( pep7 ) { ... if ( use_joint_probs && prob > max6 ) ... } .... }
V525 The code containing the collection of similar blocks. Check items 'max3', 'max4', 'max5', 'max6', 'max6' in lines 4664, 4690, 4716, 4743, 4770. proteinprophet.cpp 4664
Warning message issued by PVS-Studio: V525 The code containing the collection of similar blocks. Check items 'max3', 'max4', 'max5', 'max6', 'max6' in lines 4664, 4690, 4716, 4743, 4770. proteinprophet.cpp 4664
Unfortunately, the V525 diagnostics give a lot of false positives and are assigned to the third warning level. But if you are not too lazy to study them, you can find such wonderful bugs.
11. The pointer is not always initialized.
int main(int argc, char** argv) { .... ramp_fileoffset_t *pScanIndex; .... if ( (pFI=rampOpenFile(mzXmlPath_.c_str()))==NULL) { .... } else { .... pScanIndex = readIndex(pFI, indexOffset, &iAnalysisLastScan); .... } .... if (pScanIndex != NULL) free(pScanIndex); return 0; }
Warning message from PVS-Studio: V614 Potentially uninitialized pointer 'pScanIndex' used. sqt2xml.cxx 476
This program may crash at the end if the rampOpenFile () function returns NULL. Not critical, but unpleasant.
Another variable that may not be initialized is here:
- Potentially uninitialized pointer 'fp_' used. dta-xml.cpp 307
12. No virtual destructor
class DiscriminantFunction { public: DiscriminantFunction(int charge); virtual Boolean isComputable(SearchResult* result) = 0; virtual double getDiscriminantScore(SearchResult* result) = 0; virtual void error(int charge); protected: int charge_; double const_; };
Warning message issued by PVS-Studio: V599 The virtual destructor is not present, although the class contains virtual functions. discrimvalmixturedistr.cxx 206
Many classes are inherited from the DiscriminantFunction class. For example, the descendant is the DiscrimValMixtureDistr class. The destructor of this class frees the memory, and, therefore, it is very desirable to call it. Unfortunately, the destructor in the DiscriminantFunction class is not declared virtual, with all the ensuing consequences.
13. Miscellaneous
You can find a lot of shortcomings that do not lead to serious consequences, but their presence in the code is unpleasant. There are simply suspicious, but not necessarily erroneous places. Here is one of them:
Boolean MixtureModel::iterate(int counter) { .... if (done_[charge] < 0) { done_[charge]; } else if (priors_[charge] > 0.0) { done_[charge] += extraitrs_; } .... }
The warning given by PVS-Studio: V607 Ownerless expression 'done_ [charge]'. mixturemodel.cxx 1558
What is it? Unfinished code? Or would you like to emphasize that you do not need to do anything if the condition “done_ [charge] <0” is met?
But the wrong release of memory. Most likely, there will be no dire consequences, but this code is with a smell.
string Field::getText(....) { .... char* pepString = new char[peplen + 1]; .... delete pepString; .... }
Alert issued by PVS-Studio: V611 Consider inspecting this code. It's probably better to use 'delete [] pepString;'. pepxfield.cxx 1023
Here you should write "delete [] pepString". Such a place is far from one:
- cruxdiscrimvalmixturedistr.cxx 705
- cruxdiscrimvalmixturedistr.cxx 715
- mascotdiscrimvalmixturedistr.cxx 426
- mascotdiscrimvalmixturedistr.cxx 550
- mascotdiscrimvalmixturedistr.cxx 624
- phenyxdiscrimvalmixturedistr.cxx 692
- probiddiscrimvalmixturedistr.cxx 487
- probiddiscrimvalmixturedistr.cxx 659
- tandemdiscrimvalmixturedistr.cxx 731
- tandemdiscrimvalmixturedistr.cxx 741
But the implementation of the operator "-". Apparently it is not used anywhere. Otherwise, the error would be quickly revealed.
CharIndexedVectorIterator operator++(int) {
Warning message issued by PVS-Studio: V524 It is the odd that the body of the '+' function is fully equivalent. charindexedvector.hpp 81
The operators "-" and "++" are implemented in the same way. And then, probably, copied:
- charindexedvector.hpp 87
- charindexedvector.hpp 159
- charindexedvector.hpp 165
I will not continue further. This is not so interesting, and the article has been dragged out. As always, I ask the developers not to dwell on the editing of these flaws.
Download and test the project yourself using PVS-Studio. I could miss many mistakes. We are ready to provide a free key for some time.
I summarize
Unfortunately, the article was confusing. So what did the author want to say? I will try to briefly repeat what thoughts I wanted to convey.
- We increasingly use and trust programs that perform calculations and modeling processes.
- Programs are very complicated. It is obvious to professional programmers that you cannot create a numerical simulation package in the same way as using a programmable calculator. The increase in complexity leads to an exponential increase in the number of errors [ 2 ].
- It turns out that physicists / biologists / physicians can no longer just count something. You can not ignore the increasing complexity of programs and the consequences of incorrect calculations due to incomplete knowledge of the programming language.
- In the article I gave the arguments that everything is exactly that. The first quote - people use the computer as a calculator. The second quote is yes, just like a calculator. Examples of mistakes - yes, and indeed they make mistakes. My concerns are justified.
And what is proposed to do?
First, I want people to become aware of this problem. And told friends from related areas about her. It has long been obvious to programmers that the increase in complexity and stupid mistakes in large projects are easily brought to trouble. People who use programming simply as a tool do not know about it and do not think about it. And they should be prompted to pay attention to it.
Analogy. People took a cudgel in their hands and began to hunt for the beast. While they are doing this, weapons are rapidly improving. The club in their hands turns into a stone hammer, then into a sword, then into a gun. And they are still trying to just jam her hares on the head. Not only is it inefficient, it has also become much more dangerous (you can shoot yourself or a colleague). Hunters from the tribe of "programmers" quickly adapt. And the rest once. They are busy hunting for hares. After all, the meaning is in the hares. We must tell these people that they want it or not, they need to learn. So only everyone will be better. Nothing to wave a gun.
Additional links
- Brian Green "The Elegant Universe (superstrings, hidden dimensions and the search for a final theory. ISBN 978-5-453-00011-1 (URSS), ISBN 978-5-397-01575-2 (Book House" LIBROCOM ")
- Andrey Karpov. Feelings that were confirmed by numbers. http://www.viva64.com/ru/b/0158/