31

Suppose I have a fully defined struct with tag MyStruct, and suppose that x, y, ..., z are allowed values for its fields. Why is

struct MyStruct q = {x,y,..,z};

allowed, but

struct MyStruct q;
q = {x,y,...,z};

is not allowed? I find this very annoying. In the second case, where I have previously declared q, I need to assign a value to each field, one by one:

q.X = x; q.Y = y; ... q.Z = z;

where X, Y, ..., Z are the fields of MyStruct. Is there a reason behind this?

VendettaDroid
  • 3,131
  • 2
  • 28
  • 41
a06e
  • 18,594
  • 33
  • 93
  • 169
  • rvalue of the assignment isn't concrete and its in runtime. the initial assignment is concrete however and available in binary (most probable in .BSS section if this is an elf file). if you want to assign structs to each other, you can assign q to something initialised. like; struct MyStruct w = {x,y,..,z}; q = w – sardok Aug 30 '12 at 04:06

2 Answers2

48

What you are looking for is a compound literal. This was added to the language in C99.

Your first case:

struct MyStruct q = {x,y,..,z};

is a syntax specific to initialization. Your second case, in the pedantics of the language is not initialization, but assignment. The right hand side of the assignment has to be a struct of the correct type. Prior to C99 there was no syntax in the language to write a struct literal, which is what you are trying to do. {x,y,..,z} looked like a block with an expression inside. If one were inspired to try to think of it as a literal value, though the language didn't, one couldn't be sure of its type. (In your context, you could make a good guess.)

To allow this and resolve the type issue, C99 added syntax so you could write:

q = (struct MyStruct){x,y,...,z};
Avi Berger
  • 2,068
  • 1
  • 18
  • 13
  • 5
    +1 for specifying that it is C99. Didn't know this was possible which is probably since we have to work with old compilers. – Leo Aug 30 '12 at 06:00
27

You can do this, but you need to supply the type of the structure before your aggregate:

struct MyStruct q;
q = (struct MyStruct){x,y,...,z};
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    But only in C99 (see Avi Berger's answer) – AAT Aug 30 '12 at 07:49
  • 1
    @AAT You are correct, it's a feature that has been added in C99. However, since C99 has been around for more than a decade, it has pretty much become synonymous with C in many contexts. – Sergey Kalinichenko Aug 30 '12 at 12:22
  • @AAT It doesn't work. I am using Visual Studio 2010, Windows. I get a syntax error and it won't compile. I'd expect Visual Studio to support the latest standards. I must be missing a setting somewhere, or something. Any ideas? Perhaps I should open a new question with this issue? – a06e Aug 30 '12 at 22:59
  • 4
    @becko: your expectations are way too high... MS tools rarely use latest standards. – Karoly Horvath Aug 30 '12 at 23:04
  • Damn... you're right. I just found this: http://stackoverflow.com/q/146381/855050. After googling a little it seems that MS has no plans to support C99 nor C11. – a06e Aug 30 '12 at 23:43