On 06/10/2012 07:00 PM, Artur Skawina wrote:
On 06/10/12 18:02, Timon Gehr wrote:
On 06/10/2012 04:54 PM, Artur Skawina wrote:
...
An array literal is a dynamic array with a known constant length that
implicitly converts to a static array of the same size and element type.
That's a sane definition,

It is not. It does not specify if/when allocations take place, for example.

Implementation details. Would you like to forbid "unnecessary" allocations?
Not doing this should be harmless as it only affects performance,

Wrong.

class S{
    ~this() {
        int[3] a = [1,2,3];
    }
}


but maybe
the hidden heap allocations should indeed be disallowed. Any decent compiler
won't be emitting them anyway.

and AFAICT this is how it's currently handled.


It is not.

void main(){
     int[0] x = [1];
}

Try running that, in non-release mode. :)


(I never post valid D code that I haven't run.)

The fact that the compiler accepts it even in the cases where it should
be able to statically figure out that it will fail at runtime isn't ideal,
but this is just a quality of implementation issue.


It is a bug. A static type system is pointless if it is not used for validating certain code properties.


The
other place that this causes problems is templated functions. e.g.

void func(A)(A array)
       if(isStaticArray!A)
{}

func([1, 2, 3, 4, 5]);

will fail to compile. You're forced to create one on the stack first.

int[5] array = [1, 2, 3, 4, 5];
func(array);


func(cast(int[5])[1,2,3,4,5]);

That _might_ merit adding a syntax for indicating that an array
literal is
static.

I wasn't kidding about overloading 'static' for this; it would certainly
be better that inventing yet another literal syntax.


Using 'static' is "inventing yet another literal syntax" as well.

In a way - yes. But i think "static[...]" would be much better than "[...]S".


Obviously, none is much better than the other.

...

The isStaticArray!A problem is partially related to how the compiler handles
arrays.

     auto f(T)(T a) { enum l = a.length; return l; }

works with

     int[3] a = [1,2,3];
     f(a);

but fails with

     f([1,2,3]);

And cases like

     auto f(E)(E[] a) { enum l = a.length; return l; }

don't work at all.

Making these things work, which should be possible,

f([1,2,3]);               // f!(int[])
f([1,2,3,4]);             // f!(int[])

int[3] a = [1,2,3];
f(a);                     // f!(int[3])
f(cast(int[3])[1,2,3]);   // f!(int[3])
f(cast(int[4])[1,2,3,4]); // f!(int[4])

I'm not sure what your point is here.

A statically known length cannot be different in two identical instantiations.

Mine is that 'length' is
known in all these cases at compile time. Yet it's only possible
to retrieve it when the argument is a real static array. It should
also be possible when the function is called with a literal.

That is a case for introducing a dedicated static array literal syntax, not for butchering the template instantiation semantics. (if at all)

Yes,
it's just for templates and would need (hidden) specialization/cloning.
Which sounds worse than it is - because it can happen after inlining.


It sounds bad because it is bad.


would help when dealing
with static arrays, and also allow more optimization opportunities.

I don't see it helping optimization.

See above.

artur

The optimizer can inline the call and use the additional information gained without language changes.

What you want to achieve is better left to macros.

Reply via email to