C++ implementation: references vs. pointers

Started by
7 comments, last by MaulingMonkey 18 years, 7 months ago
Let's assume we have a normal integer, usually taking 4 bytes: int a = 5; // (address = x, value = 5) Now, we create a pointer pointing to 'a' (again usually taking 4 bytes): int* b = &a // (address = y, value = x) Now the question is: if we create a reference to 'a', what will its address and value look like? There are two options: int& c = a; // (address = x, value=5), that is the reference is just a "syntactic alias" to 'a', without the 4-byte memory overhead of pointers OR int&c = a; // (address = z, value=x), that is the reference is implemented the same way as a pointer, but with stricter language rules (no pointer arithmetic and other "ugly things") Thanks in advance, - Mikko
Advertisement
References may or may not take up storage; it is implementation defined.
References are just syntactic aliases for another variable.

ace
In many cases the compiler will be clever enough to figure out that it's just an alias and optimize it as such, however for the general case it's treated as a pointer internally.
For instance if you send a reference across compilation units the compiler hasn't got choice other than to use a pointer, however if you try passing a basic type as a constant reference to an inline function then the compiler will probably send it by value instead.

edit: I should probably add that if the compiler can deduce that a reference can be passed by value then it'll almost certainly be able to do the same for a pointer as well.

[Edited by - doynax on September 4, 2005 12:05:22 PM]
int value;int & reference = value;int * const pointer = & value;assert( value == reference );assert( value == *pointer );assert( & value == & reference );assert( & value == pointer );assert( sizeof( value ) == sizeof( reference ) );assert( sizeof( value ) == sizeof( *pointer ) );


A reference is a constant pointer with slightly difference syntax, nothing more. Just like such a pointer, the compiler is free to be smart and make assumptions.

Most compilers will store both of these structures in 8 bytes:

struct foo {    int value;    int & reference;    foo() : value( 0 ) , reference( value ) {}};struct bar {    int value;    int * const pointer;    bar() : value( 0 ) , pointer( &value ) {}};


Similarly, most will only use 4 bytes of stack in both of these functions:

void foo () {    int value;    int & reference = value;    ...use value and/or reference...}


void bar () {    int value;    int * const pointer = & value;    ...use value and/or pointer...}


-Mike
Quote:Original post by MaulingMonkey
int value;int & reference = value;int * const pointer = & value;assert( value == reference );assert( value == *pointer );assert( & value == & reference );assert( & value == pointer );assert( sizeof( value ) == sizeof( reference ) );assert( sizeof( value ) == sizeof( *pointer ) );


A reference is a constant pointer with slightly difference syntax, nothing more. Just like such a pointer, the compiler is free to be smart and make assumptions.

From what I can gather, that code is ill formed. You can't create pointers to references, and the & operator returns a pointer to its operand. Presumably, this is linked to the fact that the standard doesn't required a reference actually occupy space, so a pointer to a reference might not mean anything.

CM
I have a question: when you intialize a reference you do:

int a=4;int& b=a;


and not:
int a=4;int& b=&a;


From my understanding, the first one is correct, the second one is a compile-time type error. Is that correct?
Quote:Original post by dyerseve
I have a question: when you intialize a reference you do:

*** Source Snippet Removed ***

and not:
*** Source Snippet Removed ***

From my understanding, the first one is correct, the second one is a compile-time type error. Is that correct?

You are correct.

CM
Quote:Original post by Conner McCloud
From what I can gather, that code is ill formed.

It isn't.
Quote:You can't create pointers to references, and the & operator returns a pointer to its operand.

Correct, which is why I'm comparing this address to the address of the value. They should be identical because of exactly this behavior. I'm taking the address of the referenced value, which being value, should be identical to the address of value, being the same thing. If I was taking the address of the reference itself, as I could a pointer, I would be testing for inequality, not equality.

Of possible interest is that a [reference | pointer] to a reference is illegal. But I'm not doing that, either. :-).

assert( typeid(int *) == typeid(& reference) );//assert( typeid(int & *) != typeid(& reference) ); //../main.cc:8: error: cannot declare pointer to `int&'//assert( typeid(int & &) != typeid(reference) ); //../main.cc:9: error: cannot declare reference to `int&'


[Edited by - MaulingMonkey on September 4, 2005 3:53:57 PM]

This topic is closed to new replies.

Advertisement