Reputation: 2481
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
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
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
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
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