4.3.7 Array Subscripts

In general, array subscripts should be of type INTN or UINTN. Using these types avoids problems if an array subscript is decremented below 0. If a UINT32 is used as an array subscript and is decremented below 0, it is decremented to 0xFFFFFFFF on a 32-bit processor and 0x00000000FFFFFFFF on a 64-bit processor. These subscript values are very different. On 32-bit architectures, this value is the same indexing element as -1 of the array. However, on a 64-bit processor, this value is the same indexing element as 0xFFFFFFFF of the array.

If an INTN or UINTN is used instead of a UINT32 for the array subscript, then this problem goes away. When a UINTN is decremented below 0, it is decremented to 0xFFFFFFFF on a 32-bit processor and 0xFFFFFFFFFFFFFFFF on a 64-bit processor. These values are both the same indexing element as -1 of the array.

The following example shows two array subscripts. The first one works on 32-bit architectures but accesses a very high address on 64-bit architectures that may generate a fault or hang condition. The second array subscript is rewritten to work properly on both 32-bit architectures and 64-bit architectures.

Example 13-Array subscripts example
UINT32 Index;
CHAR8 Array[] = "ABCDEFGHIJKLIMNOPQRSTUVWXYZ";
CHAR8 *MyArray;

MyArray = &(Array[5]);
Index = 0;

//
// Works on 32-bit CPUs
// Accesses high memory on 64-bit CPUs and may generate fault or hang
//
Print (L"Character = %c\n", Array[Index - 1]);

////////////////////////////////////////////////////////////////////////

UINTN Index;
CHAR8 Array[] = "ABCDEFGHIJKLIMNOPQRSTUVWXYZ";
CHAR8 *MyArray;

MyArray = &(Array[5]);
Index = 0;

//
// Works on 32-bit CPUs and 64-bit CPUs
//
Print (L"Character = %c\n", Array[Index - 1]);