0

I have this simple piece of code in file test.c:

#include <stdio.h>
#include <string.h>

struct Student {
    char name[10];
    int grade;
};

int main(){

    struct Student s = {.name = "Joe", .grade = 10}; //correct

    struct Student students[10];

    students[0] = {.name = "John", .grade = 10}; //error

    students[1] = s; //correct

    struct Student some_other_students[] = {
        {.name = "John", .grade = 10}
    }; //correct

    students[2].grade = 8;
    strcpy(students[2].name, "Billy"); //correct?!? O_o


    return 0;
}

Upon compiling I get this error

test.c|14|error: expected expression before '{' token|

Shouldn't the array initialize correctly at students[0] = {.name = "John", .grade = 10};?. When initializing it this way: struct Student s = {.name = "Joe", .grade = 10}; and then setting it to the array like this students[1] = s; I get no errors. Just an assumption but could it be that {.name = "Joe", .grade = 10} expression, has no reference in memory, and an array of structures is just an array of references to already initialized structures?

But then again if the array is just a reference of initialized structures how this can work? students[2].grade = 8;?

3
  • 4
    Assignment is not initialization. However, you can use a compound literal in assignment. Commented Jan 5, 2018 at 14:05
  • ... which would look like: { students[0] = (struct Student) {.name = "John", .grade = 10}; } The outer curly brackets are optional. They just limit the lifetime of the compound literal. Commented Jan 5, 2018 at 14:07
  • Indeed, (struct Student){.name = "John", .grade = 10} gives no errors... But is my question without reason? Shouldn't the compiler know that an array of struct Student might as well get assigned with such structures? Commented Jan 5, 2018 at 14:10

1 Answer 1

4

You can only initialize variables when you define them. After the variables are defined you can not use the same syntax when you assign to the variables as you use for initialization. That you attempt to assign to an array element doesn't matter, what's relevant is that you use assignment instead of initialization.

With that said, there is a way around that, even if the syntax is a little clumsy (IMO), and that is to use compound literals to create a temporary dummy structure object, and copy that to the variable:

students[0] = (struct Student){.name = "John", .grade = 10};

The above is equivalent to

{
    // Define and initialize a "temporary" Student structure object
    struct Student temp = {.name = "John", .grade = 10};

    // Assign it to students[0]
    students[0] = temp;
}

Or you can just initialize the array when you define it:

struct Student students[10] = {
    {.name = "John", .grade = 10}
};
Sign up to request clarification or add additional context in comments.

3 Comments

Correct. Like alk and EOF answered in a comment above. Still don't know tho why students[2].grade = 8; works, since it's just an assignment. But that's another question. The one I asked is answered, so I mark it.
@venge students[2].grade is basically a simple int variable. You can assign to it like any other variable.
So actually this struct Student students[10]; tells the compiler how it should treat the memory pointed by the array. It should be treated like a struct Student and expect one integer and a char[10]. In an OOL {.name = "John", .grade = 10} this should already have the properties of struct Student to be assigned to such variable. But in C it can be used as an assignment but has no other valid uses. This is hard for me to accept!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.