Galaxy
Galaxy

Reputation: 2481

Assignment vs. Initialization: Initializing structs inside another struct in C

I have a struct with two fields which are structs themselves. I want to use an initializer list to assign the fields of the internal structs, without having to assign each single field manually.

struct point
{
    int x;
    int y;
};

struct rectangle
{
    struct point p1;
    struct point p2;
};

struct rectangle r2;
r2.p1 = {5, 6};
r2.p2 = {7, 20};

However this code won't compile:

structs3.c:105:11: error: expected expression before ‘{’ token
   r2.p1 = {5, 6};
           ^
structs3.c:106:11: error: expected expression before ‘{’ token
   r2.p2 = {7, 20};
           ^

Why doesn't this work? What is the reason?

Upvotes: 2

Views: 1354

Answers (4)

AnT stands with Russia
AnT stands with Russia

Reputation: 320541

The reason is that in C { 5, 6 } by itself is not an expression and it cannot be used by itself as an operand in expressions. { ... } list can only be used as part of initializer syntax in declarations or in compound literals.

So, if you want to use assignment specifically, you'd have to resort to compound literals

struct rectangle r2;
r2 = (struct rectangle) { { 5, 6 }, { 7, 20 } };

optionally with designators

struct rectangle r2;
r2 = (struct rectangle) { .p1 = { 5, 6 }, .p2 = { 7, 20 } };

or, to assign the sub-structs individually

struct rectangle r2;
r2.p1 = (struct point) { 5, 6 };
r2.p2 = (struct point) { 7, 20 };

Again, if you so desire, you can express it as

struct rectangle r2;
r2.p1 = (struct point) { .x = 5, .y = 6 };
r2.p2 = (struct point) { .x = 7, .y = 20 };

Upvotes: 3

Galaxy
Galaxy

Reputation: 2481

I would like to add to sth's answer. Initialization means giving an initial value to a variable when a variable is first declared/defined. An initialization list in C is valid only when declaring/defining a variable for the first time. Assignment means giving a value to a variable after that variable had already been declared/defined, somewhere lower in the code.

  1.  struct rectangle r2;
  2.  r2.p1 = {5, 6};
  3.  r2.p2 = {7, 20};

The initialization of the struct rectangle object is on line 1. After that line has executed, the struct was now created in the memory. In that case, we can't use an initializer list because this is an assignment. I'll write the code that Some programmer dude and sth suggested.

  1.  struct rectangle r2 = { {5, 6}, {7, 20} };

Notice that it fits on one line. It is an initialization! I can change the above code. Notice that there can also be any other lines of code after the initialization. I want to prove that this is an assignment.

  1.  struct rectangle r2;
  2.  int x = 1 + 2;
  3.  printf("Hello World\n");
  4.  r2.p1 = {5, 6};
  5.  r2.p2 = {7, 20};

Upvotes: 0

sth
sth

Reputation: 229643

What you have is not an initialization, it's an assignment. The initialization must be done directly where the variable is declared, in this case struct rectangle r2;.

You can initialize both nested structs in one step by nesting {}:

struct rectangle r2 = {
    {5, 6},
    {7, 20},
};

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409196

You could do it when defining r2, like

struct rectangle r2 = {
    {5, 6},
    {7, 20}
};

Or using compound literals as in

r2.p1 = (struct point){5, 6};
r2.p2 = (struct point){7, 20};

Upvotes: 6

Related Questions