11.2.2.3 Non-Auto Variable Size Limits

The compiler option -mlarge-arrays allows you to define and access arrays greater than or equal to 32K. You must ensure that there is enough space to allocate such an array by nominating a memory space large enough to contain such an object.

Using this option will have some effect on how code is generated as it effects the definition of the size_t type, increasing it to an unsigned long int. If used as a global option, this will affect many operations used in indexing (making the operation more complex). Using this option locally may effect how variables can be accessed. With these considerations in mind, using large arrays require careful planning. This section discusses some techniques for its use.

Two things occur when the -mlarge-arrays option is selected:

  1. The compiler generates code in a different way for accessing arrays.
  2. The compiler defines the size_t type to be unsigned long int.

Item 1 can have a negative effect on code size, if used throughout the whole program. It is possible to only compile a single module with this option and have it work, but there are limitations which will be discussed shortly.

Item 2 affects the calling convention when external functions receive or return objects of type size_t. The compiler provides libraries built to handle a larger size_t and these objects will be selected automatically by the linker (provided they exist).

Mixing -mlarge-arrays and normal-sized arrays together is relatively straightforward and might be the best way to make use of this feature. There are a few usage restrictions: functions defined in such a module should not call external routines that use size_t, and functions defined in such a module should not receive size_t as a parameter.

For example, one could define a large array and an accessor function which is then used by other code modules to access the array. The benefit is that only one module needs to be compiled with -mlarge-array with the defect that an accessor is required to access the array. This is useful in cases where compiling the whole program with -mlarge-arrays will have negative effect on code size and speed.

A code example for this would be:

file1.c

 /* to be compiled -mlarge-arrays */
 __prog__ int array1[48000] __attribute__((space(prog)));
 __prog__ int array2[48000] __attribute__((space(prog)));

 int access_large_array(__prog__ int *array, unsigned long index) {
   return array[index];
 }

file2.c

 /* to be compiled without -mlarge-arrays */
 extern __prog__ int array1[] __attribute__((space(prog)));
 extern __prog__ int array2[] __attribute__((space(prog)));

 extern int access_large_array(__prog__ int *array, unsigned long index);

 main() { 
   fprintf(stderr,"Answer is: %d\n", access_large_array(array1, 39543));
   fprintf(stderr,"Answer is: %d\n", access_large_array(array2, 16));
 }