| Thread overview | |||||
|---|---|---|---|---|---|
|
February 14, 2011 ref vs out. | ||||
|---|---|---|---|---|
| ||||
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
| ||||
February 14, 2011 Re: ref vs out. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Charles McAnany | 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.
| |||
February 14, 2011 Re: ref vs out. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Charles McAnany | 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.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply