This program shows that you are allowed to initialize a single const char inside static this() and struct constructor, but you are not allowed to initialize the items of a char array: const char gc; const char[1] ga; static this() { gc = 'a'; // OK ga[0] = 'a'; // line 5, Err } struct Foo { const char cc; const char[1] array; this(char c) { cc = c; // OK array = [c]; // line 12, Err array[0] = c; // line 12, Err } } void main() {} DMD 2.053: temp.d(5): Error: ga[0] isn't mutable temp.d(12): Error: slice this.array[] is not mutable temp.d(13): Error: this.array[0] isn't mutable I'd like to initialize the arrays too.
This also happens without explicit slicing/indexing: immutable float[3] foo; static this() { foo = [1,2,3]; } In my actual code I need a function to initialize the array. It uses exp and thus isn't CTFEable. Hence static this would be the only to initialize this immutable.
https://github.com/D-Programming-Language/dmd/pull/166 This patch transitively checks that an expression is part of initializing.
See also a comment by Kenji Hara: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=148428 > Inside constructor, compiler can detect that this.a[n] is part of the > fields of 'this' (because static array is value type), then should > allow to bypass const type checking for assignment. > But dynamic array and associative array are reference type, then > compiler cannot detect that the elements of them (this.b[n] and > this.aa[key]) are part of 'this'. Therefore line 8 and 9 cannot bypass > const type checking, even if inside constructor, then should be > rejected. > > I have call this concept "transitively modifiable", and I have > implemented it with dmd/pull/166. > "Transitively modifiable" is only checked inside constructor, and > allow more flexible initializing. > I think this is reasonable improvement. So all this is expected to eventually compile and run: const struct Foo1 { const int[1] a; this(in int x) pure { a[0] = x; // Error } } const struct Foo2 { const int[1] a; this(in int x) pure { a = [x]; // Error } } const struct Foo3 { const int[1] a; this(in int x) pure { a[] = x; // Error } } const struct Foo4 { const int a; this(in int x) pure { a = x; // OK } } void main() {} ------------------ While this is not yet compilable: const struct Foo { const int[] a; const int[int] aa; this(in int n) pure { this.a = new int[5]; this.a[0] = n; // line 6 this.aa[1] = 2; // line 7 } } void main() {} test.d(6): Error: this.a[0] isn't mutable test.d(7): Error: this.aa[1] isn't mutable
*** Issue 6924 has been marked as a duplicate of this issue. ***
*** Issue 7882 has been marked as a duplicate of this issue. ***
https://github.com/D-Programming-Language/dmd/commit/5b42e51481d186ee5e3c2684a237a05cea33a0cf
This is an improvement of D. std.algorithm.copy can't be used to initialize const array fields, but this is not important: import std.algorithm: copy; class Foo { const int[3] bar; this() { auto data = [10, 20, 30]; foreach (i, d; data) bar[i] = d; // OK copy(data, bar[]); // error } } void main() {}
Is this expected? Do you want me to put this in a new bug report? struct Foo { int[1] bar; } const Foo[1] foos; static this() { foreach (i; 0 .. foos.length) foos[i].bar[i] = 1; // OK foreach (i, ref f; foos) f.bar[i] = 1; // Error } void main() {}
(In reply to comment #8) > Is this expected? Do you want me to put this in a new bug report? > > struct Foo { > int[1] bar; > } > const Foo[1] foos; > static this() { > foreach (i; 0 .. foos.length) > foos[i].bar[i] = 1; // OK > foreach (i, ref f; foos) > f.bar[i] = 1; // Error > } > void main() {} Hmm, it's interesting. The accessed memory through the reference 'f' would specify a part of the constructed fields, and compiler would be able to detect it in statically. Please put in a new report.
(In reply to comment #9) > Please put in a new report. OK, Issue 8783 Thank you.
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/aa33955a6ed38ab64df903b2298988f9cde42914 Clean up test cases for issue 6174 Merged similar tests by making them parameterize.
This is still failing in D1. Reopening as D1 only.
Works in D2, D1 is gone, closing.