2

I'm having trouble initializing a struct that has a union in it also. I tried following a few guides and it seems like I'm it correctly, obviously not though if it's not working.

I have the following header

#ifndef MENU_H_
#define MENU_H_

typedef struct student{
    int gpa;
    float tuitionFees;
    int numCourses;
}student;

typedef struct employee{
    float salary;
    int serviceYears;
    int level;
}employee;

typedef struct person{
    char firstName[20];
    char familyName[20];
    char telephoneNum[10];
    int type; // 0 = student / 1 = employee;
    union{
        employee e;
        student s;
    };
}newPerson;

#endif

And then this is what I'm having trouble with

newPerson person[MAX_PERSONS];
person[1] = {"geo", "dude", "6136544565", 0, {3, 2353, 234}};

when I try to initialize person[1], I get the following error

error: expected expression before ‘{’ token

I was wondering what the cause of this might be? Does not seem like I'm missing a brace, I also tried to remove the inner braces but it still does not work. Any help would be very much appreciated. Thank you

3
  • 1
    The error message is related to the first open brace, not the nested one: You can use the {...} syntax only in initialisation, but person[1] = ... is an assignment, even if it initialises the entry. You could use compound literals, however. Commented Feb 22, 2015 at 7:57
  • Unrelated to your question, but your telephone number overflows the storage of 10 chars, because it adds a null char at the end. Commented Feb 22, 2015 at 7:57
  • Designated initialisers in C99 should help you to specify which member of a union you want to initialise. Commented Feb 22, 2015 at 7:59

1 Answer 1

5

The error message refers to the first open brace. You can initialise an object with the curly-brace syntax, but you cannot assign it. In other words, this works:

int array[3] = {0, 8, 15};

but this doesn't:

array = {7, 8, 9};

C99 introduced compound literals, which look like a combination of type cast and initialiser, e.g.:

int *array;

array = (int[3]){ 1, 2, 3 };

C99 also introduced designated initialises, where you can specify an array index or a struct or ´union` field you want to initialise:

int array[3] = {[2] = -1};        // {0, 0, -1}
employee e = {.level = 2};        // {0.0, 0, 3}

If we apply these features to your problem, we get something like:

enum {
    STUDENT, EMPLOYEE
};

typedef struct student{
    int gpa;
    float tuitionFees;
    int numCourses;
} student;

typedef struct employee{
    float salary;
    int serviceYears;
    int level;
} employee;

typedef struct person{
    char firstName[20];
    char familyName[20];
    char telephoneNum[10];
    int type;
    union {
        employee e;
        student s;
    } data;
} person;

int main()
{
    person p[3];

    p[0] = (person) {
        "Alice", "Atkins", "555-0543", STUDENT,
        .data = { .s = { 20, 1234.50, 3 }}
    };

    p[1] = (person) {
        "Bob", "Burton", "555-8742", EMPLOYEE,
        .data = { .e = { 2000.15, 3, 2 }}
    };    

    return 0;
}

I have introduced a name for the union, so that I can refer to it in the initialiser.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this helped me a lot. Was having trouble understanding how to apply the designated initializers to my struct.
@alk: Yes, it must be an initialiser, of course. Will correct that.

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.