## ~skeeto/public-inbox

### Legitimate Use of Variable Length Arrays

Brett Kuntz
Details
Message ID
`<223994466.443623753.1590450353746.JavaMail.zimbra@shaw.ca>`
DKIM signature
pass
```Hello, I see you have stumbled into the wonderful world of multi-dimensional pointers. I have used and abused them for years and I have some additional tips for you!

Generally speaking, avoid using the pointer * symbol always. An exception is if a pointer points to a single item, like a structure. Use the square brackets everywhere else, it is cleaner to read, and there is a much lower chance a person messes up pointer arithmetic.

These 4 functions are equivalent, some "look nicer" than others. sum3b and sum3d are my go-to's in a situation like this.

int sum3(int (*array))
{
return (*array) + (*array) + (*array);
}

int sum3b(int (*array))
{
return array + array + array;
}

int sum3c(int *array)
{
return array + array + array;
}

int sum3d(int (*array))
{
int *a = (int*)array;
return a + a + a;
}

Here are 16 ways to use them:

int buff[] = { 1, 2, 4 };

printf("r = %d\n", sum3(&buff));
printf("r = %d\n", sum3b(&buff));
printf("r = %d\n", sum3c(buff));
printf("r = %d\n", sum3d(&buff));

int buff2[] = { { 1, 2, 4 } };

printf("r = %d\n", sum3(buff2));
printf("r = %d\n", sum3b(buff2));
printf("r = %d\n", sum3c(buff2));
printf("r = %d\n", sum3d(buff2));

int buff = { 1, 2, 4 };

printf("r = %d\n", sum3(&buff));
printf("r = %d\n", sum3b(&buff));
printf("r = %d\n", sum3c(buff));
printf("r = %d\n", sum3d(&buff));

int buff2 = { { 1, 2, 4 } };

printf("r = %d\n", sum3(buff2));
printf("r = %d\n", sum3b(buff2));
printf("r = %d\n", sum3c(buff2));
printf("r = %d\n", sum3d(buff2));

Here's another way to write one of your examples:

int array[] = malloc(sizeof(int) * 3);
array = 1;
array = 2;
array = 4;
int r = sum3(array);
free(array);

Another example:

int n = /* run-time value */;
/* TODO: Check for integer overflow. See note. */
float identity[][n][n] = malloc(sizeof(float) * n * n);
if (identity) {
for (int y = 0; y < n; y++) {
for (int x = 0; x < n; x++) {
identity[y][x] = x == y;
}
}
}

And finally, here is my favourite method that I use very often, it is pretty close to "bru del"'s method. Notice how smooth and clean it is! Notice how we can use the [y] offset, we can do this since the size of all of the remaining dimensions is known by the compiler. This works up to as many dimensions as possible.

float identity[][n] = malloc(sizeof(float) * n * n);
if (identity) {
for (int y = 0; y < n; y++) {
for (int x = 0; x < n; x++) {
identity[y][x] = x == y;
}
}
}

If we wanted to make a 3D Cube of the above code:

float identity[][n][n] = malloc(sizeof(float) * n * n * n);
if (identity) {
for (int z = 0; z < n; z++) {
for (int y = 0; y < n; y++) {
for (int x = 0; x < n; x++) {
identity[z][y][x] = 12345;
}
}
}
}

Hope this helps!

-Brett Kuntz```