Self-assignment?

  • Thread starter Steven T. Hatton
  • Start date
S

Steven T. Hatton

If I try to assign a variable of class type to itself, can I expect the
(default) assignment operator to do nothing? I'm not asking if the result
will be that the object is unchanged. I'm asking if it will 'go through
the motions' of assignment. That is, will it touch all the member fields
with an assignment of the current data to itself?
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
J

JKop

Steven T. Hatton posted:
If I try to assign a variable of class type to itself, can I expect the
(default) assignment operator to do nothing? I'm not asking if the
result will be that the object is unchanged. I'm asking if it will 'go
through the motions' of assignment. That is, will it touch all the
member fields with an assignment of the current data to itself?

Depends on the definition of the assignment operator. For example:

AnyClass& AnyClass::eek:perator=(AnyClass const &other)
{
if ( this == &other ) return *this;

//Now do assignment
}


or:

AnyClass& AnyClass::eek:perator=(AnyClass const &other)
{
//Now do assignment
}


If you don't define an "operator=", then it's as if you defined the latter.


-JKop
 
R

Rolf Magnus

Steven said:
If I try to assign a variable of class type to itself, can I expect the
(default) assignment operator to do nothing? I'm not asking if the result
will be that the object is unchanged. I'm asking if it will 'go through
the motions' of assignment.

Yes, it will.
That is, will it touch all the member fields with an assignment of the
current data to itself?

If all the non-staic member variables are of built-in types or don't define
their own operator=, the compiler might optimize the whole thing away,
since there will be no observable effect.
 
M

Mike Wahler

JKop said:
Steven T. Hatton posted:


Depends on the definition of the assignment operator.

Read again Steven's question. He's asking about the
default operator, not a user defined one.

-Mike
 
M

Mike Wahler

Nils O. Selåsdal said:
Is that an yes it will _always_ ,

Yes it will always 'go through the motions', that is,
the behavior must be 'as if' the members are copied.
or is a compiler allowed to optimize
away someone doing
Foo f;
f = f;

It's allowed to optimize away virtually anything which
is not necessary to achieve the desired behavior. (I don't
recall for sure, but there may be certain constructs where
this isn't strictly true, but this isn't one of them).
Look up 'As if' rule.

-Mike
 
R

Ron Natalie

Steven said:
If I try to assign a variable of class type to itself, can I expect the
(default) assignment operator to do nothing?

If you mean the compiler generated assignment operator, then the answer
is NO. As a matter of fact, it will almost ALWAYS do the assignment.
It's actually required to assign all the (non-static) members unless it
can figure out that they are also no ops.
 
L

Larry Brasfield

Steven T. Hatton said:
If I try to assign a variable of class type to itself, can I expect the
(default) assignment operator to do nothing?

No, not in general. (And this includes assignment to/from
any aliases that result in self-assignement.)
I'm not asking if the result
will be that the object is unchanged. I'm asking if it will 'go through
the motions' of assignment. That is, will it touch all the member fields
with an assignment of the current data to itself?

I think the answer is yes. What I can say for sure is
that the default (compiler generated) assignment will
do is assign each member, however that is defined
on a member by member basis.

That assignment would "do nothing" only if the result
of each member assignment is a self-assignment
that "does nothing". Whether that is so will depend
on how assignment is defined for each member.
 
R

Rolf Magnus

Nils said:
Is that an yes it will _always_ , or is a compiler allowed to optimize
away someone doing
Foo f;
f = f;
?

As I wrote in the part you snipped, if there is no observable effect of that
optimization (except for the speed-up of course), the compiler is allowed
to optimize it away.
So if you're asking because you are worried that a user-defined operator=
might not be called, then be assured that it will be called.
 
S

Steven T. Hatton

Larry said:
That assignment would "do nothing" only if the result
of each member assignment is a self-assignment
that "does nothing". Whether that is so will depend
on how assignment is defined for each member.

That adds a new twist I hadn't considered yet. Some assignments do things
like modify handle counts. It seems unlikely a compiler is going to be
smart enough to figure out if so deeply nested assignment is going to
behave differently upon self-assignment. Thanks for the insight.

--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
S

Steven T. Hatton

Rolf Magnus wrote:

Note: I originated the thread, but did not post the message to which you
were replying here. So 'you' are two different people.
As I wrote in the part you snipped, if there is no observable effect of
that optimization (except for the speed-up of course), the compiler is
allowed to optimize it away.
So if you're asking because you are worried that a user-defined operator=
might not be called, then be assured that it will be called.

Here's what I'm thinking about. This is *one* approach to operating on a
vector with a matrix. (I don't particularly like it because it has side
effects which are not consistent with the mathematical meaning of matrix by
vector multiplication):

const unsigned ORDER = 3;
class Matrix3;

class Vector3{
public:
friend class Matrix3;
/*...*/
protected:
float _a[ORDER];
};

class Matrix3{
public:
/*...*/
Vector3& mDotV(Vector3& v)
{
/* matrix multiply v = _a X v._a ... */
return v;
}
protected:
float _a[ORDER][ORDER];
};

Vector3& operator*(const Matrix3& m, Vector3& v)
{
return m.mDotV(v);
}

Matrix3 m3(rotation);
Vector3 v3(x,y,z);

v3 = m3 * v3;//self-assignment
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top