Thread overview
struct members not default initialized?
Dec 07, 2009
Ali Cehreli
Dec 08, 2009
bearophile
Dec 08, 2009
Ali Cehreli
Dec 28, 2009
Ali Çehreli
Dec 08, 2009
Ali Cehreli
December 07, 2009
(I must be missing something here; this is such a fundamental operation and I can't find a bug report on it.)

I've been under the impression that struct members would always be initialized. Having seen D an init-happy language compared to C and C++, that's what I would have expected. :)

Shouldn't the members of s be int.init and double.init below?

struct S
{
    int i;
    double d;
}

void main()
{
    S s;
}

They are not; at least for dmd versions from 2.034 to 2.037.

Also, leaving out some of the initializers do not init the corresponding members either:

    S s = { 42 };

There, s.d is not double.init.

And static initializers don't help either:

struct S
{
    int i     = 1;
    double d  = 2.3;
}

Again, s.d is not initialized:

    S s = { 42 };

Is the above expected? (Not by me... :) )

Ali
December 08, 2009
This prints 42 0.000000 with the latest dmd2 and 42 nan with an older dmd1. It can be a bug:

import std.c.stdio: printf;

struct S {
    int i;
    double d;
}

void main() {
    S s = { 42 };
    printf("%d %f\n", s.i, s.d);
}

Bye,
bearophile
December 08, 2009
Ali Cehreli Wrote:

> (I must be missing something here

Yes I am! :)

> I've been under the impression that struct members would always be initialized. Having seen D an init-happy language compared to C and C++, that's what I would have expected. :)

I still think that it should be the default behavior unless no-initialization was specifically requested, like the case for uninitialized arrays.

> struct S
> {
>     int i;
>     double d;
> }
[...]
> Also, leaving out some of the initializers do not init the corresponding members either:
> 
>     S s = { 42 };
> 
> There, s.d is not double.init.

The spec says "Members not specified in the initializer list are default initialized" for *static* objects. So this works:

    static S s = { 42 };
    dout.writefln(s.d);       // prints nan

This check fails though:

    assert(s.d == double.nan);

and it is probably not meant to work anyway; because I see that the spec at

    http://www.digitalmars.com/d/2.0/float.html

has this to say (probably recently modified):

   x == x → true 	not valid if x is a NaN

> struct S
> {
>     int i     = 1;
>     double d  = 2.3;
> }
> 

>     S s = { 42 };

Good: That does set s.d... :)

Ali

December 08, 2009
bearophile Wrote:

> This prints 42 0.000000 with the latest dmd2 and 42 nan with an older dmd1. It can be a bug:

It prints garbage here with 2.037. :/

As I've responded to my own post :), I think the initialization is meant only for static objects.

> 
> import std.c.stdio: printf;
> 
> struct S {
>     int i;
>     double d;
> }
> 
> void main() {
>     S s = { 42 };
>     printf("%d %f\n", s.i, s.d);
> }
> 
> Bye,
> bearophile

Ali

December 28, 2009
bearophile wrote:
> This prints 42 0.000000 with the latest dmd2 and 42 nan with an older dmd1.

You are unlucky then... ;) The following program leaves random values in s.d with dmd 2.037. Here is one output:

42 -0.008821

> It can be a bug:

Yes it is! :)

  http://d.puremagic.com/issues/show_bug.cgi?id=2485

Sorry for not finding it earlier; and thanks for you help.

> import std.c.stdio: printf;
>
> struct S {
>     int i;
>     double d;
> }
>
> void main() {
>     S s = { 42 };
>     printf("%d %f\n", s.i, s.d);
> }
>
> Bye,
> bearophile

Ali