C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Error C2440 when allocating array of pointers
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Matthias Hofmann
Guest





PostPosted: Sat Oct 25, 2003 8:33 am    Post subject: Error C2440 when allocating array of pointers Reply with quote



Hello,

I get an error C2440 when I compile the following code on VC++ 6.0:

int main( void )
{
const int** p1 = new int*[20]; // Error: Cannot convert from 'int ** '
to 'const int ** '

const int** p2 = new const int*[20]; // Works fine.

return 0;
}

Usually it is ok to assign a pointer to a non-constant object to a pointer
to a constant object. Is this compliant with the standard and if so, why?

Regards,

Matthias




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thomas Maeder
Guest





PostPosted: Sun Oct 26, 2003 4:58 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote



"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> writes:

Quote:
I get an error C2440 when I compile the following code on VC++ 6.0:

int main( void )
{
const int** p1 = new int*[20]; // Error: Cannot convert from 'int ** '
to 'const int ** '

const int** p2 = new const int*[20]; // Works fine.

return 0;
}

Usually it is ok to assign a pointer to a non-constant object to a pointer
to a constant object. Is this compliant with the standard and if so, why?

This is a FAQ:

See http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.15
or http://www.comeaucomputing.com/techtalk/#deconstutoh

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Sun Oct 26, 2003 5:07 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote



"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote


Quote:
const int** p1 = new int*[20]; // Error: Cannot convert from 'int **
'
to 'const int ** '

Usually it is ok to assign a pointer to a non-constant object to a pointer
to a constant object. Is this compliant with the standard and if so, why?

But what you're doing is assigning a pointer to a pointer to a non-constant
object to a pointer to a pointer to a const object. This is illegal per the
standard. See http://www.jamesd.demon.co.uk/csc/faq.html#C1 for more
details. Here's the reasoning

const int i =1;
int * p;
int * * pp = &p;
const int * * cpp = pp; // suppose this were legal
* cpp = &i;
*p = 2; // oops: changing const object!

If you really must do it, use const_cast (a strange use of const_cast to add
const), but in your case you can just use your second version.

Quote:
const int** p2 = new const int*[20]; // Works fine.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dhruv
Guest





PostPosted: Sun Oct 26, 2003 5:15 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

On Sat, 25 Oct 2003 04:33:49 -0400, Matthias Hofmann wrote:

Quote:
Hello,

I get an error C2440 when I compile the following code on VC++ 6.0:

int main( void )
{
const int** p1 = new int*[20]; // Error: Cannot convert from 'int ** '
to 'const int ** '

const int** p2 = new const int*[20]; // Works fine.

return 0;
}

Usually it is ok to assign a pointer to a non-constant object to a pointer
to a constant object. Is this compliant with the standard and if so, why?

Try this:

typedef int* pint;
int main()
{
const pint* p1 = new int*[20];
}


Regards,
-Dhruv.






[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ivan Vecerina
Guest





PostPosted: Sun Oct 26, 2003 5:16 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

Hi Matthias,
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote

Quote:
I get an error C2440 when I compile the following code on VC++ 6.0:

int main( void )
{
const int** p1 = new int*[20]; // Error: Cannot convert from 'int **
'
to 'const int ** '
.....
Usually it is ok to assign a pointer to a non-constant object to a pointer
to a constant object. Is this compliant with the standard and if so, why?

Yes, because of the classic problem which is decomposed below:

int* pi = 0;
int** ppi = π

const int** ppci = ppi; // illegal ... see why below <XX>

const int ci = 5;
*ppci = &ci; // oho... by storing a const int* into pi,
// this effectively casts the const out
**ppi = 4; // this now modifies ci => UNDEFINED BEHAVIOR

Basically, if the <XX> statement were legal, it would allow
the constness of some objects to be lost without requiring
any explicit cast.
So it is a good idea to mandate the addition of a const_cast...


Regards,
Ivan
--
http://ivan.vecerina.com
http://www.brainbench.com <> Brainbench MVP for C++









[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ralf
Guest





PostPosted: Sun Oct 26, 2003 5:17 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> schrieb im Newsbeitrag
news:bncc81$mld$1 (AT) news1 (DOT) nefonline.de...
Quote:
Hello,

I get an error C2440 when I compile the following code on VC++ 6.0:

int main( void )
{
const int** p1 = new int*[20]; // Error: Cannot convert from 'int **
'
to 'const int ** '

const int** p2 = new const int*[20]; // Works fine.

return 0;
}

Usually it is ok to assign a pointer to a non-constant object to a pointer
to a constant object. Is this compliant with the standard and if so, why?

Hi,

I think, this is standard conformant. You can convert an pointer adding the
"const" specification.
int i;
int const *p = &i;
But you cannot convert pointers implicitly with two different target types.
The target type of p1 is 'const int *'. The target type of the right side is
'int *'.

Ralf



www.oop-trainer.de
www.cplusplus-kurse.de




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Sun Oct 26, 2003 11:08 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

"Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote in message

Quote:
Try this:

typedef int* pint;
int main()
{
const pint* p1 = new int*[20];
}

This is the same as

int * *const p1 = new int*[20];

which is a different issue. Const protects whatever's to its left, so it
the double pointer p1 that is const.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Sun Oct 26, 2003 7:11 pm    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

On 26 Oct 2003 01:15:25 -0400, "Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:

Quote:
On Sat, 25 Oct 2003 04:33:49 -0400, Matthias Hofmann wrote:

const int** p1 = new int*[20]; // Error: Cannot convert from 'int ** '
to 'const int ** '

const int** p2 = new const int*[20]; // Works fine.

Try this:

typedef int* pint;
int main()
{
const pint* p1 = new int*[20];
}

That compiles because it is

int* const* p1 = new int*[20];

That is much different from what was desired. How do you plan
to make any of those uninitialized const pointers point at
anything?

int const* const* p1 = new int*[20];

That will also compile and be just as useless.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Sun Oct 26, 2003 7:13 pm    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

On 26 Oct 2003 06:08:10 -0500, "Siemel Naran"
<SiemelNaran (AT) REMOVE (DOT) att.net> wrote:

Quote:
"Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote in message

typedef int* pint;
int main()
{
const pint* p1 = new int*[20];
}

This is the same as

int * *const p1 = new int*[20];

which is a different issue. Const protects whatever's to its left, so it
the double pointer p1 that is const.

No, const pint* is pint const* is int*const*.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthias Hofmann
Guest





PostPosted: Sun Oct 26, 2003 7:15 pm    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote


Ivan Vecerina <please_use_web_form (AT) ivan (DOT) vecerina.com> schrieb in im
Newsbeitrag: [email]3f9b094a (AT) news (DOT) swissonline.ch[/email]...
Quote:
Hi Matthias,
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message
news:bncc81$mld$1 (AT) news1 (DOT) nefonline.de...
I get an error C2440 when I compile the following code on VC++ 6.0:

int main( void )
{
const int** p1 = new int*[20]; // Error: Cannot convert from 'int
**
'
to 'const int ** '
....
Usually it is ok to assign a pointer to a non-constant object to a
pointer
to a constant object. Is this compliant with the standard and if so,
why?

Yes, because of the classic problem which is decomposed below:

int* pi = 0;
int** ppi = π

const int** ppci = ppi; // illegal ... see why below <XX

const int ci = 5;
*ppci = &ci; // oho... by storing a const int* into pi,
// this effectively casts the const out
**ppi = 4; // this now modifies ci => UNDEFINED BEHAVIOR

Basically, if the <XX> statement were legal, it would allow
the constness of some objects to be lost without requiring
any explicit cast.
So it is a good idea to mandate the addition of a const_cast...


This sounds quite logical to me. However, what about the following case:

int i = 0;
int* p = &i;
const int* cp = &i;
++( *p ); // Modifies both *p and *cp, the latter of which is const!

This is another way to bypass the constness of an object, which is likely to
occur frequently in a program. According to the standard, is the behaviour
of this undefined as well?

Best regards,

Matthias Hofmann




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Sun Oct 26, 2003 11:59 pm    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

On 26 Oct 2003 14:15:20 -0500, "Matthias Hofmann"
<hofmann (AT) anvil-soft (DOT) com> wrote:

Quote:
Ivan Vecerina <please_use_web_form (AT) ivan (DOT) vecerina.com> schrieb in im
Newsbeitrag: [email]3f9b094a (AT) news (DOT) swissonline.ch[/email]...

int* pi = 0;
int** ppi = π

const int** ppci = ppi; // illegal ... see why below <XX

const int ci = 5;
*ppci = &ci; // oho... by storing a const int* into pi,
// this effectively casts the const out
**ppi = 4; // this now modifies ci => UNDEFINED BEHAVIOR

Basically, if the <XX> statement were legal, it would allow
the constness of some objects to be lost without requiring
any explicit cast.
So it is a good idea to mandate the addition of a const_cast...

This sounds quite logical to me. However, what about the following case:

int i = 0;
int* p = &i;
const int* cp = &i;
++( *p ); // Modifies both *p and *cp, the latter of which is const!

This is another way to bypass the constness of an object, which is likely to
occur frequently in a program. According to the standard, is the behaviour
of this undefined as well?

There is a big difference. In the first example, a non-const path to a
truely const object was obtained without a cast. In your example there
are both const and non-const paths to a non-const object. This happens
all of the time and the first is forbidden by the language.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ivan Vecerina
Guest





PostPosted: Mon Oct 27, 2003 7:22 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote

Quote:
Ivan Vecerina <please_use_web_form (AT) ivan (DOT) vecerina.com> schrieb in im
Newsbeitrag: [email]3f9b094a (AT) news (DOT) swissonline.ch[/email]...
......
This sounds quite logical to me. However, what about the following case:

int i = 0;
int* p = &i;
const int* cp = &i;
++( *p ); // Modifies both *p and *cp, the latter of which is const!

This is another way to bypass the constness of an object, which is likely
to
occur frequently in a program. According to the standard, is the behaviour
of this undefined as well?

This code snippet does not actually bypass the constness
of an *object*, since the object 'i' is not const.
It does however modify an object on which you hold a const
pointer (or reference), which is perfectly legal.
A const reference does not allow the direct modification of the
object it points to, but the object may still be modified by
other means.

Take for example:
void addup_twice(int& val, int const& inc)
{
val += inc; // compiler cannot optimize this as
val += inc; // a single val += 2*inc operation.
}
The output of the following statements:
int i = 1;
addup_twice( i, i );
std::cout << i << std::endl;
is well-defined and required to be 4.

Having two references to the same object or memory is called
aliasing. A C/C++ compiler is required to generate code that
behaves correctly when aliasing occurs, which does prevent
several "obvious" optimizations. ( This is why the 'restrict'
keyword has been introduced in the 99 C standard, and will
most likely be adopted by C++0x ).


[ Another example would be const volatile variables (such as
memory-mapped input ports), which cannot be modified
by code that uses them, but may have a different value
every time they are accessed. ]


Kind regards,
Ivan
--
http://ivan.vecerina.com





[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dhruv
Guest





PostPosted: Tue Oct 28, 2003 2:11 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

On Sun, 26 Oct 2003 14:11:52 -0500, John Potter wrote:

Quote:
On 26 Oct 2003 01:15:25 -0400, "Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:

On Sat, 25 Oct 2003 04:33:49 -0400, Matthias Hofmann wrote:

const int** p1 = new int*[20]; // Error: Cannot convert from 'int ** '
to 'const int ** '

const int** p2 = new const int*[20]; // Works fine.

Try this:

typedef int* pint;
int main()
{
const pint* p1 = new int*[20];
}

That compiles because it is

int* const* p1 = new int*[20];

That is much different from what was desired. How do you plan
to make any of those uninitialized const pointers point at
anything?

int const* const* p1 = new int*[20];

That will also compile and be just as useless.

Ok. I got confused in the typedef thing. Speaking of which, I have never
really understood it......... Like, say you have:

typedef int type;
typedef type& rtype;

No, why can't you use rtype like this:


type foo (const rtype rf)
{
return rf;
}

int main ()
{
type aaa = 5;
const rtype ra = 23;
foo (5);
}


This doesn't seem to work...

Regards,
-Dhruv.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthias Hofmann
Guest





PostPosted: Tue Oct 28, 2003 6:39 pm    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote


Ivan Vecerina <please_use_web_form (AT) ivan (DOT) vecerina.com> schrieb in im
Newsbeitrag: [email]3f9c966a (AT) news (DOT) swissonline.ch[/email]...
Quote:
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message
news:bnh1i7$anv$1 (AT) news1 (DOT) nefonline.de...
Ivan Vecerina <please_use_web_form (AT) ivan (DOT) vecerina.com> schrieb in im
Newsbeitrag: [email]3f9b094a (AT) news (DOT) swissonline.ch[/email]...
.....
This sounds quite logical to me. However, what about the following
case:

int i = 0;
int* p = &i;
const int* cp = &i;
++( *p ); // Modifies both *p and *cp, the latter of which is const!

This is another way to bypass the constness of an object, which is
likely
to
occur frequently in a program. According to the standard, is the
behaviour
of this undefined as well?

This code snippet does not actually bypass the constness
of an *object*, since the object 'i' is not const.
It does however modify an object on which you hold a const
pointer (or reference), which is perfectly legal.
A const reference does not allow the direct modification of the
object it points to, but the object may still be modified by
other means.

Take for example:
void addup_twice(int& val, int const& inc)
{
val += inc; // compiler cannot optimize this as
val += inc; // a single val += 2*inc operation.
}
The output of the following statements:
int i = 1;
addup_twice( i, i );
std::cout << i << std::endl;
is well-defined and required to be 4.

Having two references to the same object or memory is called
aliasing. A C/C++ compiler is required to generate code that
behaves correctly when aliasing occurs, which does prevent
several "obvious" optimizations. ( This is why the 'restrict'
keyword has been introduced in the 99 C standard, and will
most likely be adopted by C++0x ).


[ Another example would be const volatile variables (such as
memory-mapped input ports), which cannot be modified
by code that uses them, but may have a different value
every time they are accessed. ]



Thank you very much for the detailed information! Could you give a brief
explanation of what the 'restrict' keyword is supposed to do? I have never
heard of it myself.

Best regards,

Matthias Hofmann




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Wed Oct 29, 2003 1:25 am    Post subject: Re: Error C2440 when allocating array of pointers Reply with quote

In article <pan.2003.10.27.02.57.46.285660 (AT) gmx (DOT) net>,
Dhruv wrote:
<snip>
Quote:
Ok. I got confused in the typedef thing. Speaking of which,
I have never really understood it......... Like, say you
have:

typedef int type;
typedef type& rtype;

No, why can't you use rtype like this:


type foo (const rtype rf)
{
return rf;
}

int main ()
{
type aaa = 5;
const rtype ra = 23;
foo (5);
}


This doesn't seem to work...

Type aliases are not macros so, regardless of what a textual
substitution might produce, cv-qualifiers on a type alias (or
type parameter) that names a compound type (such as pointer-
to-T) are applied to the compound type and not to the
fundamental or user-defined type T that it is based on.

Reference types cannot be cv-qualified; such qualification
would be meaningless since references are immutable. It is
a syntax violation to put cv-qualifiers after "&" in a
declarator, but if a reference type is named using a type
alias or a type parameter then any cv-qualifiers on it are
simply ignored. (As a test, I wrote some code that does
this; VC++ 7.1 and Comeau 4.3.3 beta both accepted the code
but warned about the ignored qualifiers.)

What the code above does is:

int foo (int & /*const ignored*/ rf)
{
return rf;
}

int main ()
{
int aaa = 5;
int & /*const ignored*/ ra = 23;
foo (5);
}

Note that cv-qualifiers on function parameters aren't part
of the function's signature anyway.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.