June 04, 2013
On Monday, 3 June 2013 at 09:06:25 UTC, Don wrote:
> DMD has always accepted this initializer syntax for static arrays:
>
> float [50] x = 1.0;

I would expect block initialization and have never considered first element initialization.
June 04, 2013
On Tuesday, 4 June 2013 at 02:33:54 UTC, Kenji Hara wrote:
>> Personally I'd like to just use block-init everywhere. I personally find
>> first-element-init rather unexpected, but maybe that's just me. I don't
>> know when it would be useful. But regardless, we need to get this sorted
>> out.
>> It's a blocker for my CTFE work.
>>
>
> First-element-init is definitely a bug. I can argue that nobody wants the
> strange behavior.

Good, it seems that everyone agrees. It's therefore a bug in todt.c, StructInitializer::todt()


>> void main()
>> {
>>    int [3][4] w = 7;
>>    assert( w[2][2] == 7); // Passes, it was block-initialized
>>
>
> Currently block-initialization for multi-dimensional static array is just
> only allowed for variable declaration in statement scope.
> I'm planning to fix bug 3849 and 7019, but changing this behavior might
> affect them. As my hope, I'd like to keep this as-is so I've not finished
> thinking about it well.

Yeah, there's difficulties with things like:

int [3][4] = [7, 7, 7];

which could be a block initialization -- is this allowed or not?

Though I think we have already dealt with such issues for block assignment.

>    S s =  { 8 }; // OK, struct static initializer. first-element-init
>>
>
> This is definitely a bug. Instead, block-init should occur.

Good.

>
>
>>    S r = S( 8 ); // OK, struct literal, block-init.
>>    T t;          // Default initialized, block-init
>>
>
> OK.
>
>
>>    assert( s.x[2] == 8); // Fails; it was first-element-initialized
>>
>
> Also, definitely a bug.
>
>
>>    assert( r.x[2] == 8); // Passes; all elements are 8. Block-init.
>>    assert( t.x[2] == 8); // Passes; all elements are 8. Block-init.
>>
>
> OK.
>
>
>>    U u = { 9 };  // Does not compile
>>    // Error: cannot implicitly convert expression (9) of type int to
>> int[3LU][3LU]
>>
>
> For reasons I've already mentioned in `int [3][4] w = 7;`, I'd like to keep
> this current behavior.

There is still one problem, bug 10198. This currently compiles, and does something stupid:
---
struct U {
   int [3][3] y;
}

U u = U(4);
---
What do you think should happen here?
June 04, 2013
Don:

> Yeah, there's difficulties with things like:
>
> int [3][4] = [7, 7, 7];
>
> which could be a block initialization -- is this allowed or not?

I hope it keeps being disallowed, to avoid programmer's mistakes.

(Maybe this is acceptable: int [3][4] = [7, 7, 7][]; )

Bye,
bearophile
June 04, 2013
2013/6/4 Don <turnyourkidsintocash@nospam.com>

>
> There is still one problem, bug 10198. This currently compiles, and does something stupid:
> ---
>
> struct U {
>    int [3][3] y;
> }
>
> U u = U(4);
> ---
> What do you think should happen here?
>

Oh! I did not know it is currently accepted.

I think accepting multi-dimensional block initializing on StructLiteralExp
arguments is very bug-prone behavior.
Different from variable declaration in statement scope, there is no target
type we can look for. So inferring the cost of static array construction is
difficult.

struct U { int[3][3][3][3] w; }
U u = U(1);    // looks trivial, but actually costly operation.

int[3][3][3][3] w = 1;   // initializing cost is very obvious

At most it would be better that it is restricted up to one-dimensional block initializing, same as StructInitializer.

Kenji Hara


June 04, 2013
Sometimes I'd like to write code like this:


struct Foo {
    int x;
}
void main() {
    Foo[100] foos;
    foos[].x = 10;
}


Bye,
bearophile
1 2
Next ›   Last »