81

Is there any way to find the address of a reference?

Making it more specific: The address of the variable itself and not the address of the variable it is initialized with.

merlin2011
  • 71,677
  • 44
  • 195
  • 329
Sandeep
  • 3,107
  • 5
  • 24
  • 18
  • Related: http://stackoverflow.com/questions/1898524/difference-between-pointer-to-a-reference-and-reference-to-a-pointer/1898556#1898556 – Khaled Alshaya Dec 23 '09 at 05:24
  • 2
    @Sandeep: "The variable itself" is just another name for the variable it is initialized with. There is no separate variable as in the case of a pointer. The reference and the variable being referenced are both the same variable. – Agnel Kurian Dec 23 '09 at 05:27
  • 4
    This case is just one more reason references are pretty useless. They're basically just there for people who can't type `->` and want to type `.` instead. – Cosine Jan 01 '14 at 19:24
  • 1
    @AgnelKurian: Sometimes. The fact that you can have a reference as a member, or function parameter stands counter to that reasoning though. – Mooing Duck Mar 06 '15 at 00:49
  • 12
    @Cosine: What?! Total rubbish. – Lightness Races in Orbit Mar 06 '15 at 00:49
  • 2
    @MooingDuck: I still consider that an abstraction leak :P – Lightness Races in Orbit Mar 06 '15 at 00:49
  • 1
    I wish such Qs had to give a rationale why the OP could possibly want the theoretical thing requested. As for those who slate references, they only betray that their experience in C++ is so limited, they've never written any code in which refs are mandatory or at least helpful - & that somehow is an indictment of the language(!) Are they used to languages where pass-by-ref is implicit & don't see the irony of complaining about C++ offering the same ability? Do they think 'pass-by-reference' should all be done manually by pointers, with the mess of C code that results? I guess we'll never know! – underscore_d Sep 16 '18 at 14:33

10 Answers10

95

References don't have their own addresses. Although references may be implemented as pointers, there is no need or guarantee of this.

The C++ FAQ says it best:

Unlike a pointer, once a reference is bound to an object, it can not be "reseated" to another object. The reference itself isn't an object (it has no identity; taking the address of a reference gives you the address of the referent; remember: the reference is its referent).

Please also see my answer here for a comprehensive list of how references differ from pointers.

The reference is its referent

Community
  • 1
  • 1
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
  • 13
    You are correct. But sometimes it is easier to use the term alias rather than referent. – Martin York Dec 23 '09 at 06:31
  • 1
    Is there any sample implementation of reference as pointers? am really interested to see how they implemented.Please share any example if you came across. – Hemanth Nov 30 '12 at 13:30
  • 1
    @Saran: GCC is open-source. – Lightness Races in Orbit Jan 09 '14 at 12:59
  • This rule defeats `va_start(vargs,a_referece_argument)`, by the way. :( – Mordachai Dec 09 '14 at 14:52
  • @Mordachai: Not really, no; `va_start` with a reference-type second argument is UB. – Lightness Races in Orbit Mar 06 '15 at 00:49
  • @Brian What would be the behavior if the reference happens to be a const reference to an rvalue? `int const &i = 5; std::cout<<&i<<"\n";` This compiles and runs perfectly with gcc 4.8. But what does the standard say? – stillanoob Oct 09 '18 at 13:13
  • Maybe according to *the standard*, the reference is its referent. But in practice it is not: when a reference is passed as an argument to a function, it is stored on the stack and there is a level of indirection (if i understand correctly). So, is here some hack to get the address of the location where the reference is stored? – Alexey Apr 07 '20 at 13:04
  • @Alexey: It isn't according to the Standard either. Only according to the FAQ, which has quite a few mistakes in it. The Standard itself is quite clear the the lifetime of the reference is distinct from the lifetime of what it points at: https://eel.is/c++draft/basic.life paragraphs 1, 2, 4, 7 and 8 – Ben Voigt Oct 12 '22 at 21:33
50

NO. There is no way to get the address of a reference.
That is because a reference is not an object, it is an alias (this means it is another name for an object).

int  x = 5;
int& y = x;

std::cout << &x << " : " << &y << "\n";

This will print out the same address.
This is because 'y' is just another name (an alias) for the object 'x'.

Martin York
  • 257,169
  • 86
  • 333
  • 562
28

The ISO standard says it best:

There shall be no references to references, no arrays of references, and no pointers to references.

I don't like the logic a lot of people are using here, that you can't do it because the reference isn't "guaranteed to be just a pointer somewhere anyway." Just as int x may be only a processor register with no address, but magically becomes a memory location when & x is used, it still may be possible for the compiler to allow what you want.

In the past, many compilers did allow exactly what you're asking for, eg

int x, y;
int &r = x;
&r = &y; // use address as an lvalue; assign a new referent

I just checked and GCC will compile it, but with a strongly worded warning, and the resulting program is broken.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 1
    Wow, I can't believe that was ever allowed! Under what extension or Standard vagueness or suchlike was that ever not a hard error, and do you remember the wording of the resulting diagnostic? As of now, `g++` with no arguments, thankfully, gives `error: lvalue required as left operand of assignment`. – underscore_d Sep 16 '18 at 14:12
  • @underscore_d This was always evil and contrary to the spirit of references. I don't know if it was ever an intended feature, or only a leaky abstraction within the compiler, where it forgot to prevent lvalue access to an internal pointer. – Potatoswatter Sep 17 '18 at 14:31
  • But that program says "assign an address to an address". However `&x` is also invalid as lvalue. The reference just acts as x. What meaning would it have to change an address? An address is something that, just is. It's not assignable. Or at best, it's a materialized temporary copy of the address of `x` which could be assignable, but wouldn't affect the address of x. – v.oddou Sep 15 '22 at 08:36
14

No.

As Bjarne Stroustrup says in TC++PL, a reference can be thought of as just another name for an existing entity (object or function). While this is not always the most precise description of the underlying low-level mechanism that implements references, it is a very good description of the concept the references are intended to implement at the language level. Not surprisingly, the language provides no means to obtain the address of reference itself.

At language level reference is not guaranteed to occupy a place in storage, and therefore in general case it has no address.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
9

From another instance of this same question: $8.3.2/3 - "It is unspecified whether or not a reference requires storage (3.7).".

So the C++ standard allows the compiler/runtime implementor to choose whether or not a reference lives in a separate memory location. However note that if it does live in a separate memory location, you can't find its address in a standard-compliant manner. So don't do it.

If you take an address of a reference, by definition in the C++ standard, you will get the address of what it refers to, rather than the address of the reference, if in fact that reference even exists as a separate entity in the runtime environment or not.

Ben Mesander
  • 91
  • 1
  • 1
9

Just use the '&' operator. e.g :

int x = 3;
int &y = x;
cout<<&y<<endl;

This will return the address of x since y is nothing more than the address of x.

Jesse Emond
  • 7,180
  • 7
  • 32
  • 37
  • 3
    I think Sandeep means the *address of the reference itself* – Drew Dormann Dec 23 '09 at 05:05
  • 1
    that will effectively print out the address of x (since y being a reference is just another name for x). – Evan Teran Dec 23 '09 at 05:05
  • yea I wasn't actually sure if he/she meant the address of what the reference points to or the reference itself so I posted this answer just in case. But, isn't the reference nothing more than the address of what it points to? So the address of the reference would be the address of "x" in my example? I'm just wondering. :) – Jesse Emond Dec 23 '09 at 05:08
  • I meant to say the address of variable itself as it is posssible in case of pointer(pointer has its own address). – Sandeep Dec 23 '09 at 05:12
  • 5
    Oh well, a reference is just an alias(an alternate name) for an object. It doesn't get its own memory cell. – Jesse Emond Dec 23 '09 at 05:16
  • 5
    @Sandeep: "pointer has its own address". Correct. That's because the pointer is a *separate* variable holding the address of the variable it points to. In the case of a reference, there is *no separate variable*. The reference is just another name for the variable being referenced. Taking the address of the reference will just return the address of the variable being referenced. – Agnel Kurian Dec 23 '09 at 05:30
  • @Agnel: As reference can be implemented with pointers, we must be aware that there can be a time penalty in using reference instead of the variable itself (because of dereferencing), so it is more subtle than "just another name". – rafak Dec 23 '09 at 11:05
  • @rafak There are 2 counterpoints to that: (a) If the reference was not actually required, i.e. the variable it refers to was in the same scope and the reference only used for convenience or suchlike, then the compiler could see that and optimise away the indirection; also, "same scope" takes on an increasingly less traditional meaning if using LTO. (b) If the reference is actually required, e.g. because the real referred variable is not known at compile-time or whatever other reason, then it's required, so there's no need to worry about the cost of indirection, because you can't avoid it. :P – underscore_d Sep 16 '18 at 14:19
4

Not reliably, as references don't have to have a unique location in addressable memory.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
3

Not by itself. If you want its "address", shove it in a struct or class. Even then that isn't necessarily guaranteed to get you within the vicinity of what you probably want to do which is using a pointer. If you want proof, the sizeof of a reference is equal to the referent type. Try it with char & and see.

MSN
  • 53,214
  • 7
  • 75
  • 105
1

It is possible, but not strictly using C++. Since the reference is passed as a parameter of a function, its value will be stored on the stack or in a register. This is hardware architecture dependent. Access to these values will require inline assembly. Consult the reference manual for the processor you are using to determine stack behavior and register addresses. Corrupting the stack or registers can very easily cause BSOD, data loss, or even permanent damage to your system. Proceed with extreme caution.

Jim Fell
  • 13,750
  • 36
  • 127
  • 202
0

If you implement a reference as a member of a struct, you then can get its address:

struct TestRef{
  int& r;
  int i;
  TestRef(int& ref): r(ref){
  }
};

The reference indeed a pointer (in my case using Xcode compiler) and you can update it's value to re-assign the reference to a new variable. To do so we need to find out the address of the reference and trick it value to address of other variable

Now the address of the reference TestRef.r is the address of TestRef object.Because r is the first member of TestRef.

You can re-assign the reference by updating the value store in the memory of TestRef.r.

This code below shows that you can get address of reference and you and re-assign a reference to a difference variable. Note: my OS is X64 OS (I use Xcode MacBook Pro 2015, MacOs 10.15.1).

#include <iostream>
using namespace std;

struct TestRef{
  int& r;
  int i;
  TestRef(int& ref): r(ref){}
};

int main(int argc, const char * argv[]) {
  int i = 10;
  int j = 11;
  TestRef r(i); // r.r is reference to i

  cout << r.r << " " << i << " " << j << endl; // Output: 10 10 11

  int64_t* p = (int64_t*)&r; // int32_t in 32 bit OS; 
  // Note: 
  // p is the address of TestRef r and also the address of the reference r.r
  // *p is the address of i variable
  //
  // Difficult to understand? r.r indeed a pointer to i variable 
  // *p will return the address inside the memory of r.r
  // that is the address of i variable
  // this statement is true: *p == &i  
  // ------>
  // now we change the value of *p to the address of j 
  // then r.r will be the reference of j instead the reference of i

  *p = (int64_t)&j;          // int32_t in 32 bit OS; 

  cout << r.r << " " << i << " " << j << endl; // Output: 11 10 11
  return 0;
}

So in fact you can work around to re-assign a reference, like a hacker.

  • Note that `construct_at` can be used to reassign the reference (creating a new one transparently in its place, that is accessed by the existing name), no hackish tricks required. C++20 entered a defect report that says doing this with placement-new has actually always been legal. – Ben Voigt Oct 12 '22 at 21:41