February 11, 2018 Re: Fixed size array initialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to rumbu | On Sat, 10 Feb 2018 10:55:30 +0000, rumbu wrote: > I know that according to language spec (https://dlang.org/spec/arrays.html#static-init-static) you can skip declaring all your elements in a fixed size array. > > I'm just recovering from a bug which took me one day to discover because of this. > > I have a large static initialized array, let's say int[155], and I forgot to declare the last element: > > int[155] myarray = [ > a, > b, > c, > ... > //forgot to declare the 155th element > ]; > > I took for granted that the compiler will warn me about the fact that my number of elements doesn't match the array declaration but I was wrong. > > Does it worth to fill an enhancement on this, or this is intended behavior? If you separate initialization to a static this, you'll get a compile error: ``` immutable uint256[78] pow10_256; static this() { // Error: mismatched array lengths, 78 and 2 pow10_256 = [ uint256(1UL), uint256(10UL) ]; } ``` Or if you know that no element should be the object's init value, you could do a static foreach to validate that at compile-time. You could also generate the elements at compile-time (this could use some improvement, and should be generalized so a single function can generate fillers for your other arrays as well): ``` immutable uint256[78] pow10_256; static this() { // Uncomment this to view the generated code. Helpful for debugging. //pragma(msg, GenPow10_256Initializer); mixin(GenPow10_256Initializer); } static string GenPow10_256Initializer() { import std.range : repeat; import std.conv : text; string code = "pow10_256 = [\n"; foreach(i; 0..78) { code ~= ` uint256("1` ~ '0'.repeat(i).text ~ `")` ~ ",\n"; } code = code[0..$-2]; // Remove trailing comma. code ~= "\n];"; return code; } ``` |
February 11, 2018 Re: Fixed size array initialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to rjframe | On Sunday, 11 February 2018 at 14:06:32 UTC, rjframe wrote: > On Sat, 10 Feb 2018 10:55:30 +0000, rumbu wrote: > > If you separate initialization to a static this, you'll get a compile error: > > ``` > immutable uint256[78] pow10_256; > > static this() { > // Error: mismatched array lengths, 78 and 2 > pow10_256 = [ > uint256(1UL), > uint256(10UL) > ]; > } > ``` Yes, this was in fact the idea of https://github.com/dlang/phobos/pull/4936 Didn't like it, sorry. > > Or if you know that no element should be the object's init value, you could do a static foreach to validate that at compile-time. Nice idea too, but this will significantly increase compilation time. > > You could also generate the elements at compile-time (this could use some improvement, and should be generalized so a single function can generate fillers for your other arrays as well): > > ``` > immutable uint256[78] pow10_256; > > static this() { > // Uncomment this to view the generated code. Helpful for debugging. > //pragma(msg, GenPow10_256Initializer); > mixin(GenPow10_256Initializer); > } > > static string GenPow10_256Initializer() { > import std.range : repeat; > import std.conv : text; > > string code = "pow10_256 = [\n"; > foreach(i; 0..78) { > code ~= ` uint256("1` ~ '0'.repeat(i).text ~ `")` ~ ",\n"; > } > code = code[0..$-2]; // Remove trailing comma. > code ~= "\n];"; > return code; > } > ``` As I said in my previous comments, this was the initial approach for all the arrays there (I'm a very lazy person, believe me) but the compiler complained with a nice "Out of memory" error, that's why I ended writing the array elements by hand. |
Copyright © 1999-2021 by the D Language Foundation