5

After reading this answer, I am not really sure whether a reference actually does occupy memory or not. I get that it does not occupy memory when the the compiler replaces the references with the referenced variable, like swapping the reference with the referenced variable.

However,

In the general case, compilers usually implement references as pointers. But they generally have more information about what a reference may point to, and use that for optimization.

and since a pointer does occupy memory, won't that reference now result in occupying memory since the compiler made it a pointer? In the cases where the compiler chooses to make the reference a pointer instead of just swapping it, would it be valid to say that the reference actually does occupy memory but in a slight implicit way?

In fact, when does the compiler choose to implement references as pointers and not swapping, or is that different from compiler to compiler?

Shivam Arora
  • 476
  • 5
  • 18
  • 1
    It is all implementation defined. A reference is not required to take up any space per the standard. – NathanOliver Jun 27 '17 at 15:58
  • "It is all implementation defined" great, that answered the last part, thanks. But what about when the compiler actually chooses to make a reference a pointer, would it then be valid to say that the reference is occupying memory in a slight implicit way? @NathanOliver –  Jun 27 '17 at 16:01
  • 2
    Yes, if the reference is really a pointer then it is taking up space. You just don't know if it is or isn't without examining the assembly. – NathanOliver Jun 27 '17 at 16:04
  • Although it's implementation-specific, it's not implementation-defined. "Implementation defined" in the language definition means that the implementation must document what it does. – Pete Becker Jun 27 '17 at 16:28
  • But so when writing about references, should I say that they do occupy memory or not? Or that you never know? –  Jun 27 '17 at 16:33
  • Actually, I do not really think that my main questions have been answered :-/ Just whether it was implementation-specific or not... –  Jun 27 '17 at 18:24
  • A pointer takes up no memory if it is in a register. – stark Jun 27 '17 at 18:26
  • @stark and would that be the case if the compiler chooses to make the reference to a pointer? That it would be in the register? –  Jun 27 '17 at 19:02
  • 1
    An optimizing compiler is free to eliminate slow memory references when it can. – stark Jun 27 '17 at 20:16

1 Answers1

2

Reference will definitely occupy some space if it is a member of a class. For example:

class A{
public:
  A(int &refval):m_ref(refval){};
private:
  int &m_ref;
}

The compiler will just treat this variable as a constant pointer.

However if you're using it as a temporary variable inside a scope, it has no reason to use memory:

void func(int &a){
  int &a_ref = a;
}

The compiler would just replace reference with an actual variable.

Heavy
  • 1,861
  • 14
  • 25
  • Wow. I thought that it was implementation-specific when a reference was treated as a pointer or not.. I mean you are defining when a reference is treated as a pointer or not which is opposite to what Nathan and Pete say. Or am I misunderstanding something? –  Jun 27 '17 at 19:31
  • It is implementation specific. However, all compilers I know uses this method. Maybe, in certain circumstances (like when the reference is initialized to a member of the same object - but there is no point doing this), it can optimize away the space in a class, but I don't think that any compiler bothers with this. Actually, I cannot imagine other solution than using a pointer for the reference. – geza Jun 27 '17 at 21:06
  • @geza ahh okay, makes more sense. But how can a transformation from a reference to a pointer be considered as an optimization by the compiler when a pointer occupy memory and a reference does not? –  Jun 27 '17 at 21:34
  • 1
    @Thu, It is not considered as an optimization. A class member reference is implemented as a pointer. If you think about it, how can you implement it in other way? There is no "magical" thing that a reference is not occupying memory. It does. Even in other scenarios, not just as a class member. For example, when you have a function which has a "const Object &" parameter, it is implemented as a pointer. – geza Jun 27 '17 at 21:52
  • @geza I get what you are saying but there is no reason for the compiler to make the reference a constant pointer when the reference is initialized to another class member, like `int abc; int& reffer = abc; `, am I right? If so, the statement "A class member reference is implemented as a pointer" is not entirely true, correct? –  Jun 28 '17 at 11:05
  • @Thu: yes, exactly (that's what I tried to say in one of my previous comments). However, I don't think (but I've never checked) that any compiler applies this optimization, as initializing a reference to another class member is pointless, no one does this kind of thing :) – geza Jun 28 '17 at 11:10
  • You are definitely right. One more question though: When declaring them as data members, are they then transformed to pointers so that they can be left uninitialized or what? Just for confirmation :) I do see the logic in having references as pointers since they are not really bound to anything until a given time.. @geza Thanks for your time –  Jun 28 '17 at 11:18
  • @Thu: No, they cannot be left uninitialized (like you cannot have uninitialized a const variable). In every constructor, you have to initialize the reference. Reference is reference with its own rules. Usually, you don't think about them as pointers. Now, you just happen to know, that usually, references are implemented as pointers under the hood. But references have their own semantics, which are different from pointers. – geza Jun 28 '17 at 11:28
  • Thanks. But you said "A class member reference is implemented as a pointer. If you think about it, how can you implement it in other way?" what exactly did you then mean by this? Please elaborate. You have really helped me a lot so far, I know :)) @geza –  Jun 28 '17 at 11:39
  • @Thu: no problem, I'm glad to help. I don't really know what part needs clarification. You have to separate C++ language rules, and how the various features are implemented. Language rules say that you have to always initialize a reference. But, under the hood, the reference is just a pointer, that's how it is implemented (which is not documented anywhere, I know this because of my experience). If it is still not clear then please ask a specific question :) – geza Jun 28 '17 at 11:43