-2

All

traditionally, in books on C++ and even in Core Guidelines the self-assignment protection is written as

A& A::operator=(const A& a) {
    if (&a != this) {
       ...
    }
    return *this;
}

But in modern C++ (since C++-11) we have std::addressof magic.

If I to teach students all the goodies of modern C++, shall I promote self-assignment check to be written as

A& A::operator=(const A& a) {
    if (std::addressof(a) != this) {
       ...
    }
    return *this;
}

More general question - should it be the way to go, in Core Guidelines and elsewhere?

Thoughts? Comments?

Barry
  • 286,269
  • 29
  • 621
  • 977
Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
  • 6
    You don't need to use `std::addressof()` unless your class overloads `operator&`. A "more modern" way to write `operator=` would be to make sure your class has adequate copy and move constructors, and then merge copy assignment and move assignment into a single `operator=` implementation, letting the compiler decide whether to use copy or move depending on the input, eg: `A& A::operator=(A a) { /* move a into this as needed ... */ return *this; }` – Remy Lebeau Sep 18 '18 at 17:20
  • 2
    Do you know the difference between the two? – Rakete1111 Sep 18 '18 at 17:20
  • @RemyLebeau "You don't need to use std::addressof() unless your class overloads operator&" sorry, it sounds like "you do not need to delete copy ctor for non-copyable class, unless somebody tries to copy object of your class". And how existance of copy/move ctor changes this? – Slava Sep 18 '18 at 17:26
  • 2
    @Slava That's... not the same thing at all? – Barry Sep 18 '18 at 17:27
  • @Barry I think it is similar, if there is way to prevent problems to happen later, why not to use it? What is downside of using `std::addressof()`? – Slava Sep 18 '18 at 17:28
  • 5
    @Slava It's not the same thing. You delete the copy constructor because you _know_ your class isn't copyable and you want to prevent it from being copied. You use `addressof` in places where you _don't know_ how types you don't own behave. – Barry Sep 18 '18 at 17:29
  • @Barry "You use addressof in places where you don't know how types you don't own behave." can you provide citation from C++ standard that claims this? – Slava Sep 18 '18 at 17:30
  • @Slava A copy/move constructor has nothing to do with whether you use `std::addressof()` or not. `std::addressof()` gets the address of a variable without using `operator&`. A class is allowed to overload `operator&` to return a memory address to something other than itself (it is not uncommon for various smart pointer implementations to overload `operator&` to return the address of the pointer being held internally). – Remy Lebeau Sep 18 '18 at 17:30
  • 1
    Another thing to consider if you are teaching C++ is that the assignment operator very rarely needs to be overloaded. –  Sep 18 '18 at 17:31
  • 5
    @Slava That's not how the standard works - it doesn't tell you how to write code or the motivation for features in the language or library. But that is very much why `addressof` exists. – Barry Sep 18 '18 at 17:32
  • @RemyLebeau I know what `std::addressof()` does, and OP's question is legit, if using it is simpler why not to do that? Any downsides except longer typing? And I do not understand downvote on legit question. – Slava Sep 18 '18 at 17:33
  • 1
    @Slava using `std::addressof()` is not *simpler* than using `operator&`, especially when `A` does not overload `operator&`. But, if `A` does overload `operator&` then `std::addressof()` would be *required*, unless `operator=` avoids self assignment altogether by using a copy-and-swap idiom. – Remy Lebeau Sep 18 '18 at 17:34
  • @Barry ok, but you sounded like this is official and anybody that uses `std::addressof()` in other cases must be banned on SO. – Slava Sep 18 '18 at 17:35
  • @RemyLebeau I still did not hear what is downside of using `std::addressof()` instead of & in this case. Upside is obvious though. – Slava Sep 18 '18 at 17:36
  • 1
    @Slava Nobody said there was a *downside* to using it. Just that it is usually not *necessary* to use it. And it is certainly not common practice to use it in most cases. Cases where it *needs* to be used are rare. – Remy Lebeau Sep 18 '18 at 17:37
  • @RemyLebeau writing safer code without any penalty (except size of source code) is necessary enough for me. – Slava Sep 18 '18 at 17:39
  • 3
    Seems like there's a broader question than protecting against self-assignment here: should `std::addressof()` be used in place of `&` in general? – Tim Randall Sep 18 '18 at 17:39
  • 3
    @Slava: "*I still did not hear what is downside of using std::addressof() instead of & in this case.*" The downside is that you have to teach people to use a 14-character name that they would otherwise have little need to know about in cases where 99.999% of the time it serves no purpose relative to the 1-character alternative. – Nicol Bolas Sep 18 '18 at 17:49
  • @Slava How did you get from "You use `addressof` in places where you don't know how types you don't own behave" to "anybody that uses `std::addressof()` in other cases must be banned on SO"? Those two statements are not similar. – Barry Sep 18 '18 at 18:04
  • @NicolBolas 16 characters :-) parentheses count. – Barry Sep 18 '18 at 18:09
  • @Barry I got from downvotes on the question and tone of your and Remy comments. I may get it wrong but it all together really sounds negative. – Slava Sep 18 '18 at 18:09

1 Answers1

4

std::addressof is intended for generic code.

In generic code, unary operator& could be overloaded by the type you are interacting with. And if you want the real address, that won't do.

In non-generic code, operator& overloading is both rare and pathological. Anyone who overloads operator& on a type is going to make that type extremely weird and will have to audit every use of it anyhow.

The use of unary operator& overloading has fallen out of favour -- even pseudo-com smart pointers have gotten out of the habit. About the only recent use I've seen is someone writing expressions that produce function objects and the like.

Nearly pointless verbosity is not a great thing.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524