www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - another bug that 'in' enforcing 'const' would have found...

reply Regan Heath <regan netwin.co.nz> writes:
I have a template function:

void foo(T a) {
}

it modifies the contents of 'a', this works fine if 'a' is a class or 
array. But it does not work if 'a' is a struct.

This is due to the different methods of passing that D uses, it passes 
arrays and classes by reference and structs by copying-in.

The solution is to change the function to

void foo(inout T a) {
}

now it works for structs, BUT!, it also allows this function to modify the 
array/class reference.

If 'in' enforced const, then as soon as I tried to use this function with 
a struct it would have given an error.

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 03 2004
next sibling parent Norbert Nemec <Norbert.Nemec gmx.de> writes:
Coming from C++, it is one of the biggest obstacles to stay aware that
struct and classes behave differently. Writing a template that works for
both would be really difficult in most cases.

I agree with you, though, that the behavior of ""/"in"/"out"/"inout"
arguments leaves room for improvement and clarification.



Regan Heath wrote:

 I have a template function:
 
 void foo(T a) {
 }
 
 it modifies the contents of 'a', this works fine if 'a' is a class or
 array. But it does not work if 'a' is a struct.
 
 This is due to the different methods of passing that D uses, it passes
 arrays and classes by reference and structs by copying-in.
 
 The solution is to change the function to
 
 void foo(inout T a) {
 }
 
 now it works for structs, BUT!, it also allows this function to modify the
 array/class reference.
 
 If 'in' enforced const, then as soon as I tried to use this function with
 a struct it would have given an error.
 
 Regan.
 
Jul 04 2004
prev sibling parent reply Andy Friesen <andy ikagames.com> writes:
Regan Heath wrote:

 I have a template function:
 
 void foo(T a) {
 }
 
 it modifies the contents of 'a', this works fine if 'a' is a class or 
 array. But it does not work if 'a' is a struct.
 
 This is due to the different methods of passing that D uses, it passes 
 arrays and classes by reference and structs by copying-in.
 
 The solution is to change the function to
 
 void foo(inout T a) {
 }
 
 now it works for structs, BUT!, it also allows this function to modify 
 the array/class reference.
What I think is the showstopper is that out and inout parameters can't be rvalues.
 If 'in' enforced const, then as soon as I tried to use this function 
 with a struct it would have given an error.
An awful, terrible kludge comes to mind. Maybe it will tide you over. // Template that delegates to some other template function, but // drops 'inout'ness for object types. public template RefThing(alias Template) { template RefThing(T) { alias Template!(T) RefThing; } template RefThing(T : Object) { void RefThing(T t) { // the local variable t can be used as an inout return Template!(T)(t); } } } private template FooHelper(T) { void FooHelper(inout T t) { /* Do the actual work */ } } alias RefThing!(FooHelper) Foo; -- andy
Jul 04 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Andy Friesen" <andy ikagames.com> wrote in message
news:cc9ia5$1ppc$1 digitaldaemon.com...
 What I think is the showstopper is that out and inout parameters can't
 be rvalues.
void foo(inout int x) { x += 3; } ... foo(1 + y); What does it mean to assign a value to 1+y?
Jul 05 2004
next sibling parent Regan Heath <regan netwin.co.nz> writes:
On Mon, 5 Jul 2004 02:57:37 -0700, Walter <newshound digitalmars.com> 
wrote:
 "Andy Friesen" <andy ikagames.com> wrote in message
 news:cc9ia5$1ppc$1 digitaldaemon.com...
 What I think is the showstopper is that out and inout parameters can't
 be rvalues.
void foo(inout int x) { x += 3; } ... foo(1 + y); What does it mean to assign a value to 1+y?
x == 1+y; x+3 == 1+y+3; if you increment both x and y by 3 the statement x == 1+y stays equivalent. so you cannot increment '1' but you could increment 'y' not sure if it makes any sense, or would be any use.. but you could. Perhaps someone with a maths background can make some sense of this? Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 05 2004
prev sibling parent Andy Friesen <andy ikagames.com> writes:
Walter wrote:
 "Andy Friesen" <andy ikagames.com> wrote in message
 news:cc9ia5$1ppc$1 digitaldaemon.com...
 
What I think is the showstopper is that out and inout parameters can't
be rvalues.
void foo(inout int x) { x += 3; } ... foo(1 + y); What does it mean to assign a value to 1+y?
I was referring to rvalues of reference types. struct S { int x; } class C { int x; static C _inst; static C getInst() { return _inst; } } template Foo(T) { void Foo(inout T t) { t.x = 0; } } This will work for both types C and S, but it at the expense of making this illegal: Foo!(C)(c.getInst()); -- andy
Jul 05 2004