www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Initialisation of static immutable arrays

reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
I have a program that uses an immutable array, the contents of which are 
known at compile time.  Thus, ideally, I want it to be placed in 
the .rodata segment of the program.

Firstly, I seem to remember reading that using an array literal in D will 
always result in a heap allocation.  Is this correct?

Secondly, if the above is not true, how can I verify that the array in 
the following piece of code isn't allocated and/or copied anew every time 
the program runs, or even worse, every time foo() is called?

  void foo()
  {
      static immutable int[3] = [1, 2, 3];
  }

I know, RTFAsm, but some help with that would be appreciated. ;)

Thirdly, intuition tells me that when the array is immutable, the 
'static' shouldn't have an effect.  But experiments (i.e. printing the 
adress of the array) indicate that it does.  Is there some reason for 
this, or is it just a shortcoming of the compiler?

-Lars
Oct 06 2010
next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Wed, 06 Oct 2010 10:16:45 +0000, Lars T. Kyllingstad wrote:

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

..should of course be static immutable int[3] a = [1, 2, 3]; -Lars
Oct 06 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad  
<public kyllingen.nospamnet> wrote:

 I have a program that uses an immutable array, the contents of which are
 known at compile time.  Thus, ideally, I want it to be placed in
 the .rodata segment of the program.

 Firstly, I seem to remember reading that using an array literal in D will
 always result in a heap allocation.  Is this correct?

Yes. There is no way to create an immutable array besides a string in read only memory. Even enums will result in array literals being created on the heap whenever you refer to them (there's a bug related to this somewhere).
 Secondly, if the above is not true, how can I verify that the array in
 the following piece of code isn't allocated and/or copied anew every time
 the program runs, or even worse, every time foo() is called?

   void foo()
   {
       static immutable int[3] = [1, 2, 3];
   }

Actually, static probably will prevent it from being created every time foo is called. I don't think there's a way to prevent it from being created every time the program is run.
 I know, RTFAsm, but some help with that would be appreciated. ;)

 Thirdly, intuition tells me that when the array is immutable, the
 'static' shouldn't have an effect.  But experiments (i.e. printing the
 adress of the array) indicate that it does.  Is there some reason for
 this, or is it just a shortcoming of the compiler?

Of course. If you realize that the expression [1,2,3] is not immutable, then it makes sense. Another example to help you think about it: void foo(int x) { immutable int[3] = [1,2,x]; } This must be run on every call of foo, because x can vary. BTW, I'm all for making array literals immutable. You can always make runtime-allocated arrays via a library function. -Steve
Oct 06 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 06 Oct 2010 15:39:48 +0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 BTW, I'm all for making array literals immutable.  You can always make  
 runtime-allocated arrays via a library function.

 -Steve

I second that!
Oct 06 2010
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote:

 On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad
 <public kyllingen.nospamnet> wrote:
 
 [...]
 
 Secondly, if the above is not true, how can I verify that the array in
 the following piece of code isn't allocated and/or copied anew every
 time the program runs, or even worse, every time foo() is called?

   void foo()
   {
       static immutable int[3] = [1, 2, 3];
   }

Actually, static probably will prevent it from being created every time foo is called. I don't think there's a way to prevent it from being created every time the program is run.

Does anyone know a way to verify this? (If it is in fact created every time the function runs, I'll change it to a module-level array initialised in a 'static this()' instead.)
 I know, RTFAsm, but some help with that would be appreciated. ;)

 Thirdly, intuition tells me that when the array is immutable, the
 'static' shouldn't have an effect.  But experiments (i.e. printing the
 adress of the array) indicate that it does.  Is there some reason for
 this, or is it just a shortcoming of the compiler?

Of course. If you realize that the expression [1,2,3] is not immutable, then it makes sense. Another example to help you think about it: void foo(int x) { immutable int[3] = [1,2,x]; } This must be run on every call of foo, because x can vary.

I don't think that is a very good reason. The compiler could detect the special (and, might I add, common) case where an array literal whose contents are known at compile time is assigned to an immutable variable, and treat it as immutable even though [1,2,3] is formally of type int[].
 BTW, I'm all for making array literals immutable.  You can always make
 runtime-allocated arrays via a library function.

I completely agree. -Lars
Oct 06 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 06 Oct 2010 16:21:08 +0400, Lars T. Kyllingstad  
<public kyllingen.nospamnet> wrote:

 On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote:

 On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad
 <public kyllingen.nospamnet> wrote:

 [...]

 Secondly, if the above is not true, how can I verify that the array in
 the following piece of code isn't allocated and/or copied anew every
 time the program runs, or even worse, every time foo() is called?

   void foo()
   {
       static immutable int[3] = [1, 2, 3];
   }

Actually, static probably will prevent it from being created every time foo is called. I don't think there's a way to prevent it from being created every time the program is run.

Does anyone know a way to verify this? (If it is in fact created every time the function runs, I'll change it to a module-level array initialised in a 'static this()' instead.)

It's static so it allocates only once. But the following: immutable int[3] = [1, 2, 3]; always allocates, but I see no reason why it should.
Oct 06 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 06 Oct 2010 08:21:08 -0400, Lars T. Kyllingstad  
<public kyllingen.nospamnet> wrote:

 On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote:
 Of course.  If you realize that the expression [1,2,3] is not immutable,
 then it makes sense.

 Another example to help you think about it:

 void foo(int x)
 {
     immutable int[3] = [1,2,x];
 }

 This must be run on every call of foo, because x can vary.

I don't think that is a very good reason. The compiler could detect the special (and, might I add, common) case where an array literal whose contents are known at compile time is assigned to an immutable variable, and treat it as immutable even though [1,2,3] is formally of type int[].

I'm not saying it is a good explanation, but it is why the compiler does it. Any time an array literal occurs anywhere is an allocation. I have never seen a case where the compiler optimizes that out. Given that context, the behavior makes sense. I don't think any allocation should occur here, even if array literals are not made immutable, because that allocation is going to be thrown away immediately. I agree this should be special-cased. I believe there are several bugs on array literals and allocations. -Steve
Oct 06 2010