|
|
|||
![]() PVS-Studio Static Code Analyzer for 64-bit and parallel C/C++ code
|
|||
![]() ![]() ![]() ![]() ![]()
02.09.2010
Feeling the new Intel Parallel Studio XE 2011 beta So I've gotten to try the C++ compiler included into Intel Parallel Studio XE 2011 beta at last.»
30.08.2010
Five days for fixing a two-character error, or a myth of almighty technologies aiding software development In this blog, you may often read posts about how this or that software tool or software development technology helps make fewer errors, find them faster and correct them easier.»
30.08.2010
d'Artagnan and Internet, or working on the problem of bad links Friends, it is high time we stopped considering links only in the context of their number and buying/ selling and counting PR of the site they are laid out on.» ![]()
22.07.2010
Using PVS-Studio with continuous integration systems This article illustrates techniques required to employ the use of PVS-Studio static code analyzer together with continuous integration systems.»
06.07.2010
Comparing capabilities of PVS-Studio and Visual Studio 2010 in detecting defects in 64-bit programs In the article, we will compare three mechanisms of code analysis from the viewpoint of detecting 64-bit errors: the Visual C++ 2010 compiler, the Code Analysis for C/C++ component included into Visual Studio 2010 and Viva64 analyzer included into PVS-Studio 3.60.»
29.06.2010
A Collection of Examples of 64-bit Errors in Real Programs
This article is the most complete collection of examples of 64-bit errors in the C and C++ languages.» ![]() |
Knowledge Base![]() Warning C4267 in the expression unsigned n = str.find(substr)When porting 32-bit code on a 64-bit system, Visual C++ compiler may generate a lot of warnings C4267 for the code where the result of the function std::string::find() is saved into a variable of the unsigned type. Here is such an example: using namespace std;
string s("123456789");
unsigned n = s.find("a");
if (n == string::npos)
cout << "OK" << endl;
else
cout << "64-bit error" << endl;
The function find() returns the value of the type string::size_type that in practice is analogous to the type size_t. In a 32-bit program the types string::size_type and unsigned coincide and have the size 32 bits. When compiling the code example given above in the 64-bit mode, the compiler generates the following warning: warning C4267: 'initializing' : conversion from 'size_t' to 'unsigned int', possible loss of data The reason for that is that the size of the type string::size_type extends to 64 bits in a 64-bit program. Accordingly, the compiler warns you about a loss of significant bits when the 64-bit type is implicitly converted to the 32-bit type. When studying this case, programmers often make this logical mistake: My program never has and will never have strings longer than some Kbytes and Gbytes all the more. So, the unsigned type is quite enough to keep the position of the substring found. The result of such a supposition is that programmers suppress the compiler warning with an explicit type conversion. It allows them to correct only one fragment of the code without involving the following ones. Below is the code "corrected" in this way: using namespace std;
string s("123456789");
unsigned n = (unsigned)s.find("a");
if (n == string::npos)
cout << "OK" << endl;
else
cout << "64-bit error" << endl;
This way of correction is bad. The code contains an error and the warning that could help detect it is now suppressed with the explicit type conversion. If you launch this code in the 64-bit mode, it will print the message "64-bit error" instead of "OK". The error occurs because the function find() returns the value string::npos that equals 0xFFFFFFFFFFFFFFFFui64. This value is cut to the size 0xFFFFFFFFu and saved into a 32-bit variable. As a result, the condition 0xFFFFFFFFu == 0xFFFFFFFFFFFFFFFFui64 is always false. To correctly fix such warnings you should use correct types instead of suppressing them with explicit type conversions. In our case we should use a variable of the type string::size_type to store the result. Here is an example of a proper correction of the code: using namespace std;
string s("123456789");
string::size_type n = s.find("a");
if (n == string::npos)
cout << "OK" << endl;
else
cout << "64-bit error" << endl;
Of course, string::size_type makes the code a bit complicated and less readable, so you can compromise between full accuracy and simplicity of the code using the type size_t. But this is up to you what to choose. The compiler warning C4267 is useful because it allows you to detect various 64-bit errors. Unfortunately, sometimes this warning may be suppressed by an explicit type conversion that was written when developing the 32-bit code. In this case you may use the static analyzer Viva64 included into PVS-Studio to diagnose the related issues. The analyzer generates the diagnostic warnings V201 and V202 that allow you to detect unsafe explicit type conversions when developing 64-bit applications. | ||