95

How do I decide whether I need addressof(x) instead of &x when taking the address of an object?


Seems like the question was confusing, so a clarification is in order:

addressof obviously bypasses the overloaded address-of operator. I'm already aware of that.

What I want to know is:
How do I know if that's what I really want to do? (Especially when inside a template, etc.)

Is there some kind of "rule" that helps me figure out when I need addressof instead of &?
After all, they both return the "address of" the object, so when do I use which?

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
user541686
  • 205,094
  • 128
  • 528
  • 886

5 Answers5

139

You use std::addressof when you have to. Sadly, "when you have to" includes anytime you are working in template code and want to turn a variable of unknown type T or T& into an honest-to-God pointer to that variable's memory.

Because the C++ committee foolishly allowed the overloading of the reference operator (to little legitimate purpose), it is possible for a user to instantiate your template with some type that you can't use the reference operator to get an actual pointer to. std::addressof is a way to work around users who use this dubious C++ feature in order to do what the language should have guaranteed to work to begin with.

In short, it's a library fix for a language stupidity. Use it in template code instead of & if you want to make sure users can't break your code. If your users can be trusted not to use this ill-conceived feature, then you can use &.

Antoine Morrier
  • 3,930
  • 16
  • 37
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 9
    What I find funny is that the *one* class I *expected* to overload address-of, `reference_wrapper`, doesn't seem to... – user541686 Feb 11 '13 at 21:04
  • 3
    @Mehrdad: That doesn't surprise me; both `reference_wrapper` and `addressof` come from Boost. AKA: the people who most know the dangers of overloading that operator. – Nicol Bolas Feb 11 '13 at 21:11
  • 3
    Looking back at this, I'm not sure if it was foolish to allow the address-of operator to be overloaded. It's useful for something like Boost.Lambda, to represent the action of taking an address. But it seems like it's just been misused. – user541686 Dec 15 '15 at 00:09
  • 1
    @Mehrdad, I was surprised too. I think `reference_wrapper` is just a very thin layer of wrapper, one can devise a type that emulates a reference much better than `reference_wrapper`, including for example overloading `operator&`. See here http://stackoverflow.com/questions/34235818/type-emulating-a-c-reference-better-than-stdreference-wrapper and here http://stackoverflow.com/a/34144470/225186 – alfC May 26 '16 at 03:39
  • @NicolBolas *"... it is possible for a user to instantiate your template with some type that you can't use the reference operator to get an actual pointer to."* -- Would greatly appreciate it if you can edit your answer and add an example to elaborate on this sentence. I'm still confused. Thank you so much in advance! – Milan Apr 19 '22 at 17:29
  • @Milan: As mentioned in the post, C++ allows overloading the prefix `&` operator. Such an overload may no longer return a pointer to the given object. So you have to use `std::addressof` to bypass that. – Nicol Bolas Apr 19 '22 at 19:04
19

If it's a user-defined type with overloaded unary operator&, and you want its address, use addressof.

I'd say you should always use & because, as you say, if you don't, it defeats the purpose of the overload. Unless of course you do something meaningful with the overload, in which case you'd need addressof (outside the class, inside you can just use this), but you have to be very certain of what you're doing.

Here's more - if you want to overload operator& outside the class (you can), you have to use addressof to return the address, otherwise it results in infinite recursion:

struct Class
{
   virtual ~Class() {}
   int x;
};

void* operator&(const Class& x)
{
    //return &x; <---- infinite recursion
    return addressof(x) + 4; //I know this isn't safe
                             //but I also know the intrinsics of my compiler
                             //and platform to know this will actually return
                             //the address to the first data member
}

I know this isn't safe.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Wouldn't it completely defeat the purpose of the overloaded operator though? How do I tell if I should defeat it or not? – user541686 Feb 11 '13 at 20:32
  • Hmm, so this is a situation in which I *can't* even use `&` in the first place, which makes the question moot! – user541686 Feb 11 '13 at 20:46
  • The infinite recursion problem can be solved simply by casting `x` to something else first: `return const_cast(&reinterpret_cast(x))`. – alecov Sep 12 '18 at 20:30
11

Use it when you want to know the actual address of the object, and not the result of an address-of operator& overload.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
8

My opinion only:

Unless you are part of the team designing the class and its interface, never. I've personally never seen a good reason to overload that operator. But if someone designs a class where it makes sense, and assuming the class is meant for public consumption(that is to say, the class is not for internal use only in a particular library), I will expect the class to work in normal code that naturally expects that & means "address of". If the class that overloads the operator isn't designed in such a sensible way, then I wouldn't use that class, period. Because either that class is broken, or it is not meant to be used outside the library which it is a part of.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
7

After all, they both return the "address of" the object, so when do I use which?

You have absolutely no guarantee that an overloaded operator& is the "address of" the object, chances are it isn't, or the class author probably wouldn't have bothered to overload it. They could have overloaded it to return a different type, or even to return void if they are ill-advisedly trying to prevent people taking its address.

If you want a pointer to an object which might have overloaded & (e.g. because its type is a template parameter so you don't know) then either use std::addressof or document that your template doesn't support types which don't return the object's real address as the right type.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521