I am learning about references in C . In particular, i have learnt that references are not actual objects. Instead they refer to some other object. That is, reference are just alias for other objects.
Then i came across this which says:
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. It is neither a pointer to the object, nor a copy of the object. It is the object. There is no C syntax that lets you operate on the reference itself separate from the object to which it refers.
I get that the above quote means that we can't operate on the reference itself separate from the object to which it refers but it still seems to imply that "a reference is an object".
Also, i have come across the the sentence given below:
In ISO C , a reference is not an object. As such, it needs not have any memory representation.
I don't have a link to this 2nd quote but i read it in one of SO's post somewhere.
My question is that assuming the second quote is also from the standard(which may not be the case), doesn't these 2 quoted statements contradict each other. Or at least the first quote is misleading. Which one is correct.
My current understanding(by reading books like C Primer 5th edition) is that references are an alias for objects. Which leads me to the thinking that they should not take any space in memory.
CodePudding user response:
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. ...
Notes are informal and usually should not to be interpreted as strict rules. If an interpretation contradicts with standard rules, then that interpretation is wrong.
References and objects are different kinds of entities. A reference is not an object distinct from the one that it names. It isn't possible to form a pointer to a reference. A "pointer to reference" isn't even a valid type category.
The note is trying to say that reference "is" the object which it names in the sense that using the reference is using the referred object.
I was thinking of confirming that whether or not references take any space
References take space or they don't take space. It's up to the language implementation to figure out whether it needs space in each case.
Standard quote:
[dcl.ref] It is unspecified whether or not a reference requires storage
Outside of standard specifications, if you want an example of reference using space, try adding a reference member to a class and you are very likely to observe that the size of the class increases.
since pointers take space then reference should also take space. ...
Pointers do take space in the abstract machine that the standard specifies. But if you never observe the storage, then it's entirely possible that the storage never exists in practice. A significant difference between references and pointers is that you cannot observe the storage of a reference directly.
Philosopher: "If a tree falls in an abstract machine and no one is around to observe it, does it have an effect?"
Optimiser: "Not if I can help it."
CodePudding user response:
A reference provides another way of referring to an object. That's useful particularly when passing parameters by reference to functions. More formally, a reference is an alias that binds to a variable including, in this case, an anonymous temporary.
Fortunately we don't need to concern ourselves how they are implemented. That's the job of the compiler, and techniques vary. The C standard does not require them to occupy any memory.
There is a way of distinguishing reference types by the way. Non-separability is really more about not being able to bind the reference to any other variable. See
#include <iostream>
#include <type_traits>
int main() {
int a = 0;
int& ref = a;
std::cout << (
std::is_reference<decltype(ref)>::value ? "pay me a bonus\n" : "reformat my hard disk\n"
);
std::cout << (
std::is_reference<decltype(a)>::value ? "pay me a bonus\n" : "reformat my hard disk\n"
);
}
Note finally that &a
and &ref
must always be the same.
CodePudding user response:
The first quote is really saying the reference is not separable from the object.
... still seems to imply that "a reference is an object".
It really implies that a reference is a non-separable, non-first-class alias for an object, exactly as you first said.
The difficulty with these discussions is that the standardese meaning of "object" is already different from the meaning used in most less-formal contexts.
Let's start simple:
int a;
Would often be described as declaring an integer object a
, right? It actually
- declares an integer object
- binds the name
a
to that object in the appropriate scope
Now, if we write
int &b = a;
we could say that b
is the object in the same way as we could say that a
is the object. Actually neither are correct, but given that informal text already uses the latter, it's no worse.
We should instead say that the name b
refers to the same object as the name a
. This is exactly consistent with calling it an alias, but informal or introductory texts would seem pretty cumbersome if they wrote "... the integer object referred to by the name a
..." everywhere instead of just "the integer a
".
As for taking space in memory ... it depends. If I introduce 100 aliases for a single object inside a single function I'd be really surprised if the compiler didn't just collapse them (although of course they might still show up in debug symbols). No information is being lost here by eliding the redundant names.
If I pass an argument by reference to a non-inlined function, some actual information is being communicated, and that information must be stored somewhere.
CodePudding user response:
What a reference actually "is" doesn't make much sense: you could say it is the referenced object or that it is an alias to it, and these claims are both true in some sense.
int main()
{
int a(0);
int& ref(a);
ref = 1; // Will actually affect the value of a
return 0;
}
Let's go through this program line by line.
int a(0);
allocates some memory (usually 4 bytes) on the stack to hold an integer.int& ref(a);
doesn't necessarily allocate memory, and wether it actually will is compiler-specific. In this sense,ref
itself is not an object: it is simply an alias, another name, fora
. This is what the second quote means by "a reference is not an object". (Please note that sometimes, when the what object is referenced can't be known at compile-time for example, a reference has to reserve additional space for the object's address. In these cases, references are just syntactic sugar for pointers.)ref = 1;
sets the value ofa
to one. In this sense, you can think ofref
as being precisely the same object asa
. Any operation "on" the reference will actually operate on the referenced object. This is what the first quote means by "It is the object".