|
20 issues of porting C++ code on the 64-bit platform
1. Off-warningsIn all books devoted to the development of the quality code it is recommended to set a warning level of warnings shown by the compiler on as high level as possible. But there are situations in practice when for some project parts there is a lower diagnosis level set or it is even set off. Usually it is very old code which is supported but not modified. Programmers who work over the project are used to that this code works and don’t take its quality into consideration. Here it is a danger to miss serious warnings by the compiler while porting programs on the new 64-bit system. While porting an application you should obligatory set on warnings for the whole project which help to check the compatibility of the code and analyze them thoroughly. It can help to save a lot of time while debugging the project on the new architecture. If we won’t do this the simplest and stupidest errors will occur in all their variety. Here it is a simple example of overflow which occurs in a 64-bit program if we ignore warnings at all. unsigned char *array[50]; unsigned char size = sizeof(array); 32-bit system: sizeof(array) = 200 64-bit system: sizeof(array) = 400 2. Use of the functions with a variable number of argumentsThe typical example is the incorrect use of printf, scanf functions and their variants: 1) const char *invalidFormat = "%u"; size_t value = SIZE_MAX; printf(invalidFormat, value); 2) char buf[9]; sprintf(buf, "%p", pointer);In the first case it is not taken into account that size_t type is not equivalent to unsigned type on the 64-bit platform. It will cause the printing of an incorrect result in case if value > UINT_MAX. In the second case the author of the code didn’t take into account that the pointer size may become more than 32-bit in future. As a result this code will cause the buffer overflow on the 64-bit architecture. The incorrect use of functions with a variable number of arguments is a typical error on all the architectures, not only on 64-bit ones. This is related to the fundamental danger of the use of the given C++ language constructions. The common practice is to refuse them and use safe programming methods. We recommend you strongly to modify the code and use safe methods. For example, you may replace printf with cout, and sprintf with boost::format or std::stringstream. If you have to support the code which uses functions of scanf type, in the control lines format we can use special macros which open into necessary modifiers for different systems. An example:
// PR_SIZET on Win64 = "I"
// PR_SIZET on Win32 = ""
// PR_SIZET on Linux64 = "l"
// ...
size_t u;
scanf("%" PR_SIZET "u", &u);
3. Magic numbersIn the low-quality code there are often magic numbers the mere presence of which is dangerous. During the migration of the code on the 64-bit platform these magic numbers may make the code inefficient if they participate in operations of calculation of address, objects size or bit operations. Table N3 contains basic magic numbers which may influence the workability of an application on a new platform.
You should study the code thoroughly in search of magic numbers and replace them with safe numbers and expressions. To do so you can use sizeof() operator, special values from Let’s look at some errors related to the use of magic numbers. The most frequent is a record of number values of type sizes.
Let’s return to the error with INVALID_RESULT. The use of the number 0xFFFFFFFFu causes the failure of the execution of "len == (size_t)(-1)" condition in a 64-bit program. The best solution is to change the code in such a way that it doesn’t need special marker values. If you cannot refuse them for some reason or think it unreasonable to correct the code fundamentally just use fair value -1.
Double type as a rule has size 64 bits and is compatible with IEEE-754 standard on 32-bit and 64-bit systems. Some programmers use double type for storing of and work with integer types.
It is possible that an approximate value can be used in your program, but to be on the safe side we’d like to warn you about possible effects on the new architecture. And in any case it is not recommended to mix integer arithmetic with floating-point arithmetic.
|