www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: const, final, scope function parameters

reply Robert Fraser <fraserofthenight gmail.com> writes:
I understand that part, but I don't necessarily want to reassign the reference,
just change something in the state of the object being referred to. For example:

struct Foo
{
    int x;
}

void bar(in Foo var)
{
    var.x = 10;
}

Allowed?

Regan Heath Wrote:

 Denton Cockburn Wrote:
 On Mon, 28 May 2007 18:56:00 -0400, Robert Fraser wrote:
 
 Ah, thanks, now I understand scope (I understood the other two; I thought
scope would prevent copies of references). Still, const by default seems a bit
odd - make it explicit. For example, if a file stream is being passed to a
function, could I write to it inside the function if it was const?
 

No, not if it changes the internals of the object. If you want that, then simply specify the parameter as 'ref' void foo(ref Stream x) { ...blah... } or void foo(scope final Stream x) { ...blah... } I'm trying to understand this too, so hopefully I didn't just tell you the wrong thing.

You're answer looks good to me. Passing with 'ref' means that the Stream 'x' is _not_ a copy of the passed reference, but is actually the exact reference passed. This is useful when you might want to re-assign it inside the function and expect that change to be reflected outside the function. Passing with 'scope final' gives a copy of the passed reference, 'final' prevents/detects you from reassigning it (catching the bug where you want the change to be reflected and actually meant to use 'ref' and preventing the bug where a parameter is re-used several times in a large function and this can result in bugs due to programmers expecting it to have it's inital value). 'scope' prevents/detects any attempt to store it's address in an external variable (which would be an ugly bug to find) because as a copy it ceases to exist after the function returns. I'm just re-iterating the behaviour for anyone still coming to grips with this. A good understanding of what goes on in the background (function agruments being copies, or not, etc) makes for better programmers. Regan

May 29 2007
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Robert Fraser Wrote:
 
 struct Foo
 {
     int x;
 }
 
 void bar(in Foo var)
 {
     var.x = 10;
 }
 
 Allowed?

And also, what if it was a reference type instead of a value type: class Foo { int x; } void bar(Foo var) { var.x = 5; // Is this allowed? }
May 29 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
Robert Fraser Wrote:
 Robert Fraser Wrote:
 
 struct Foo
 {
     int x;
 }
 
 void bar(in Foo var)
 {
     var.x = 10;
 }
 
 Allowed?


Assuming 'in' means 'scope, const, final' then "No". 'const' prevents you modifying the data to which the variable refers. In this case that is the contents of the struct. In the case of a class reference, the contents of the class to which it refers. In the case of a pointer, the data to which it points. You might think that with a value type there is no harm in modifying it because the change is not reflected back to the original variable passed but consider; 1. What if the programmer wanted that change to be reflected back to the original variable and they have forgotten to use 'ref'? 2. Or, in a large function maintained by more than 1 developer someone changes the input variable and someone else doesn't realise and makes an assumption about it's value, perhaps.. void bar(in Foo var) { assert(var.x == 0); //many lines of code var.x = 10; //many lines of code //line which assumes var.x == 0; BANG! }
 And also, what if it was a reference type instead of a value type:
 
 class Foo
 {
     int x;
 }
 
 void bar(Foo var)
 {
     var.x = 5; // Is this allowed?
 }

"No", 'const' prevents this too. It's perhaps more important when reference types are involved because the change will be reflected back to the original variable passed. Without 'const' someone who wants to call this function cannot guarantee what state their object will be in after the function has finished. With 'const' you can guarantee the object has not changed. Regan Heath
May 29 2007
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Thanks for explaining that to me (I've only ever worked in Java, so const is a
foreign concept). Then doing that by default seems like it'd not only break a
great deal of existing code, and just sounds weird to me. I'm all for explicit
"in," but I guess we'll just have to wait and see what Walter decides.

Regan Heath Wrote:

 Robert Fraser Wrote:
 Robert Fraser Wrote:
 
 struct Foo
 {
     int x;
 }
 
 void bar(in Foo var)
 {
     var.x = 10;
 }
 
 Allowed?


Assuming 'in' means 'scope, const, final' then "No". 'const' prevents you modifying the data to which the variable refers. In this case that is the contents of the struct. In the case of a class reference, the contents of the class to which it refers. In the case of a pointer, the data to which it points. You might think that with a value type there is no harm in modifying it because the change is not reflected back to the original variable passed but consider; 1. What if the programmer wanted that change to be reflected back to the original variable and they have forgotten to use 'ref'? 2. Or, in a large function maintained by more than 1 developer someone changes the input variable and someone else doesn't realise and makes an assumption about it's value, perhaps.. void bar(in Foo var) { assert(var.x == 0); //many lines of code var.x = 10; //many lines of code //line which assumes var.x == 0; BANG! }
 And also, what if it was a reference type instead of a value type:
 
 class Foo
 {
     int x;
 }
 
 void bar(Foo var)
 {
     var.x = 5; // Is this allowed?
 }

"No", 'const' prevents this too. It's perhaps more important when reference types are involved because the change will be reflected back to the original variable passed. Without 'const' someone who wants to call this function cannot guarantee what state their object will be in after the function has finished. With 'const' you can guarantee the object has not changed. Regan Heath

May 29 2007
parent Regan Heath <regan netmail.co.nz> writes:
Robert Fraser Wrote:

 Thanks for explaining that to me (I've only ever worked in Java, so const is a
foreign concept). Then doing that by default seems like it'd not only break a
great deal of existing code, and just sounds weird to me. 

Can you give an example of something you think would break. When you say break do you mean wont compile, or will compile and behaves differently. Because, the former is fine as (I'd like to think that) it breaks because it's something that shouldn't be done. The latter is not acceptable, ever.
I'm all for explicit "in," but I guess we'll just have to wait and see what
Walter decides.

Yep, as always. (I dont want to imply any dislike about this fact, it doesn't really bother me when Walter makes a decision about Walters programming language which I don't like.. it is after all Walters). Regan
May 30 2007