Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior of self-assignment with const ref parameter

Tags:

c++

c++98

I stumbled upon some very old code which has a class with a defined copy assignment operator which takes its parameter as a const reference, but also does not check for self-assignment, so essentially:

struct A
{
    int q;
    A(): q(3) {}

    A& operator=(const A& a)
    {
        q = a.q;
        return *this;
    }
};

What is the behavior of this assignment operator when an instance of A is assigned to itself? I would assume this causes problems as it "breaks" the constness of the paramater, any compiler could assume that the parameter is not changed and optimize based on this.

However neither clang nor gcc emit a warning, and the program runs fine. This also works if I explicitly change the value of q to 4 before the assignment in the assignment operator.

like image 929
Marius Herzog Avatar asked Mar 07 '18 07:03

Marius Herzog


People also ask

What is the difference between a reference parameter and a const reference parameter?

The important difference is that when passing by const reference, no new object is created. In the function body, the parameter is effectively an alias for the object passed in. Because the reference is a const reference the function body cannot directly change the value of that object.

What does const reference do?

Const Reference to a pointer is a non-modifiable value that's used same as a const pointer. Here we get a compile-time error as it is a const reference to a pointer thus we are not allowed to reassign it.

Why are const reference parameters useful in C ++?

Passing by const reference offers the same primary benefit as pass by reference (avoiding making a copy of the argument), while also guaranteeing that the function can not change the value being referenced. In most cases, we don't want our functions modifying the value of arguments.

Can a constant be passed by reference?

You only pass by reference to non-const if you want to change the arguments and have the client observe those changes. If you don't want to change the arguments, pass by reference to const or by value. If you want to change the arguments but have no effect on the client, pass by value.


1 Answers

Binding an object to a const reference doesn't make it const all of a sudden. The const there only indicates that the function cannot modify the parameter via a. It doesn't mean that the referred to object has to be const itself.

Since *this and a can legally alias the same object, there's no risk in such code. The compiler cannot make wild assumptions about aliasing.

Self-assignment is only an issue when the object state can be left somehow corrupted if the assignment operator doesn't run to completion, or releases a resource it then tries to copy from "other". Your example has no risk of that happening. In general however, one should be mindful of exceptions potentially being thrown and ownership of resources.

like image 144
StoryTeller - Unslander Monica Avatar answered Nov 08 '22 23:11

StoryTeller - Unslander Monica