Jump to page: 1 2
Thread overview
[Issue 11346] New: [2.064 beta] field initializing not allowed in loops or after labels
Oct 25, 2013
Kenji Hara
Oct 25, 2013
Kenji Hara
Oct 25, 2013
Kenji Hara
Oct 25, 2013
Kenji Hara
Oct 25, 2013
Kenji Hara
October 24, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346

           Summary: [2.064 beta] field initializing not allowed in loops
                    or after labels
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: rswhite4@googlemail.com


--- Comment #0 from rswhite4@googlemail.com 2013-10-24 14:00:25 PDT ---
Code:
----
import std.stdio;

struct Test {
public:
    const int[] test;

    this(int i) {
        for (size_t j = 0; j < 4; ++j) {
            this.test ~= i + j;
        }
    }
}

void main() {
    Test t = Test(42);
}
----

Error: field test initializing not allowed in loops or after labels

WTF?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-24 17:24:38 PDT ---
(In reply to comment #0)
> Code:
> ----
> import std.stdio;
> 
> struct Test {
> public:
>     const int[] test;
> 
>     this(int i) {
>         for (size_t j = 0; j < 4; ++j) {
>             this.test ~= i + j;
>         }
>     }
> }
> 
> void main() {
>     Test t = Test(42);
> }
> ----
> 
> Error: field test initializing not allowed in loops or after labels
> 
> WTF?

It's intended behavior change introduced by fixing bug 9665. Possible code fix is:

    this(int i) {
        int[] tmp;
        for (size_t j = 0; j < 4; ++j) {
            tmp ~= i + j;
        }
        this.test = tmp;  // initialize non-mutable field only once
    }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #2 from rswhite4@googlemail.com 2013-10-24 23:54:24 PDT ---
That is so non intuitive. A good example how you can make simple code more complicated. I will wait for the threads in D.learn or possible bug reports for that...

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-25 00:10:47 PDT ---
(In reply to comment #2)
> That is so non intuitive. A good example how you can make simple code more complicated. I will wait for the threads in D.learn or possible bug reports for that...

If multiple initialization for non-mutable field is allowed, it could break type system. For example:

struct S {
    const int[] arr;
    this(immutable int[] a) {
        arr = a;     // First initialization
        arr[0] = 1;  // Second initialization - modify immutable data!
    }
}

Therefore, it's necessary limitation.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #4 from rswhite4@googlemail.com 2013-10-25 00:13:09 PDT ---
So it was a "bug" in 2.063.2 and will never change?
It's a real _ugly _ restriction and I'm sure that many newbies don't understand
that. But thanks for explanation.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #5 from rswhite4@googlemail.com 2013-10-25 00:41:49 PDT ---
BTW: Your example was an index assignment. Such things could be detected and therefore distinguished of "normal" assignments. Multiple assignments (as I showed in my two bug reports) for an array or an assocaitve array should be possible in the CTor.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #6 from rswhite4@googlemail.com 2013-10-25 00:50:39 PDT ---
To describe my viewpoint somewhat closer:

----
if (Primitive.Target.Vertex & trg)
    this._targetIds[Primitive.Target.Vertex] = ids++; [1]
if (Primitive.Target.Color & trg)
    this._targetIds[Primitive.Target.Color] = ids++; [2]
if (Primitive.Target.TexCoords & trg)
    this._targetIds[Primitive.Target.TexCoords] = ids++; [2]
----

[1] is allowed because the compiler things, that is the first assignment for
_targetIds. But that is _no_ real assignment.
A real assigment would be something like that: this._targetIds = ...;
It is an index assignment, so the AA is probably not fully initialized.

[2] and [3] are rejected, because the compiler thinks, that this are multiple assignments. But that is plain worng. That are also index assignments to initialize my AA.

Same thing for normal arrays.
A assignment would be arr = [1, 2, 3];
But the operator ~= is a concatenation to initialize my array.

IMO we should distinguish this. That would retain your type safety and get rid of the annoying limitation.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #7 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-25 01:00:14 PDT ---
(In reply to comment #4)
> So it was a "bug" in 2.063.2 and will never change?
> It's a real _ugly _ restriction and I'm sure that many newbies don't understand
> that. But thanks for explanation.

Yes. Unfortunately that was a long-standing hole in the type system.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #8 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-25 01:29:24 PDT ---
(In reply to comment #6)
> To describe my viewpoint somewhat closer:
[snip]

Unfortunately, AA indexing access and array concatenation also have the possibility of type system breaking.

struct S {
    immutable int[] arr;
    this(immutable int[] a) {
        arr = a;
        assert(arr.capacity > 0);
        // emulate `arr ~= 10;`
        (* cast(int[]*) &arr) ~= 10;
    }
}
void main() {
    immutable int[] arr = [1,2,3];

    immutable int[] a = arr[0..2];
    assumeSafeAppend(a);
    assert(a.capacity > 0);
    auto s = S(a);

    import std.stdio;
    writeln(arr);   // prints [1,2,10]
}

It's arbitrary example, but under the @system code, concatenation may break type system without explicit casting.

The AA case is more easy. If you access the AA by the same key twice, you will mutate once initialized non-mutable data.

struct S {
    immutable int[string] aa;
    this(int n) {
        aa["str"] = n;
        aa["str"] = n;  // multiple initialization
    }
}

Compiler cannot detect above case without extra runtime cost.

Keep the rule for "initialization inside constructor" simple, I think the current behavior is enough acceptable.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 25, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11346



--- Comment #9 from rswhite4@googlemail.com 2013-10-25 01:32:01 PDT ---
I still hate it, but ok, that means for me: no more const for arrays and AA's. Thanks for your time.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2