www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - [D1] struct opEquals questions

reply qwerty <qw er.ty> writes:
In my unittest I tried to test out my rotate function.
assert(Vec2(1,2).rotate(90) == Vec(-2,1));
But I got these compile errors:
vector.d(156): Error: function vector.Vec.opEquals (Vec) does not match
parameter types (void)
vector.d(156): Error: cannot implicitly convert expression
(opCall(1,2).rotate(opCall(90))) of type void to Vec*

2 questions:
My opEquals takes an Vec2 and not a *Vec2, is this wrong?
Why is return value of the rotate function compared and not the rotated struct
literal?
Mar 18 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
qwerty:
 My opEquals takes an Vec2 and not a *Vec2, is this wrong?

It's OK. D1 docs say: Structs and unions (hereafter just called structs) can provide a member function: int opEquals(S s) or: int opEquals(S* s)
 Why is return value of the rotate function compared and not the rotated struct
literal?

You can add a return this or return *this at the end of the rotate method. Bye, bearophile
Mar 18 2010
parent reply qwerty <qw er.ty> writes:
bearophile Wrote:

 qwerty:
 My opEquals takes an Vec2 and not a *Vec2, is this wrong?

It's OK. D1 docs say: Structs and unions (hereafter just called structs) can provide a member function: int opEquals(S s) or: int opEquals(S* s)
 Why is return value of the rotate function compared and not the rotated struct
literal?

You can add a return this or return *this at the end of the rotate method.

int opEquals(S* s) { return (i1 ==*s.i1 && i2 ==*s.i2); } What happens with the return value if it isn't used? Vec2(1,2).rotate(90); I mean, where will the *this end up? Or will the compiler not return it at all?
 
 Bye,
 bearophile

Mar 18 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
qwerty:
 If I return *this, I should also provide the *S version of opEquals? 

If you don't provide a necessary operator the compiler complaints.
 What happens with the return value if it isn't used?

The function is one and it doesn't change, it has to be the same for everyone that calls it (time ago I have suggested for a compile time flag that's defined inside functions to know if their result is used, to avoid computing it in some situations, turning the single function in a kind of templated function, but I am not sure it can work well if you have function pointers. So you need a single entry point for two functions).
 I mean, where will the *this end up? Or will the compiler not return it at all?

The function returns it, but the result is ignored. In such situations reading a little the asm helps. Bye, bearophile
Mar 18 2010
parent reply qwerty <qw er.ty> writes:
bearophile Wrote:

 qwerty:
 If I return *this, I should also provide the *S version of opEquals? 

If you don't provide a necessary operator the compiler complaints.
 What happens with the return value if it isn't used?

The function is one and it doesn't change, it has to be the same for everyone that calls it (time ago I have suggested for a compile time flag that's defined inside functions to know if their result is used, to avoid computing it in some situations, turning the single function in a kind of templated function, but I am not sure it can work well if you have function pointers. So you need a single entry point for two functions).

For a function without any side effects, it shouldn't be a problem.. I think :)
 
 
 I mean, where will the *this end up? Or will the compiler not return it at all?

The function returns it, but the result is ignored. In such situations reading a little the asm helps.

Yet another thing I should learn.. asm :)
 
 Bye,
 bearophile

Mar 18 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
qwerty:
 For a function without any side effects, it shouldn't be a problem.. I think :)

Ignoring the return value of a function without side effects (in D2 pure functions or nothrow pure functions) has to be an error. I even have a bug report for this, because it's the same situation as an expression like: a + 5; that the compiler sees as an error. Bye, bearophile
Mar 18 2010
parent reply qwerty <qw er.ty> writes:
bearophile Wrote:
 (time ago I have suggested for a compile time flag that's defined inside
functions to know if their result is used, to avoid computing it in some
situations, turning the single function in a kind of templated function, but I
am not sure it can work well if you have function pointers. So you need a
single entry point for two functions).

 For a function without any side effects, it shouldn't be a problem.. I think :)

Ignoring the return value of a function without side effects (in D2 pure functions or nothrow pure functions) has to be an error. I even have a bug report for this, because it's the same situation as an expression like: a + 5; that the compiler sees as an error.

function is with side effects --> normal func() function is without side effect --> generate 2 version of the function *if compiler can see no return is required --> point to noReturnCalc version if compiler doesn't know --> point to returnCalc version if called through pointer --> point to returnCalc version As the function has no side effect, it doesn't matter there are two different versions (no static members etc.) This will only speed up the * Hope it makes any sense :D
Mar 18 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Inside free functions there can be a locally defined compile-time boolean
constant like __used_return. If you use this constant inside a function the
compiler creates two versions of the function that share the same static
variables (if the function is a template then each pair of instantiated
functions share the same static variables). Inside the function you can use a
static if to not compute the return value if __used_return is false (so in this
case the function has void return type).

qwerty:
   if compiler doesn't know --> point to returnCalc version
   if called through pointer --> point to returnCalc version 

Yes, the default has to be __used_return = true. But I don't know if this is safe enough. So this: int foo(int x) { int val; val += x; static if (__used_return) return val + 1; } void main() { int y = foo(5); foo(6); int function(int) tf = &foo; alias typeof(foo) TF; } Once desugared is like: int _foo_val; int foo_ret(int x) { _foo_val += x; return _foo_val + 1; } void foo_void(int x) { _foo_val += x; } void main() { int y = foo_ret(5); foo_void(6); int function(int) tf = &foo_ret; alias typeof(foo_ret) TF; } In practice I don't think this can be useful enough. Bye, bearophile
Mar 18 2010
prev sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
qwerty wrote:
 In my unittest I tried to test out my rotate function.
 assert(Vec2(1,2).rotate(90) == Vec(-2,1));
 But I got these compile errors:
 vector.d(156): Error: function vector.Vec.opEquals (Vec) does not match
parameter types (void)
 vector.d(156): Error: cannot implicitly convert expression
(opCall(1,2).rotate(opCall(90))) of type void to Vec*
 
 2 questions:
 My opEquals takes an Vec2 and not a *Vec2, is this wrong?
 Why is return value of the rotate function compared and not the rotated struct
literal?

2 problems: 1. You call the struct Vec some places and Vec2 others. 2. My guess is that the compiler complains about Vec* because Vec is a struct, not a class, and you have written 'new Vec' somewhere. Am I right? If that is the case, remember that for structs, 'new' returns a pointer, whereas for classes it returns a reference. -Lars
Mar 18 2010
parent qwerty <qw er.ty> writes:
Lars T. Kyllingstad Wrote:

 qwerty wrote:
 In my unittest I tried to test out my rotate function.
 assert(Vec2(1,2).rotate(90) == Vec(-2,1));
 But I got these compile errors:
 vector.d(156): Error: function vector.Vec.opEquals (Vec) does not match
parameter types (void)
 vector.d(156): Error: cannot implicitly convert expression
(opCall(1,2).rotate(opCall(90))) of type void to Vec*
 
 2 questions:
 My opEquals takes an Vec2 and not a *Vec2, is this wrong?
 Why is return value of the rotate function compared and not the rotated struct
literal?

2 problems: 1. You call the struct Vec some places and Vec2 others.

All should be Vec2
 
 2. My guess is that the compiler complains about Vec* because Vec is a 
 struct, not a class, and you have written 'new Vec' somewhere.  Am I right?
 
 If that is the case, remember that for structs, 'new' returns a pointer, 
 whereas for classes it returns a reference.
 
 -Lars

Sorry about my typos, bearophile luckily read right over them :)
Mar 18 2010