Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What is wrong with this reference?

1 view
Skip to first unread message

Michael

unread,
Jan 29, 2009, 8:31:26 AM1/29/09
to
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)?

Victor Bazarov

unread,
Jan 29, 2009, 8:53:10 AM1/29/09
to
Michael wrote:
> 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
>

You sound surprised. A reference is initialised with an rvalue obtained
apparently from copying the original ('a'). So, it refers to some other
object, a temporary.

> That means the memory locations of a and b are different i.e. a and b is
> different object!

Yes.

> 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*’

I am not sure why this is, to be honest with you. Those indirect const
qualifiers always confuse me.

>
> The following code runs perfect:

Define "perfect", please.

>
> #include<cstdio>
>
> int main()
> {
> int a=new int;

Huh? What language is that? Java? This should be a compilation error.

> 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)?

Problem? I don't see any problem.

struct A { int a; };

int main() {
A* pNormalA = new A;
pNormalA->a = 42; // hey, it's modifiable

A const* pConstA = pNormalA;
pConstA->a = 666; // error, not modifiable
}


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Greg Falcon

unread,
Jan 29, 2009, 12:44:54 PM1/29/09
to
On Jan 29, 8:31 am, Michael <mich...@michaeldadmum.no-ip.org> wrote:

> 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

Michael

unread,
Jan 29, 2009, 9:53:00 PM1/29/09
to
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);

Ian Collins

unread,
Jan 29, 2009, 10:11:48 PM1/29/09
to
Michael wrote:
> This is the sample program:
>
What was wrong with the answers you received the first time you posted?

--
Ian Collins

Triple-DES

unread,
Jan 30, 2009, 2:07:10 AM1/30/09
to
On 30 Jan, 04:11, Ian Collins <ian-n...@hotmail.com> wrote:
> Michael wrote:
> > This is the sample program:
>
> What was wrong with the answers you received the first time you posted?
>

He corrected:
int a=new int;
to
int*a=new int;

I still have a hard time believing that this program "runs perfect",
given the line:
const int&b=a;

James Kanze

unread,
Jan 30, 2009, 6:10:10 AM1/30/09
to
On Jan 29, 2:31 pm, Michael <mich...@michaeldadmum.no-ip.org> wrote:
> 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!

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:

> #include<cstdio>

> 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.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

0 new messages