View mode: basic / threaded / horizontal-split · Log in · Help
December 01, 2012
struct initialization and assignment by field name
I'm just starting out with D, and am wondering about some differences 
with C regarding struct literals. In C99, I can do this:

struct MyStruct {
   int  number;
   char letter;
};

int main() {
   static struct MyStruct foo = { .number = 42, .letter = 'a' };
   struct MyStruct bar = { .number = 42, .letter = 'a' };
   bar = (struct MyStruct) { .number = 42, .letter = 'a' };
   return 0;
}

That is, I can initialize static and non-static struct variables by 
specifying the fields as key-value pairs.  I can also assign a struct 
literal to an already-declared struct variable in the same way.

If we try this in D:

struct MyStruct {
   int  number;
   char letter;
}

int main() {
   static MyStruct foo = { number:42, letter:'a' }; // works
   MyStruct bar = { number:42, letter:'a' };        // works despite [1]
   bar = { number:42, letter:'a' };                 // fails to compile
   return 0;
}

That is, I can do something similar for static struct initializers in D, 
and non-static struct initializers despite this being documented as not 
allowed.

It appears that this form of struct literal really can only be used in 
initializers -- the assignment to a previously declared varaible fails to 
compile.

I'm hoping somebody can shed some light on the rationale for only 
supporting this form of struct literal in initializers. And also why it's 
documented to only work for static initializers -- is this an error in 
the documentation, or is the compiler allowing things it shouldn't?

Thanks,
Bobby

1. http://dlang.org/struct.html
  "The sta­tic ini­tial­izer syn­tax can also be used to ini­tial­ize non-
   static vari­ables, pro­vided that the mem­ber names are not given."
December 01, 2012
Re: struct initialization and assignment by field name
Bobby Bingham:

> It appears that this form of struct literal really can only be 
> used in initializers -- the assignment to a previously declared 
> varaible fails to compile.

Right. That syntax is not much used in D, there were discussions 
about deprecating it fully, I don't know the current status. I 
use it sometimes when I have to initialize an array of many 
structs.


> I'm hoping somebody can shed some light on the rationale for 
> only supporting this form of struct literal in initializers.

I don't know the rationale. There are tons of things I don't know 
the rationale of, despite my efforts to learn.

The normal way to write a struct literal in D is this, that works 
in most cases:

auto foo = MyStruct(42, 'a');


> And also why it's documented to only work for static
> initializers -- is this an error in the documentation,
> or is the compiler allowing things it shouldn't?

It's another little mystery :-) Maybe the DMD compiler used to 
allow that, and then specs were updated and the compiler remained 
unchanged, or the specs where like that since the beginning, but 
the compiler was closer to a C99 one and allowed it. Or maybe 
it's just a compiler bug that allows something that is not 
allowed. Maybe it's Bugzilla worth.

Bye,
bearophile
December 01, 2012
Re: struct initialization and assignment by field name
On Saturday, 1 December 2012 at 19:32:27 UTC, bearophile wrote:
> I don't know the rationale. There are tons of things I don't 
> know the rationale of, despite my efforts to learn.
>
> The normal way to write a struct literal in D is this, that 
> works in most cases:
>
> auto foo = MyStruct(42, 'a');
>
>
>> And also why it's documented to only work for static
>> initializers -- is this an error in the documentation,
>> or is the compiler allowing things it shouldn't?
>
> It's another little mystery :-) Maybe the DMD compiler used to 
> allow that, and then specs were updated and the compiler 
> remained unchanged, or the specs where like that since the 
> beginning, but the compiler was closer to a C99 one and allowed 
> it. Or maybe it's just a compiler bug that allows something 
> that is not allowed. Maybe it's Bugzilla worth.
>
> Bye,
> bearophile

I'm starting to look into this kind of thing now, although I ave 
not used struct initializations like that yet for real code, just 
for my tinkering.

In my case I've been fully relying on constructors and 
initializers, and that seems to be working very well for me, with 
no reason to change.

If you want to perform initializations like that, there is one 
advantage of specifying the field name:

If the struct fields are reordered, then that will not require 
changes elsewhere, also for example, if you reorder two ints, the 
code will compile, but will create difficult to detect errors 
when run.

struct X{
int a, b;
}

X x = { a: 12, b: 13 }

------

struct X{
int b, a;
}

X x = { 12, 13 }

Personally, I think you are far better off using constructors, 
overloaded opAssign and so forth.

Now if you really want to dive into the weirdness of D, then have 
a look at tuples. Using a tuple, you can perform similar named 
initializations, and more, but it's far too weird and messy for 
me to make real use out of, i.e., it is in dire need of a 
re-think and redesign to make it a clean generalized concept that 
fits in consistently with the other components of the language.

--rt
Top | Discussion index | About this forum | D home