The development of the 64-bit solutions market has given some new tasks in the field of their verification and testing. The article describes one of such tools - Viva64. It's a lint-like static code analyzer assigned for exposure of errors related with the peculiarities of the 64-bit platforms. The prerequisites for the creation of such an analyzer and its connection with the "Detect 64-Bit Portability Issues" mode in C++ compiler Visual Studio 2005 are covered in the article.
1. 64-bits for C++ Developers: from /Wp64
to Viva64
Author: Andrey Karpov
Date: 03.02.2007
Abstract
The development of the 64-bit solutions market has given some new tasks in the field of their
verification and testing. The article describes one of such tools - Viva64. It's a lint-like static code
analyzer assigned for exposure of errors related with the peculiarities of the 64-bit platforms. The
prerequisites for the creation of such an analyzer and its connection with the "Detect 64-Bit Portability
Issues" mode in C++ compiler Visual Studio 2005 are covered in the article.
One of the most frequent questions I've been asked by the developers of C++ programs is why do we
need Viva64 analyzer if there is a built-in means of diagnostics of a code which is being ported to the 64-
bit architecture in Visual C++ 2005. This diagnostic tool can be turned on using the /Wp64 compiler key
and is called "Detect 64-Bit Portability Issues". The forum answers gave birth to this article. It gives a
brief account of what was the prerequisite for the creation of the static code analyzer, Viva64, and what
is its distinction from other means of verification and code quality improvement.
The compiler key /Wp64 (Detect 64-Bit Portability Issues) is certainly a good feature for detection of
errors related to the migration of application to the 64-bit system. It is able to point to many lines of
code which may cause incorrect behavior. But there is an important detail behind all this. Many of the
widely-spread C++ language constructions are potentially dangerous from the point of view of 64 bits,
but the compiler is not able to display warning messages for them because in most cases they are
absolutely correct. Further on, by means of the examples this aspect will be uncovered in detail. Viva64
analyzer carries out a more profound and detailed analysis, discovers potentially dangerous code and
makes proper diagnostics. It is not an analogue or a substitute of a /Wp64. It is its expansion and
supplement!
Before the Viva64 analyzer release I have participated in the porting of a rather large application to the
64-bit platform, and it was as the following: the first couple of days were spent on compilation of the
project at the new architecture. Then a week more was spent on correction of all the dangerous places
(at least they seemed to be all), they were diagnosed by the /W4 and /Wp64 keys. As a result, in a week
and a half we got the 64-bit variant of the program. The entire source code, except the external
libraries, was compiled when the options /W4 and /Wp64 were on, without a single warning. It is also
worth mentioning that as this project was developed for several platforms, so, for example, with Linux it
was compiled by gcc compiler without warnings with - Wall key. Our team was satisfied and believed
that the migration is almost done. The application pretended to work. And we started testing.
Now the trouble began... Errors appeared in the most unexpected locations. As a consequence of this
we spent more than two months for debug and correction of the errors found. The corrections were
very difficult to make. It turned out that there were no specialized programs for searching errors of such
type. The existing lint-like code analyzers were of little help and required many efforts to be set.
2. You may ask "And what about unit-tests?". They were to narrow down the field of search.
Unfortunately, the project has existed for many years, and on the early stages the use of unit-tests was
not in practice. As a consequence, the code is covered by them rather fragmentarily. But unfortunately,
the lack of unit-tests in our situation had the following consequences: the tests did not cover cases of
processing more than 4 gigabytes of data. It is explainable because such processing was just impossible
before. Even now the use of such tests is embarrassing. Realization of unit tests with such big arrays
leads to enormous time wastes. But the porting to the 64-bit platform was started exactly for the big
arrays.
There was nothing to do, but keep on testing and use our eyes for the analysis of the code, and correct
it. Later on all this led to the idea of the development of a specialized static analyzer. This analyzer
should be aimed at the search of errors which appear when C++ code is being ported to the 64-bit
platform. Now let us consider some situations which can be diagnosed by Viva64 analyzer.
The first example is my favourite one. It's the alteration of the virtual function behavior. It can show up
very simply - the help system in an MFC application suddenly stops working on the 64-bit platform. Here
is the code which illustrates the problem:
class CWinApp {
virtual void WinHelp(DWORD_PTR dwData, UINT nCmd);
};
class CMyApp : public CWinApp {
// Don't called in x64 mode
virtual void WinHelp(DWORD dwData, UINT nCmd);
};
Once, prototype of the WinHelp virtual function in Visual C++ took a variable of DWORD type as the first
argument. And it is quite logical, you also used the DWORD type to override this function at that time.
Then the function prototype in the header files of Visual C++ changed and the first argument came to
the DWORD_PTR type. On the 32-bit platform everything will keep working properly. But it won't on a
64-bit platform. There will be just two different functions, that's it. No one is to be blamed, and one
error has already been found.
If you've got classes with composite inheritance hierarchy and virtual functions, similar errors might hide
there. Accordingly, Viva64 finds and diagnoses errors of this type. The compiler with the /Wp64 key
remains silent because from its point of view everything is correct.
The second example is an infinite loop.
size_t n = bigValue;
for (unsigned i = 0; i != n; ++i) { ... }
Here is the example of a classical infinite loop if the value of the bigValue variable exceeds the value of
UINT_MAX. Even with /Wp64 the compiler has to remain silent because it is a widely-spread operation
of comparison of two variables, each of which has different digit capacity in bits. The code is completely
correct when bigValue<=UINT_MAX. But when we are developing a 64-bit application we often mean
3. processing of great amount of elements. In this case it is necessary to find and analyze such operations.
That's exactly what Viva64 analyzer does. It marks all the comparison operations between 32-bit types
and types which become 64-bit ones on a 64-bit platform.
The third example is an incorrect explicit type conversion. Often the errors of clipping of 64-bit types to
32-bit types hide behind the explicit type conversion. The reasons of the existence of such locations in
the code may be different. The compiler here has no reasons to show warning. One and the same
explicit type conversion can be written in many ways:
size_t a;
int b = (int)a;
int b = (int)(a);
int b = int(a);
int b = static_cast<int>(a);
The search for the explicit type conversion can be a rather laborious task. And what's more, one needs
looking for not all the explicit type conversions, but only dangerous ones from the point of view of
program migration.
Here Viva64 analyzer can be helpful again, if it is run in the corresponding search mode.
The fourth example is an incorrect array indexing.
size_t n = bigValue;
unsigned index = 0;
for (size_t i = 0; i != n; ++i)
array[index++] = 10;
Unfortunately, it is more habitual to use int and unsigned types for array indexing. Never do this! Use
only ptrdiff_t and size_t! If you work with arrays containing more than UINT_MAX elements, as we have
in the example, the behavior of the algorithm will not be correct.
Unfortunately /Wp64 is unable to help, too. If the compiler starts to warn about the usage of a 32-bit
type for indexing, it will reject a large part of your perfectly correct code as defective. The error will
occur only when you work with huge arrays, and there may be no such arrays in your program. But if
you've got ones, it will be difficult to find similar errors.
Viva64 analyzer allows you to look through each usage of 32-bit variables for indexing an array elements
in the program and to make corrections if it is necessary. At the same time it is smart enough not to
draw your attention to constructions of the following type:
enum NUM { ZERO, ONE, TWO };
array[0] = array[ONE];
We'd like to suggest you one more reason to appreciate the advantages of Viva64. Imagine that you've
got an old "dirty" code of a third-party developer. You compile it with the warnings switched off because
4. there is no sense to correct it. Now imagine that you have to port this code to a 64-bit platform. If you
leave the warnings switched off, you'll get a 64-bit code which is unable to work. If you switch on the
warnings, you'll spend weeks and months looking through them. It's a realistic but very sad situation. If
you use Viva64, you can look through ONLY THOSE parts of the code which are potentially dangerous in
the 64-bit context, and you don't have to pay any attention to secondary warnings. This may save your
time to a greater extent.
Of course, it's by no means everything that the analyzer can do. But I hope I've given some general
estimate to it. I'm sure it can save several millions of nerve cells for somebody allowing to release a 64-
bit product in time, and not with a two-months delay, like the company described in the example.
This analyzer is an excellent addition for some other means of verification and enhancement of
applications. The examples of such means are /Wp64 in Visual Studio, Gimpel Software's static analyzer
PC-Lint or Compuware's BoundsChecker. All these and some other tools are able to lighten the burden
for a developer and to speed up software development. I hope that Viva64 will contribute much to that.
I wish you good luck in mastering 64-bit systems!