While developing Viva64 analyzer intended for detecting 64-bit errors, I sometimes encounter interesting ways of code behavior. I would like to show you one example that is not very interesting practically but might be helpful in understanding more complicated cases.
char *A = "123456789"; unsigned B = 1; char *X = A + B; // X: "23456789" char *Y = A - (-B); // Y: <Bad Ptr>
If we compile the 32-bit version of the code, the expressions "A + B" and "A - (-B)" will be equivalent. In the 32-bit code, the pointers X and Y point to the second item of the array A. To understand it better look at the Figure 1 showing the process of calculating "A - (-B)".
But when we compile the 64-bit code, the expressions "A + B" and "A - (-B)" mean absolutely different things. The subexpression "-B" has an unsigned type and equals 0xFFFFFFFFu. And it is this value 0xFFFFFFFFu that is subtracted from the pointer (see Figure 2).
The shown error leads to an access outside the array on a 64-bit system. Such errors might occur when working with negative indexes when 32-bit unsigned variables are used to store them. Here is an example:
unsigned Index = -1; Array[Index] = Z;
Like in the previous case, the expression "Array[Index] = Z;" works well in the 32-bit program but leads to an error in the 64-bit one.
You should avoid using unsigned data types to store negative values. If the variables used to access array items can take negative values, use only signed data types, for example "int". Or rather use the types size_t and ptrdfiff_t.
I often hear in various interpretations the phrase: "The given examples show not the code incorrect from the viewpoint of porting to x64 systems, but the code incorrect in itself". I would like to discuss and theorize a bit on this point in the blog. Please, take this note with a bit of humor.
In forums, people often say that 64-bit versions of programs consume a larger amount of memory and stack. Saying so, they usually argue that the sizes of data have become twice larger. But this statement is unfounded since the size of most types (char, short, int, float) in the C/C++ language remains the same on 64-bit systems. Of course, for ...
In this article, I've collected a huge amount of links all of which could prove potentially useful to software developers who are getting acquainted with 64-bit world. In general, we will cover C/C++ languages, but I am sure, that developers from other languages will discover a lot of interesting stuff here as well.