3
#include <stdio.h>

int main()
{
    typedef struct s
    {
        int a;
        int b[5];
        char c[2];
    }st;

    st vs[1];

    vs[0] = {1,{1,2,3,4,5},{'c','d'}};

    printf("%d:a\n",vs[1].a);
    printf("%d:b[0]\t %d:b[4]\n",vs[0].b[0],vs[0].b[4]);
    printf("%c:c[0]\t %c:c[1]\n",vs[0].c[0],vs[0].c[1]);

    return 0;
}

why does this doesn't work?

on

gcc -o main *.c 

I get this error

main.c: In function 'main': main.c:15:12: error: expected expression before '{' token vs[0] ={1,{1,2,3,4,5},{'c','d'}};

But if I have this:

#include <stdio.h>

int main()
{
    typedef struct s
    {
        int a;
        int b[5];
        char c[2];
    }st;

    st vs[] = {
                {1,{1,2,3,4,5},{'c','d'}}
              };

    printf("%d:a\n",vs[0].a);
    printf("%d:b[0]\t %d:b[4]\n",vs[0].b[0],vs[0].b[4]);
    printf("%c:c[0]\t %c:c[1]\n",vs[0].c[0],vs[0].c[1]);

    return 0;
}

it works. What is the logic in this.

How can I make it work using st vs[1] method?

2 Answers 2

8

You can only do braced initialization when you declare a variable. So,

st vs[] = {
            {1,{1,2,3,4,5},{'c','d'}}
          };

is allowed. But

vs[0] = {1,{1,2,3,4,5},{'c','d'}};

is not. Because this is not a initialization but assignment.

However, you can use C99's compound literal, see C11, 6.5.2.5:

vs[0] = (struct s){1,{1,2,3,4,5},{'c','d'}};
Sign up to request clarification or add additional context in comments.

Comments

3

Initialization is when you declare a variable and provide initial values for it as part of the declaration. For example this is legal:

st vs[1] = { {1,{1,2,3,4,5},{'c','d'}} };

Your code is actually attempting assignment. Assignment is when an existing variable has a value assigned to it. The reason your code doesn't work is that {1,{1,2,3,4,5},{'c','d'}} isn't a value.

In a statement (not a declaration), each expression must be readable by the compiler on its own merit, and a more complicated statement is made up of various expressions joined by operators. So the compiler doesn't know what to do with {1,{1,2,3,4,5},{'c','d'}} - at this stage it has no idea that that is supposed to be a st.

Since C99 there is a new language construct you can use here, called compound literal:

vs[0] = (const st){1,{1,2,3,4,5},{'c','d'}};

Note that this is not a cast operator being applied to some sort of braced expression; it is a single syntactic construct (Typename){ initializers } .

My use of const is a micro-optimization, it may help the compiler store the literal in a read-only block of the executable and allow constant folding.

Comments

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.