1

I'm trying to initialize both an array and the structs that it contains

#include <stdio.h>
#include <math.h>

typedef struct
{
    int  rgbtBlue;
    int  rgbtGreen;
    int  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

void edges(int height, int width, RGBTRIPLE image[height][width]);

int main()
{
    int height = 3;
    int width = 3;
    RGBTRIPLE image[height][width] = {
        {{0, 10, 25}, {0, 10, 30}, {40, 60, 80}},
        {{20, 30, 90}, {30, 40, 100}, {80, 70, 90}},
        {{20, 20, 40}, {30, 10, 30}, {50, 40, 10}}
    };
    return 0;
}

I'm not sure whether this initialization can happen at the same time or if I must initialize first all the structs before inserting them into the array.

David Meléndez
  • 389
  • 5
  • 15

2 Answers2

2

You can give initial values for the elements in an array, including members of structures in the array, when defining an array.

The C standard says a thing being initialized shall not have variable length array type (C 2018 6.7.9 3). Your array has variable length array type because height and width are variables, not constants as C defines them. To fix that, you can use #define directives or enum declarations to define height and width.

If you do need a variable length array or a dynamically allocated array, you can give values to its elements using assignment statements, including assignments of whole structures using a compound literal for each structure, as in:

image[i][j] = (RGBTRIPLE) { 0, 10, 25 };

However, the C standard does not provide any way to give initial values to a variable length array or dynamically allocated array during its creation. With optimization, assigning values immediately after creating an array will likely be equivalent to initializing them during creation.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

The problem in your code is not due to the fact that you have an array of structures; rather, it is because it is a variable length array (VLA), and VLAs cannot be initialized.

To fix this (assuming you are using a GCC-compatible compiler, as hinted by your use of __attribute__((__packed__))), you can declare the height and width 'variables' as const:

int main()
{
    const int height = 3;
    const int width = 3;
    RGBTRIPLE image[height][width] = {
        {{0, 10, 25}, {0, 10, 30}, {40, 60, 80}},
        {{20, 30, 90}, {30, 40, 100}, {80, 70, 90}},
        {{20, 20, 40}, {30, 10, 30}, {50, 40, 10}}
    };
    for (int h = 0; h < height; ++h) {
        for (int w = 0; w < width; ++w) {
            printf("%3d %3d %3d | ", image[h][w].rgbtBlue, image[h][w].rgbtGreen, image[h][w].rgbtRed);
        }
        printf("\n");
    }
    return 0;
}

This will compile, but with warnings:

warning : variable length array folded to constant array as an extension [-Wgnu-folding-constant]

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Sizes could be declared as `enum { width=3, height=3 };` to avoid compiler extensions. – user694733 Jan 07 '21 at 16:01
  • @user694733 Of course. But Eric had already posted that by the time I had posted my answer, so adding that option would have been 'stealing' his (excellent) answer. So I didn't do it. – Adrian Mole Jan 07 '21 at 16:05