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, CharlesThere'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