Put array in register in C/ C++


An array in C or C++ can be placed in a register explicitly if it is allocated memory statically and its memory is not accessed. If memory is allocated dynamically (using malloc and other similar functions) and/ or memory of such an array is fetched, the code will give a compile time error.

Placing array in register will give a significant boost but it is limited by the above conditions. Even if you do not explictly define an array as a register, compiler may decide to make it a register for optimization.

In short, one cannot define an array as a register if the address of the array is being explicitly invoked such as:

Key points:

  • A register is accessed using direct addressing mode and does not have a memory address (like another assigned memory)
  • An array has a memory address associated with it and all elements are contiguous
  • An array can be placed in registers internally to accelerate operations
  • Even on declaring a data as a register, it may not be placed on a register (a specific property of C and C++)

We shall, now, go through some code examples to understand the idea behind this better.

Statically allocated array

Consider this example where we define a statically allocated array of 2 dimension 2 x 2 of strings (or character array). If we define this array as a register, there will be no problem. This is because we are not dealing with the array by referring it through memory location.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    register char* words[2][2] = {{"opengenus", "open source"},{"opengenus iq", "cs"}};
	printf("%s", words[1][0]);
}

Output:

opengenus iq

We can assign specific value to a specific index of our statically allocated array in register as well. We have demonstrated this in our next example. The focus is on this line:

words[1][1] = "computing";

Go through our complete C code example:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int H = 2, C = 4;
    register char* words[2][2] = {{"opengenus", "open source"},{"opengenus iq", "cs"}};
    words[1][1] = "computing";
	printf("%s", words[1][1]);
}

Output:

computing

Get address of a location

The main problem comes when we try to get the memory address of a specific element of an array declared as a register. This is because we cannot get the memory address of a register in C/ C++.

In this example, we try to fetch the memory location of a specific element and print it:

printf("%p", (void *)&words[1][1]);

This code line fails during the compilation step. Go through this complete C code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    register char* words[2][2] = {{"opengenus", "open source"},{"opengenus iq", "cs"}};
	printf("%p", (void *)&words[1][1]);
}

Compilation error:

opengenus.c: In function 'main':
opengenus.c:7:2: error: address of register variable 'words' requested
  printf("%p", (void *)&words[1][1]);
  ^

The same code works perfectly fine if we remove the register keyword that is not define the array as a register. Consider this C code example:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char* words[2][2] = {{"opengenus", "open source"},{"opengenus iq", "cs"}};
	printf("%p", (void *)&words[1][1]);
}

Output:

0x7ffc4aba9678

Dynamically allocated array

If we dynamically allocate a 1D array, there will be no problem but the issue comes when we try to define arrays of higher dimension. This reflects the idea that we allocate more memory to a specific pointer to define a higher dimension.

A work around is to visualize the array as a 1D array (row wise or column wise) and process it accordingly. For this, register will work.

Consider this code where we define the same 2D array using malloc:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    register int *words[2]; 
    for (int i=0; i<2; ++i) 
         words[i] = (int *)malloc(2 * sizeof(int));
}

Compilation error:

opengenus.c: In function 'main':
opengenus.c:8:10: error: address of register variable 'words' requested
          words[i] = (int *)malloc(2 * sizeof(int));
          ^

The same code compiles code if we do not define the array as a register. Consider this code example:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int *words[2]; 
    for (int i=0; i<2; ++i) 
         words[i] = (int *)malloc(2 * sizeof(int));
}

With this, you have the complete idea of defining an array as a register in C and C++ and the significance behind it.

Learn more: