Things to Remember When Developing 64-bit Software
1. Things to Remember When
Developing 64-bit Software
OOO "Program Verification Systems"
www.viva64.com
2. Advantages of 64-bit Software
• You can store all the data right in
memory
• Performance boost (when the
data format is chosen correctly)
• Additional performance boost
due to architectural solutions
• No resources wasted to pass
through the WoW64 layer
3. Who can write
ideal,
spherical
code?
Differences in Programming
• No differences. C/C++ is a language
designed to develop crossplatform
applications
• Only the data model is different
• But in practice, programs are not
completely crossplatform
• A compiled 64-bit program != a correct
64-bit program
4. What Has Changed?
• Pointer size: 4 bytes -> 8 bytes.
• Sizes of types size_t, ptrdiff_t, intptr_t,
uintptr_t, INT_PTR, UINTPTR_T: 4 bytes -> 8
bytes.
• Data alignment. Mind it when serializing
structures.
• Array index size.
• So few? More than enough for troubles!
5. From Simple to Complex.
Magic Numbers
hFileMapping = CreateFileMapping(
(HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE,
(DWORD) 0, (DWORD) (szBufIm),
(LPCTSTR) &FileShareNameMap[0]);
//Number 0xFFFFFFFF is “usigned int”. The fixed code:
#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
6. Storing Pointers in a 32-bit Variable
char *ptr = ...;
int n = (int) ptr;
...
ptr = (char *) n;
A very annoying bug.
It only occurs when the
program is running for
a long time.
7. The Most Important Thing to
Remember with 64-bit Development
• The pointer is not the same thing as int or long.
By the way, the long type is different in the data
models LP64 and LLP64. It also adds some more
confusion.
• Don’t use 32-bit types and address arithmetic
together. Use these types:
– size_t
– ptrdiff_t
– intptr_t
– uintptr_t
– INT_PTR, ….
8. A More Creative Solution for Pointer
Storage
int *p1, *p2;
....
char str[128];
sprintf(str, "%X %X", p1, p2);
int *p1, *p2;
sscanf(str, "%X %X", &p1, &p2);
Use “%p” to print pointer values. Also, programmers often incorrectly
print size_t variables. “%Iu” should be used for this purpose.
const char *invalidFormat = "%u";
size_t value = SIZE_MAX;
printf(invalidFormat, value);
9. A few more words about functions
with variable number of arguments
11. Address Arithmetic. Signed and
Unsigned Types
float p1[100];
unsigned x = 5;
int y = -1;
float *p2 = p1 + 50;
p2 = p2 + x * y;
// Access violation
*p2 = 1.0f;
Correct code!!!!!!!!!!!!!!!!!!!!!!!!!!
12. Address Arithmetic. Overflows.
extern int Width, Height, Depth;
size_t GetIndex(int x, int y, int z) {
return z * Width * Height + y * Width + x;
}
...
MyArray[GetIndex(x, y, z)] = 0.0f;
return size_t(z) * Width * Height +
size_t(y) * Width +
x;
These errors reveal themselves only at LARGE data amounts. Unit tests won’t
help you here, neither will dynamic analyzers such as Bounds Checker (it is too
slow).
18. Other Issues
• Use of deprecated functions (SetClassLong,
GetClassLong, GetFileSize, EnumProcessModules,
GlobalMemoryStatus)
• Undeclared functions in C
• Different parameters of virtual functions
• Array type change
• Pointers in unions
• Exceptions
• And so on…
19. How to Prepare a Reliable 64-bit
Version of a Product?
• Unit-tests (but don’t rely solely on them)
• Regression tests
• Compiler warning elimination
• Using specialized tools, for example the
Viva64 rule set included into the PVS-Studio
static analyzer.
20. PVS-Studio
• Rule sets:
– The most powerful analysis for
64-bit errors among other similar
tools
– General diagnostics
– Micro optimizations
– OpenMP
• About the tool:
http://www.viva64.com/en/pvs-studio/
• Download:
http://www.viva64.com/en/pvs-studio-download/
23. References
• Lessons on development of 64-bit C/C++
applications. http://www.viva64.com/en/l/
• An article. A Collection of Examples of 64-bit
Errors in Real Programs.
http://www.viva64.com/en/a/0065
• Article reviews
http://www.viva64.com/en/r/tag/x64/
• Knowledge base
http://www.viva64.com/en/k/