What is wrong with this reference?

M

Michael

This is the sample program:

#include<cstdio>

int main()
{
int*const a=new int;
const int*const&b=a;
printf("%p %p\n",&a,&b);
delete a;
return 0;
}

When running, it produces:

0x7fff1dc49fc8 0x7fff1dc49fb8

That means the memory locations of a and b are different i.e. a and b is
different object! I want to make something that *a is modifiable but *b is
not (to be used inside a class) but the following code generates a
compile-time error:

#include<cstdio>

int main()
{
int*a=new int;
const int*&b=a;
printf("%p %p\n",&a,&b);
delete a;
return 0;
}

test.cpp:6: error: invalid initialization of reference of type ‘const int*&’
from expression of type ‘int*’

The following code runs perfect:

#include<cstdio>

int main()
{
int a=new int;
const int&b=a;
printf("%p %p\n",&a,&b);
return 0;
}

What is the problem in the first code (I am using g++ 4.2.4)?
 
G

Greg Falcon

the following code generates a compile-time error:
int*a=new int;
const int*&b=a;

This doesn't compile because it is incorrect; the types are not
compatible. If this were allowed, you could use this reference to
modify const ints. This is in the FAQ, here:
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17
.. Though the faq entry refers to pointers and not references, the
idea is exactly the same.
int*const a=new int;
const int*const&b=a;
printf("%p %p\n",&a,&b);

This compiles, but does not do what you want. The types are still not
compatible as above, so b doesn't refer to the same object as a.
However, since you are declaring a reference _to const_, the reference
is allowed to bind to a temporary. Although an int** can't convert
safely to const int**, an int* can convert to a const int*. So the
"a" in the second line here is a perfectly valid expression
convertible to const int*, and it's the temporary object resulting
from this expression that "b" binds to.

Notice that your printf is printing the _address of_ your pointers,
which are different because they're different objects. If you instead
printed their _contents_, you would see the same number.

Greg F
 
J

James Kanze

This is the sample program:

int main()
{
int*const a=new int;
const int*const&b=a;
printf("%p %p\n",&a,&b);
delete a;
return 0;
}
When running, it produces:
0x7fff1dc49fc8 0x7fff1dc49fb8
That means the memory locations of a and b are different i.e.
a and b is different object!

Obviously. The have different types (int* and int const*). One
object can never have two different types.
I want to make something that *a is modifiable but *b is not
(to be used inside a class) but the following code generates a
compile-time error:
#include<cstdio>

int main()
{
int*a=new int;
const int*&b=a;
printf("%p %p\n",&a,&b);
delete a;
return 0;
}
test.cpp:6: error: invalid initialization of reference of type \u2018const int*&\u2019
from expression of type \u2018int*\u2019

Consider the following:

int const a = 43 ;
int const* pa = &a ;
int* b ;
int const*& rb = b ; // This is what the compiler is
// complaining about
rb = pa ;
*b = 0 ;

If const is to mean anything, one of the last three statements
above must be illegal. And it's hard to imagine how to make the
last two illegal, so the conversion in the third from the bottom
is banned.
The following code runs perfect:

int main()
{
int a=new int;
const int&b=a;
printf("%p %p\n",&a,&b);
return 0;
}

I can't get it to compile. Are you sure about the initializer
of a?

With an initializer of type int, there's nothing wrong with it.
A reference to an int const can refer to an int that isn't
const, just as a pointer to an int const can refer to an int
that isn't const. It's when you start adding levels of
indirection that it stops working. A pointer or a reference to
a cv-qualified type can refer to anything of that type whose
cv-qualifications are less than or equal to those of the pointer
or reference. Thus, a reference to an int* const can refer to
an int*. But not to an int const*; the types (and not just the
cv-qualifiers) of the pointer are different.
What is the problem in the first code (I am using g++ 4.2.4)?

Nothing. You initialized a reference with an rvalue, which
creates a temporary, and binds the reference to that temporary.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top