inferred size for static array initialization

2016-05-02 Thread Erik Smith via Digitalmars-d-learn
Is there a way to initialize a static array and have it's size 
inferred (and that works for arrays of structs using braced 
literals)?  This would make it easier to maintain longer static 
array definitions.  The code below doesn't work when removing the 
array size even though the array is declared as static immutable.


import std.traits;
static immutable int[] a  = [1,2,3];
static assert(isStaticArray!(typeof(a)));  // fails



Re: inferred size for static array initialization

2016-10-18 Thread Nordlöw via Digitalmars-d-learn

On Monday, 2 May 2016 at 17:43:56 UTC, Namespace wrote:

immutable auto a  = [1,2,3].s;


Will that have zero run-time overhead compared to:

immutable int[3] a = [1,2,3];

?


Re: inferred size for static array initialization

2016-10-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/18/16 6:35 AM, Nordlöw wrote:

On Monday, 2 May 2016 at 17:43:56 UTC, Namespace wrote:

immutable auto a  = [1,2,3].s;


Will that have zero run-time overhead compared to:

immutable int[3] a = [1,2,3];


Neither will have zero runtime overhead, but use the disassembler to see 
if there is a difference. My understanding is that while the compiler 
used to allocate whenever it saw an array literal (including your above 
usage), that is no longer the case.


-Steve


Re: inferred size for static array initialization

2016-10-18 Thread Namespace via Digitalmars-d-learn

On Tuesday, 18 October 2016 at 10:35:44 UTC, Nordlöw wrote:

On Monday, 2 May 2016 at 17:43:56 UTC, Namespace wrote:

immutable auto a  = [1,2,3].s;


Will that have zero run-time overhead compared to:

immutable int[3] a = [1,2,3];

?


I'm not quite sure if pragma(inline, true) would result in zero 
runtime overhead, but without you have 3 lines of assembler more 
(with gdc).


https://godbolt.org/g/JUjP1d
https://godbolt.org/g/qaqylp


Re: inferred size for static array initialization

2016-05-02 Thread Basile B via Digitalmars-d-learn

On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:
Is there a way to initialize a static array and have it's size 
inferred (and that works for arrays of structs using braced 
literals)?  This would make it easier to maintain longer static 
array definitions.  The code below doesn't work when removing 
the array size even though the array is declared as static 
immutable.


import std.traits;
static immutable int[] a  = [1,2,3];
static assert(isStaticArray!(typeof(a)));  // fails


Help yourself with a template:


import std.traits;

auto toStaticArray(alias array)()
if (isArray!(typeof(array)))
{
enum size = array.length;
alias T = typeof(array.init[0])[size];
T result = array[0..size];
return result;
}

enum a = toStaticArray!([1,2,3]);
static assert(isStaticArray!(typeof(a)));  // success


Does it fit ?


Re: inferred size for static array initialization

2016-05-02 Thread Basile B via Digitalmars-d-learn

On Monday, 2 May 2016 at 13:22:01 UTC, Basile B wrote:

On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:
Is there a way to initialize a static array and have it's size 
inferred (and that works for arrays of structs using braced 
literals)?  This would make it easier to maintain longer 
static array definitions.  The code below doesn't work when 
removing the array size even though the array is declared as 
static immutable.


import std.traits;
static immutable int[] a  = [1,2,3];
static assert(isStaticArray!(typeof(a)));  // fails


Help yourself with a template:


import std.traits;

auto toStaticArray(alias array)()
if (isArray!(typeof(array)))
{
enum size = array.length;
alias T = typeof(array.init[0])[size];
T result = array[0..size];
return result;
}

enum a = toStaticArray!([1,2,3]);
static assert(isStaticArray!(typeof(a)));  // success


Does it fit ?


Using an enum is probably a bit better


auto toStaticArray(alias array)()
if (isDynamicArray!(typeof(array)) && array.length)
{
alias T = typeof(array[0])[array.length];
enum T result = array[0..array.length];
return result;
}


Re: inferred size for static array initialization

2016-05-02 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 02 May 2016 13:00:27 +
schrieb Erik Smith :

> Is there a way to initialize a static array and have it's size 
> inferred (and that works for arrays of structs using braced 
> literals)?  This would make it easier to maintain longer static 
> array definitions.  The code below doesn't work when removing the 
> array size even though the array is declared as static immutable.
> 
>  import std.traits;
>  static immutable int[] a  = [1,2,3];
>  static assert(isStaticArray!(typeof(a)));  // fails
> 

Sure,

  struct S { int a, b; }

  immutable tab = { static enum S[] s = [
  {1,2},
  {3,4},
  ]; return cast(typeof(s[0])[s.length])s; }();

  static assert(isStaticArray!(typeof(tab)));  // succeeds

-- 
Marco



Re: inferred size for static array initialization

2016-05-02 Thread ag0aep6g via Digitalmars-d-learn

On 02.05.2016 15:53, Marco Leise wrote:

   immutable tab = { static enum S[] s = [


`static enum`? What kind of black magic is this?


Re: inferred size for static array initialization

2016-05-02 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 2 May 2016 18:52:11 +0200
schrieb ag0aep6g :

> On 02.05.2016 15:53, Marco Leise wrote:
> >immutable tab = { static enum S[] s = [  
> 
> `static enum`? What kind of black magic is this?

I don't know, but it works, haha.

-- 
Marco



Re: inferred size for static array initialization

2016-05-02 Thread Erik Smith via Digitalmars-d-learn
I tried to combine the two solutions (Basile with the wrapper, 
Marco with the struct initializer support) but it didn't work. 
The struct initializer is not a array literal (seems obvious 
now).   I might go with the 2nd but it's pretty heavy just to get 
the size.


Thanks.


struct S {
int a, b;
}

auto toStaticArray(alias array)()
{
struct S { int a, b; }

immutable tab = {
static enum S[] s = array;
return cast(typeof(s[0])[s.length])s;
}();
return tab;
}

enum a = toStaticArray!([{1,2},{3,4}]);  // error



Re: inferred size for static array initialization

2016-05-02 Thread Namespace via Digitalmars-d-learn

On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:
Is there a way to initialize a static array and have it's size 
inferred (and that works for arrays of structs using braced 
literals)?  This would make it easier to maintain longer static 
array definitions.  The code below doesn't work when removing 
the array size even though the array is declared as static 
immutable.


import std.traits;
static immutable int[] a  = [1,2,3];
static assert(isStaticArray!(typeof(a)));  // fails


I still like

auto s(T, size_t n)(T[n] arr) {
return arr;
}

auto arr = [1, 2, 3].s;


But of course this won't work:

int[] a  = [1,2,3].s;
static assert(isStaticArray!(typeof(a)));  // fails


Since 'a' is just a slice.

But this will work:

immutable auto a  = [1,2,3].s;



Re: inferred size for static array initialization

2016-05-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/2/16 1:43 PM, Namespace wrote:

On Monday, 2 May 2016 at 13:00:27 UTC, Erik Smith wrote:

Is there a way to initialize a static array and have it's size
inferred (and that works for arrays of structs using braced
literals)?  This would make it easier to maintain longer static array
definitions.  The code below doesn't work when removing the array size
even though the array is declared as static immutable.

import std.traits;
static immutable int[] a  = [1,2,3];
static assert(isStaticArray!(typeof(a)));  // fails


I still like

auto s(T, size_t n)(T[n] arr) {
 return arr;
}


Interesting. But there is a major problem here...



auto arr = [1, 2, 3].s;


But of course this won't work:

int[] a  = [1,2,3].s;
static assert(isStaticArray!(typeof(a)));  // fails



And this is the problem.


Since 'a' is just a slice.


A slice of a no-longer-existing temporary! Admittedly, this is not an 
issue with your code, but a deeper issue of allowing slicing of rvalues.




But this will work:

immutable auto a  = [1,2,3].s;



You can drop auto. It's just a placeholder for the storage class in the 
case where a storage class isn't specified.


-Steve


Re: inferred size for static array initialization

2016-05-02 Thread Namespace via Digitalmars-d-learn

On Monday, 2 May 2016 at 18:57:49 UTC, Namespace wrote:
A slice of a no-longer-existing temporary! Admittedly, this is 
not an issue with your code, but a deeper issue of allowing 
slicing of rvalues.

This works:

int[] as = [1, 2, 3].s;
writeln(as[2]);


Of course this slice is only valid as long as you dont leave the 
scope. That's maybe what you tried to say, right?


Re: inferred size for static array initialization

2016-05-02 Thread Namespace via Digitalmars-d-learn
A slice of a no-longer-existing temporary! Admittedly, this is 
not an issue with your code, but a deeper issue of allowing 
slicing of rvalues.

This works:

int[] as = [1, 2, 3].s;
writeln(as[2]);

Bug or feature? Or did I may misunderstood you?

You can drop auto. It's just a placeholder for the storage 
class in the case where a storage class isn't specified.

Right, I forgot, it's a bit since I wrote something in D.




Re: inferred size for static array initialization

2016-05-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/2/16 3:02 PM, Namespace wrote:

On Monday, 2 May 2016 at 18:57:49 UTC, Namespace wrote:

A slice of a no-longer-existing temporary! Admittedly, this is not an
issue with your code, but a deeper issue of allowing slicing of rvalues.

This works:

int[] as = [1, 2, 3].s;
writeln(as[2]);


Of course this slice is only valid as long as you dont leave the scope.
That's maybe what you tried to say, right?


No, because 'as' is pointing at stack space no longer allocated. It may 
work, and it may not, but having it work is not proof that it's sound.


To make things clear, this is what your code effectively does:

int[] as = void;
{
   auto _tmp = [1, 2, 3].s;
   as = _tmp;
}

Which is not the same thing as having the static array a defined stack 
variable in the same scope.


-Steve


Re: inferred size for static array initialization

2016-05-02 Thread Namespace via Digitalmars-d-learn

On Monday, 2 May 2016 at 19:08:52 UTC, Steven Schveighoffer wrote:

On 5/2/16 3:02 PM, Namespace wrote:

On Monday, 2 May 2016 at 18:57:49 UTC, Namespace wrote:
A slice of a no-longer-existing temporary! Admittedly, this 
is not an
issue with your code, but a deeper issue of allowing slicing 
of rvalues.

This works:

int[] as = [1, 2, 3].s;
writeln(as[2]);


Of course this slice is only valid as long as you dont leave 
the scope.

That's maybe what you tried to say, right?


No, because 'as' is pointing at stack space no longer 
allocated. It may work, and it may not, but having it work is 
not proof that it's sound.


To make things clear, this is what your code effectively does:

int[] as = void;
{
   auto _tmp = [1, 2, 3].s;
   as = _tmp;
}

Which is not the same thing as having the static array a 
defined stack variable in the same scope.


-Steve


The assembler looks different than that but I may be wrong and I 
only looked at gdc.
But anyway, that means with 'pragma(inline, true)' I'm save. Is 
that right?


Re: inferred size for static array initialization

2016-05-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/2/16 3:12 PM, Namespace wrote:

On Monday, 2 May 2016 at 19:08:52 UTC, Steven Schveighoffer wrote:

On 5/2/16 3:02 PM, Namespace wrote:

On Monday, 2 May 2016 at 18:57:49 UTC, Namespace wrote:

A slice of a no-longer-existing temporary! Admittedly, this is not an
issue with your code, but a deeper issue of allowing slicing of
rvalues.

This works:

int[] as = [1, 2, 3].s;
writeln(as[2]);


Of course this slice is only valid as long as you dont leave the scope.
That's maybe what you tried to say, right?


No, because 'as' is pointing at stack space no longer allocated. It
may work, and it may not, but having it work is not proof that it's
sound.

To make things clear, this is what your code effectively does:

int[] as = void;
{
   auto _tmp = [1, 2, 3].s;
   as = _tmp;
}

Which is not the same thing as having the static array a defined stack
variable in the same scope.



The assembler looks different than that but I may be wrong and I only
looked at gdc.
But anyway, that means with 'pragma(inline, true)' I'm save. Is that right?


The assembler might be safe in some instances, but that doesn't reflect 
the original internal representation in the compiler. Some other 
configuration of calls may allow the compiler to reuse that memory, and 
then you run into problems.


I'm wondering if you used my rewrite if it would actually output the 
same thing?


But in any case, I don't know the answer to the pragma(inline) thing. I 
would guess it is subject to the same issues, but I'm not 100% sure.


-Steve


Re: inferred size for static array initialization

2016-05-02 Thread Namespace via Digitalmars-d-learn
The assembler might be safe in some instances, but that doesn't 
reflect the original internal representation in the compiler. 
Some other configuration of calls may allow the compiler to 
reuse that memory, and then you run into problems.


I'm wondering if you used my rewrite if it would actually 
output the same thing?


Not quite. Look for yourself:
https://godbolt.org/g/kO8hdW
https://godbolt.org/g/KCfYPy


Re: inferred size for static array initialization

2016-05-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/2/16 3:38 PM, Namespace wrote:

The assembler might be safe in some instances, but that doesn't
reflect the original internal representation in the compiler. Some
other configuration of calls may allow the compiler to reuse that
memory, and then you run into problems.

I'm wondering if you used my rewrite if it would actually output the
same thing?


Not quite. Look for yourself:
https://godbolt.org/g/kO8hdW
https://godbolt.org/g/KCfYPy


Except for offsets, it looks identical. May be the compiler puts things 
in different spots for different ways of writing.


But the thing that's not disclosed here is: what happens when the 
compiler feels the need to reuse that stack space? Your example doesn't 
have anything that may compete for the space, it just returns after this 
is over.


For example, define a static array of exactly the same size to use after 
the call:


int[3] x;

Now, see if x is pigeonholed into that same place your temporary return 
existed (and therefore 'as' points at it).


I'm still fully on the side of this being unsafe.

-Steve


Re: inferred size for static array initialization

2016-05-02 Thread Namespace via Digitalmars-d-learn

On Monday, 2 May 2016 at 20:05:15 UTC, Steven Schveighoffer wrote:

On 5/2/16 3:38 PM, Namespace wrote:
The assembler might be safe in some instances, but that 
doesn't
reflect the original internal representation in the compiler. 
Some
other configuration of calls may allow the compiler to reuse 
that

memory, and then you run into problems.

I'm wondering if you used my rewrite if it would actually 
output the

same thing?


Not quite. Look for yourself:
https://godbolt.org/g/kO8hdW
https://godbolt.org/g/KCfYPy


Except for offsets, it looks identical. May be the compiler 
puts things in different spots for different ways of writing.


But the thing that's not disclosed here is: what happens when 
the compiler feels the need to reuse that stack space? Your 
example doesn't have anything that may compete for the space, 
it just returns after this is over.


For example, define a static array of exactly the same size to 
use after the call:


int[3] x;

Now, see if x is pigeonholed into that same place your 
temporary return existed (and therefore 'as' points at it).


I'm still fully on the side of this being unsafe.

-Steve


I used it very often, but always assigned the result to an 
auto-type variable, never to a slice.


Re: inferred size for static array initialization

2016-05-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/2/16 4:14 PM, Namespace wrote:


I used it very often, but always assigned the result to an auto-type
variable, never to a slice.


Using auto is fine, but the slice should not happen if you are assigning 
slice to a local var. There is a bug report on this: 
https://issues.dlang.org/show_bug.cgi?id=12625, though it's not as 
focused as I think it should be.


-Steve


Re: inferred size for static array initialization

2016-05-03 Thread Basile B. via Digitalmars-d-learn

On Monday, 2 May 2016 at 17:43:56 UTC, Namespace wrote:


I still like

auto s(T, size_t n)(T[n] arr) {
return arr;
}


Wooah, this trick is awesome. But actually it does the same thing 
that what I've proposed before. Exactly the same code is 
generated. So I'd say that it's rather a matter of readability.


https://godbolt.org/g/wGTs52
https://godbolt.org/g/cXECyO