digitalmars.D.learn - ref vs out.
- Charles McAnany (35/35) Feb 14 2011 Hi, all. So I'm new to this whole contract thing. (I'm coming from C and...
- Jesse Phillips (2/6) Feb 14 2011 The init value for a dynamic array is null. Thus you have an empty array...
- Stanislav Blinov (5/40) Feb 14 2011 There's nothing perplexing at all - the default initializer for a
Hi, all. So I'm new to this whole contract thing. (I'm coming from C and Java.)
I got the impression that using foo(out arg) means that arg is given its
default value, but other than that it's just like ref. So, here's the basic
code I have thus far.
01 import std.random:Random;
02 import std.container:heapify;
03 Random gen;
04 void main(){
05      auto start = new int[n];
06      randomize(start);
07      auto theHeap = heapify(start);
08      int temp = theHeap.front;
09 }
10 void randomize(ref int[] arr){
11      foreach(ref i; arr){
12           i = gen.front % 10000;
13           gen.popFront;
14      }
15 }
This compiles and runs.
However, if I switch the method signature to randomize(out int[] arr)
I get
object.Exception C:\D\dmd2\windows\bin\..\..\src\phobos\std\container.d(2533):
Enforcement failed
(This is a run-time error, it compiles fine.)
What's really perplexing is that the problem comes from line 8.
If I comment out 8, then there's no enforcement error.
If it helps, container.d includes
2531      property ElementType!Store front()
2532    {
2533        enforce(!empty);
2534        return _store.front;
2545    }
Thanks,
Charles
 Feb 14 2011
Charles McAnany Wrote:Hi, all. So I'm new to this whole contract thing. (I'm coming from C and Java.) I got the impression that using foo(out arg) means that arg is given its default value, but other than that it's just like ref. So, here's the basic code I have thus far.The init value for a dynamic array is null. Thus you have an empty array when you change to 'out', and you assign nothing into it.
 Feb 14 2011
14.02.2011 18:06, Charles McAnany пишет:
 Hi, all. So I'm new to this whole contract thing. (I'm coming from C and Java.)
 I got the impression that using foo(out arg) means that arg is given its
 default value, but other than that it's just like ref. So, here's the basic
 code I have thus far.
 01 import std.random:Random;
 02 import std.container:heapify;
 03 Random gen;
 04 void main(){
 05      auto start = new int[n];
 06      randomize(start);
 07      auto theHeap = heapify(start);
 08      int temp = theHeap.front;
 09 }
 10 void randomize(ref int[] arr){
 11      foreach(ref i; arr){
 12           i = gen.front % 10000;
 13           gen.popFront;
 14      }
 15 }
 This compiles and runs.
 However, if I switch the method signature to randomize(out int[] arr)
 I get
 object.Exception C:\D\dmd2\windows\bin\..\..\src\phobos\std\container.d(2533):
 Enforcement failed
 (This is a run-time error, it compiles fine.)
 What's really perplexing is that the problem comes from line 8.
 If I comment out 8, then there's no enforcement error.
 If it helps, container.d includes
 2531      property ElementType!Store front()
 2532    {
 2533        enforce(!empty);
 2534        return _store.front;
 2545    }
 Thanks,
 Charles
There's nothing perplexing at all - the default initializer for a 
dynamic array is an empty dynamic array :) So, because it is indeed a 
pass-by-reference with an enforced initialization, 'start' references an 
empty slice after randomize() call, hence the enforcement failure.
 Feb 14 2011








 
  
  
 
 Jesse Phillips <jessekphillips+D gmail.com>
 Jesse Phillips <jessekphillips+D gmail.com> 